我正在努力为 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
部分。