简体   繁体   English

python logging.Logger:覆盖makeRecord

[英]python logging.Logger: overriding makeRecord

I have a formatter that expects special attribute in the record, "user_id", that not always there(sometimes I add it to records using special logging.Filter). 我有一个格式化程序,它期望记录“ user_id”中有特殊属性,但并不总是存在(有时我使用特殊logging.Filter将其添加到记录中)。 I tried to override the makeRecord method of logging.Logger like so: 我试图覆盖这样的logging.Logger的makeRecord方法:

import logging

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)-15s user_id=%(user_id)s %(filename)s:%(lineno)-15s: %(message)s')


class OneTestLogger(logging.Logger):
    def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
        rv = logging.Logger.makeRecord(self, name, level, fn, lno,
                                       msg, args, exc_info,
                                       func, extra)
        rv.__dict__.setdefault('user_id', 'master')
        return rv


if __name__ == '__main__':

    logger = OneTestLogger('main')
    print logger
    logger.info('Starting test')

But that doesn't seem to work and I keep getting: 但这似乎不起作用,我不断得到:

< main .MyLogger instance at 0x7f31a6a5b638> < .MyLogger实例位于0x7f31a6a5b638>

No handlers could be found for logger "main" 找不到记录程序“主”的处理程序

What am I doing wrong? 我究竟做错了什么? Thanks. 谢谢。

Following the guideline provided in Logging Cookbook . 遵循《 日志记录食谱》中提供的指南。 Just the first part, I did not implement Filter (which does not appear in the below quote either). 只是第一部分,我没有实现Filter(它也没有出现在下面的引用中)。

This has usually meant that if you need to do anything special with a LogRecord, you've had to do one of the following. 这通常意味着,如果您需要对LogRecord做任何特殊的事情,则必须执行以下操作之一。

  1. Create your own Logger subclass, which overrides Logger.makeRecord(), and set it using setLoggerClass() before any loggers that you care about are instantiated. 创建您自己的Logger子类,该子类将覆盖Logger.makeRecord(),并在实例化您关心的所有记录器之前使用setLoggerClass()对其进行设置。

I have simplifed your exampled just to add the 'hostname': 我简化了您的示例,仅添加了“主机名”:

import logging
from socket import gethostname

logging.basicConfig(level=logging.DEBUG,
                            format='%(asctime)s - %(hostname)s - %(message)s')

class NewLogger(logging.Logger):
    def makeRecord(self, *args, **kwargs):
        rv = super(NewLogger, self).makeRecord(*args, **kwargs)
        # updating the rv value of the original makeRecord
        # my idea is to use the same logic than a decorator by
        # intercepting the value return by the original makeRecord
        # and expanded with what I need
        rv.__dict__['hostname'] = gethostname()
        # by curiosity I am checking what is in this dictionary
        # print(rv.__dict__)
        return rv

logging.setLoggerClass(NewLogger)

logger = logging.getLogger(__name__)
logger.info('Hello World!')

Note that this code worked on python 2.7 请注意,此代码适用于python 2.7

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM