在日志格式化程序中提取日志记录调用中的其他字段

时间:2019-12-04 12:28:36

标签: python python-3.x logging

所以我可以像这样将其他字段添加到我的日志消息中

logging.info("My log Message", extra={"someContext":1, "someOtherContext":2})

很好

但不清楚如何提取日志格式化程序中的所有其他字段

def format(self, record):
  record_dict = record.__dict__.copy()
  print(record_dict)

在上面,我可以在输出字典中看到我所有的额外字段,但是它们被压平成一个带有我不希望的其他垃圾负载的字典

{'name': 'root', 'msg': 'My log Message', 'args': (), 'levelname': 'INFO', 'levelno': 20, 'pathname': '.\\handler.py', 'filename': 'handler.py', 'module': 'handler', 'exc_info': None, 'exc_text': None, 'stack_info': None, 'lineno': 27, 'funcName': 'getPlan', 'created': 1575461352.0664868, 'msecs': 66.48683547973633, 'relativeCreated': 1253.0038356781006, 'thread': 15096, 'threadName': 'MainThread', 'processName': 'MainProcess', 'process': 23740, 'someContext': 1, 'someOtherContext':2}

有什么方法可以获取我所有的额外密钥,而不必事先知道它们,

我正在写一个json格式化程序,想创建一个字典la

justMyExtra = ?????
to_log = {
"message" record_dict["message"], 
**justMyExtra
}

2 个答案:

答案 0 :(得分:1)

如果您阅读logging.Logger.makeRecord方法的源代码,该方法返回具有给定日志记录信息的LogRecord对象,您会发现它将extra字典与{恢复中的__dict__对象的{1}}属性,因此之后您将无法在格式化程序中检索原始LogRecord字典。

相反,您可以使用包装器函数修补extra方法,该函数将给定的logging.Logger.makeRecord字典存储为返回的extra对象的_extra属性:

LogRecord

这样:

def make_record_with_extra(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None):
    record = original_makeRecord(self, name, level, fn, lno, msg, args, exc_info, func, extra, sinfo)
    record._extra = extra
    return record

original_makeRecord = logging.Logger.makeRecord
logging.Logger.makeRecord = make_record_with_extra

输出:

class myFormatter(logging.Formatter):
    def format(self, record):
        print('Got extra:', record._extra) # or do whatever you want with _extra
        return super().format(record)

logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
handler.setFormatter(myFormatter('%(name)s - %(levelname)s - %(message)s - %(foo)s'))
logger.addHandler(handler)
logger.warning('test', extra={'foo': 'bar'})

演示:https://repl.it/@blhsing/WorthyTotalLivedistro

答案 1 :(得分:0)

想到两种方法:

  1. 将所有其他字段转储到主词典中的词典中。调用键“ additionalContext”并获取所有其他条目。
  2. 创建原始词典的副本,并删除所有已知键:'name','msg','args'等,直到只有justYourExtra为止