How do you specify output log file using structlog?

4.7k Views Asked by At

I feel like this should be super simple but I cannot figure out how to specify the path for the logfile when using structlog. The documentation states that you can use traditional logging alongside structlog so I tried this:

    logger = structlog.getLogger(__name__)
    logging.basicConfig(filename=logfile_path, level=logging.ERROR)
    logger.error("TEST")

The log file gets created but of course "TEST" doesn't show up inside it. It's just blank.

2

There are 2 best solutions below

4
On

For structlog log entries to appear in that file, you have to tell structlog to use stdlib logging for output. You can find three different approaches in the docs, depending on your other needs.

0
On

I was able to get an example working by following the docs to log to both stdout and a file.

import logging.config
import structlog

timestamper = structlog.processors.TimeStamper(fmt="iso")
logging.config.dictConfig({
        "version": 1,
        "disable_existing_loggers": False,
        "handlers": {
            "default": {
                "level": "DEBUG",
                "class": "logging.StreamHandler",
            },
            "file": {
                "level": "DEBUG",
                "class": "logging.handlers.WatchedFileHandler",
                "filename": "test.log",
            },
        },
        "loggers": {
            "": {
                "handlers": ["default", "file"],
                "level": "DEBUG",
                "propagate": True,
            },
        }
})
structlog.configure(
    processors=[
        structlog.stdlib.add_log_level,
        structlog.stdlib.PositionalArgumentsFormatter(),
        timestamper,
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
        structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
    ],
    logger_factory=structlog.stdlib.LoggerFactory(),
    wrapper_class=structlog.stdlib.BoundLogger,
    cache_logger_on_first_use=True,
)
structlog.get_logger("test").info("hello")

If if you just wanted to log to a file you could use the snippet hynek suggested.

logging.basicConfig(filename='test.log', encoding='utf-8', level=logging.DEBUG)