我使用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')
。
我该怎么做?
为了预处理日志语句,我不得不使用非常合适的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
通常,下一步就是像这样插入适配器:
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")
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))