TensorFlow
logging
redirect output
machine learning
Python

How to redirect TensorFlow logging to a file?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

TensorFlow messages do not all come from the same place, which is why "redirect TensorFlow logging" can feel inconsistent. Some messages go through Python logging, some come from TensorFlow's C++ runtime, and some are just your own training prints. A good solution starts by deciding which stream you actually want to capture.

Redirect the Python-Level TensorFlow Logger

For normal TensorFlow logger messages, use tf.get_logger() and attach a file handler.

python
1import logging
2import tensorflow as tf
3
4logger = tf.get_logger()
5logger.setLevel(logging.INFO)
6
7file_handler = logging.FileHandler("tensorflow.log")
8file_handler.setFormatter(
9    logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
10)
11
12logger.handlers.clear()
13logger.addHandler(file_handler)
14
15logger.info("TensorFlow logging redirected")

This captures messages that go through TensorFlow's Python logger. It is the cleanest option when the goal is application-level log management.

C++ Runtime Messages Are Different

Many of the noisy startup messages people associate with TensorFlow come from the underlying C++ runtime. Those are not always controlled by the Python logger.

You can reduce them with the environment variable TF_CPP_MIN_LOG_LEVEL:

python
1import os
2
3os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
4
5import tensorflow as tf

The import order matters. Set the environment variable before importing TensorFlow, or the runtime may already be initialized.

Typical values are:

  • '0 for all logs'
  • '1 to hide INFO'
  • '2 to hide INFO and WARNING'
  • '3 to hide INFO, WARNING, and ERROR'

This suppresses noise, but it does not itself create a log file.

If You Want Everything, Redirect Standard Streams

If your goal is "capture whatever TensorFlow prints during the run," redirect stdout and stderr at the process level.

python
1import contextlib
2import sys
3import tensorflow as tf
4
5with open("run.log", "w") as f:
6    with contextlib.redirect_stdout(f), contextlib.redirect_stderr(f):
7        print("starting run")
8        tf.get_logger().warning("logger warning")
9        tf.constant([1, 2, 3])

This is broader than logger configuration. It captures normal prints and many warning messages that eventually reach the standard streams.

Use Log Rotation for Long Runs

Training jobs can generate large logs, so a rotating file handler is often better than a single ever-growing file.

python
1import logging
2from logging.handlers import RotatingFileHandler
3import tensorflow as tf
4
5handler = RotatingFileHandler("tensorflow.log", maxBytes=1_000_000, backupCount=3)
6handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
7
8logger = tf.get_logger()
9logger.handlers.clear()
10logger.addHandler(handler)
11logger.setLevel(logging.INFO)

This keeps logs manageable during long experiments or repeated batch jobs.

Keep Your Own Training Logs Separate

It is also worth separating TensorFlow framework logs from your experiment logs. For example, training metrics such as epoch loss or validation accuracy are often better written through your own logger rather than mixed into TensorFlow's internal messages.

That can look like:

python
1import logging
2
3app_logger = logging.getLogger("training")
4app_logger.setLevel(logging.INFO)
5app_logger.addHandler(logging.FileHandler("training_metrics.log"))
6
7app_logger.info("epoch=1 loss=0.312 val_loss=0.401")

This produces cleaner experiment records and avoids coupling your reporting format to TensorFlow's internal logging behavior.

Choose the Right Layer

The practical question is not only "How do I redirect TensorFlow logs?" It is:

  • do I want Python logger messages
  • do I want C++ runtime noise reduced
  • do I want all process output written somewhere

Those are related but different problems. Many confusing setups happen because one mechanism is expected to solve all three.

Common Pitfalls

  • Setting TF_CPP_MIN_LOG_LEVEL after importing TensorFlow.
  • Expecting tf.get_logger() to capture every C++ runtime message.
  • Redirecting standard streams when only structured logger output was needed.
  • Forgetting log rotation for long training jobs.
  • Mixing framework logs and experiment metrics into one uncontrolled file.

Summary

  • 'tf.get_logger() is the right tool for TensorFlow's Python-level logger output.'
  • 'TF_CPP_MIN_LOG_LEVEL reduces noisy C++ runtime messages, but it is not file redirection by itself.'
  • Standard stream redirection captures broader process output when needed.
  • Use rotating handlers for long-running jobs.
  • Decide which logging layer you want before choosing the redirection method.

Course illustration
Course illustration

All Rights Reserved.