How do you specify output log file using structlog?
Asked Answered
S

2

9

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.

Serbocroatian answered 6/4, 2022 at 22:31 Comment(1)
Were you able to solve it? If so, can you tell me how please?Jordanjordana
M
3

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)
Mansized answered 15/2, 2023 at 20:38 Comment(0)
D
-2

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.

Delmardelmer answered 7/4, 2022 at 10:58 Comment(4)
Can you please detail your answer? I still can't seem to figure it out and couldn't find what I need from the documentation as it seems quite complicated.Jordanjordana
The problem is that standard library logging is complicated. If you insist on using it, you'll have to spend some time learning it. The easiest way as of structlog 22.1 is to use structlog.stdlib.recreate_defaults(log_level=None) which will configure structlog to log thru stdlib and then use something like logging.basicConfig(filename='example.log', encoding='utf-8', level=logging.DEBUG) to configure logging.Delmardelmer
thanks! it works but the printing doesn't look as good as it did in the console: [2m2022-08-12 14:08.49[0m [[32m[1minfo [0m] [1mHello, world![0m whereas on the console things look like: 2022-08-11 23:30.25 [info ] Executing step step=99Jordanjordana
That is because the logs are outputted to the console with colors, but your console does not support colors. You can disable colored logs in console by setting: python3 structlog.dev.ConsoleRenderer(colors=False) Kulak

© 2022 - 2024 — McMap. All rights reserved.