简体   繁体   中英

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). I tried to override the makeRecord method of logging.Logger like so:

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>

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).

This has usually meant that if you need to do anything special with a LogRecord, you've had to do one of the following.

  1. Create your own Logger subclass, which overrides Logger.makeRecord(), and set it using setLoggerClass() before any loggers that you care about are instantiated.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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