我如何装饰python日志记录输出?

问题描述 投票:0回答:1

我使用import logging模块在带有python 3.7运行时的AWS lambda内部进行登录。

我想在将日志语句刷新到stdout之前对其执行某些操作,例如将消息包装为json并添加跟踪数据,以便Kibana解析器可以解析它们。

我不想为此编写自己的装饰器,因为这对于基础依赖项无效。

理想情况下,它应该类似于为记录器配置的回调这样它将为我完成以下工作:

    log_statement = {}
    log_statement['message'] = 'this is the message'
    log_statement['X-B3-TraceId'] = "76b85f5e32ce7b46"
    log_statement['level'] = 'INFO'
    sys.stdout.write(json.dumps(log_statement) + '\n')

仍然有logger.info('this is the message')

我该怎么做?

python python-3.x logging
1个回答
0
投票

为了预处理日志语句,我不得不使用非常合适的LoggerAdapter

    import logging class CustomAdapter(logging.LoggerAdapter): def process(self, msg, kwargs): log_statement = '{"X-B3-TraceId":"%s", "message":"%s"}' % (self.extra['X-B3-TraceId'], msg) + '\n' return log_statement, kwargs
  1. 参见:https://docs.python.org/3/howto/logging-cookbook.html#using-loggeradapters-to-impart-contextual-information

    通常,下一步就是像这样插入适配器:

    import logging ... logging.basicConfig(format='%(message)s') logger = logging.getLogger() logger.setLevel(LOG_LEVEL) custom_logger = CustomAdapter(logger, {'X-B3-TraceId': "test"}) ... custom_logger.info("test")
  1. 注意:我只需要将格式作为message放置,因为我需要将整个语句作为JSON字符串获取。不幸的是,因此我丢失了一些预定义的日志语句部分,例如aws_request_id。这是LoggerAdapter#process的局限性,因为它仅处理message部分。如果有人在这里有更好的方法,请提出建议。

    [AWS lambda python运行时似乎以某种方式干扰了日志记录功能,并且无法更改上述格式。因此,我还必须这样做:

    FORMAT = "%(message)s" logger = logging.getLogger() for h in logger.handlers: h.setFormatter(logging.Formatter(FORMAT))
  1. 参见:https://gist.github.com/niranjv/fb95e716151642e8ca553b0e38dd152e
© www.soinside.com 2019 - 2024. All rights reserved.