首页 > 解决方案 > 是否可以在 python 日志记录中将日志级别注入结构化数据

问题描述

我正在尝试从我的 python 程序在 stdout 上写一些结构日志。具体来说,我正在尝试编写符合以下内容的 json,以便当它在 GCP 中运行时,它会被堆栈驱动程序拾取并解释为结构化数据:

https://cloud.google.com/run/docs/logging#run_manual_logging-python

查看 python 文档,我可以为我的结构化数据创建一个类,并将其呈现为单行 json 字符串:

https://docs.python.org/2/howto/logging-cookbook.html#implementing-structured-logging

然而,我坚持的是;如何在没有多余的日志调用的情况下将日志级别添加到该结构化数据:

class StructuredMessage(object):
def __init__(self, **kwargs):
    self.kwargs = kwargs

def __str__(self):
    return json.dumps(self.kwargs)

// Ideally I should have to type level='INFO' here, is there a way to get the logging
// module to do something to insert that information on the StructuredMessage instance?
logging.info(StructuredMessage(level='INFO'))

标签: pythonlogginggoogle-cloud-platformstackdriver

解决方案


有很多方法可以做到这一点——一种是使用像这样的简单辅助函数(假设import logging已经完成):

def log_structured(logger, level, **kwargs):
    kwargs[level] = level
    # you could also inject the logger name into kwargs here ...
    # convert e.g. string 'INFO' to logging.INFO
    # assumes you only use the standard levels defined in logging
    level = getattr(logging, level)
    logger.log(level, StructuredMessage(**kwargs))

logging.info()使用根记录器这样的功能,所以你可以做类似的事情

root_logger = logging.getLogger()
log_structured(root_logger, 'INFO', foo='bar', bar='baz', num=123, fnum=123.456)

推荐阅读