0

我正在努力为 structlog 中的不同处理程序设置不同的处理器。

这是我要实现的目标的最小示例:


import logging
import structlog
import sys

from logging.handlers import TimedRotatingFileHandler


def elastic_format(logger: logging.Logger, method_name: str, event_dict: dict):
    # Elastic requires the message to be under 'message' and not under 'event'
    if isinstance(event_dict, dict) and event_dict.get('event') and not event_dict.get('message'):
        event_dict['message'] = event_dict.pop('event')

    return event_dict

structlog.configure_once(
    # Don't mess up the order of this!
    # Note this https://www.structlog.org/en/stable/standard-library.html
    # On the structlog side, the processor chain must be configured to end with
    # structlog.stdlib.ProcessorFormatter.wrap_for_formatter as the renderer.
    processors=[
        structlog.stdlib.add_log_level,
        structlog.stdlib.add_logger_name,
        structlog.processors.TimeStamper(fmt='iso'),
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
        structlog.stdlib.ProcessorFormatter.wrap_for_formatter
    ],
    context_class=structlog.threadlocal.wrap_dict(dict),
    logger_factory=structlog.stdlib.LoggerFactory(),
    wrapper_class=structlog.stdlib.BoundLogger,
    cache_logger_on_first_use=True
)

console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(structlog.stdlib.ProcessorFormatter(processor=structlog.dev.ConsoleRenderer(colors=True)))

file_handler = TimedRotatingFileHandler(filename='./my_logs.log', interval=1, backupCount=48, encoding='utf-8')
file_handler.setFormatter(structlog.stdlib.ProcessorFormatter(processor=structlog.processors.JSONRenderer()))

root_logger = logging.getLogger()
root_logger.addHandler(console_handler)
root_logger.addHandler(file_handler)

root_logger.setLevel('INFO')

logger = structlog.getLogger('my_logger')
logger.info('My log message.', extra={'abc': 123})

控制台输出为:

2021-12-30T21:55:58.793483Z [info     ] My log message.                [my_logger] extra={'abc': 123}

文件输出为:

{"extra": {"abc": 123}, "event": "My log message.", "level": "info", "logger": "my_logger", "timestamp": "2021-12-30T21:55:58.793483Z"}

上面的输出是我所期望的,但是,对于文件处理程序,我想添加elastic_format代码示例中包含的函数。

我看不到在处理程序上单独设置处理器的方法。目前这只是更改日志数据,但一旦完全实施,将对数据应用一些转换。如何使用 structlog 实现这一点?

为了澄清,我希望这仅适用于文件处理程序而不是控制台处理程序,所以我不相信它可以添加到该structlog.configure_once部分。

4

1 回答 1

0

structlog 21.3.0 添加了一个processors(复数)参数structlog.stdlib.ProcessorFormatter(作为processor(单数)的替代品)。

它需要一个完整的链条,所以我相信应该可以通过在其中添加 elastic_format 来实现您想要的?

于 2022-01-05T14:40:37.373 回答