[Solved]-How to override method of the logging module

21👍

You can firstly implement your own logger class by deriving from logging.Logger, in which you override the methods you target. And then you pass the logger class to the logging system by using logging.setLoggerClass. With this setting, the logger objects instantiated from logging.getLogger will be of your class.

update with sample code based on request:

import logging
import threading

class MyLogger(logging.Logger):

    def __init__(self, name, level = logging.NOTSET):
        self._count = 0
        self._countLock = threading.Lock()       

        return super(MyLogger, self).__init__(name, level)        

    @property
    def warnCount(self):
        return self._count

    def warning(self, msg, *args, **kwargs):
        self._countLock.acquire()
        self._count += 1
        self._countLock.release()

        return super(MyLogger, self).warning(msg, *args, **kwargs)

logging.setLoggerClass(MyLogger)
logging.basicConfig()


'''testing below'''

logger = logging.getLogger('loggerX')
assert isinstance(logger, MyLogger)

logger.warning('1st warning')
logger.warning('2nd warning')
print logger.warnCount

0👍

If you planning to override a default logging module, you have to override logging.Handler class. logging.Handler class have a function called emit(self, record) that will be called when we use log functionality in our Django view like this,

# import the logging library
import logging

# Get an instance of a logger
logger = logging.getLogger(__name__)

def my_view(request, arg1, arg):
    ...
    if bad_mojo:
        # Log an error message
        logger.error('Something went wrong!')

overriding logging.Handler class

for my specific requirement, I’m logging message in a database by creating object of ErrorLog but you want to do console, print or even email that you do can do also. by doing an error log in a database you can count logger.info and logger.errors

import logging
import traceback


class ErrorLogHandler(logging.Handler):

def emit(self, record):
    '''this each method called when a log creates '''
    from ..models.error_log import ErrorLog
    # for more info you can use this thing from record object
    # print('levelname', record.levelname)
    # print('filename', record.filename)
    # print('funcName', record.funcName)
    # print('lineno', record.lineno)
    # print('module', record.module)
    # print('args', record.args)
    # print('exc_info', record.exc_info)
    # print('msg', record.msg)

    trace = None
    user_master = None

    if record.exc_info:
        trace = traceback.format_exc()

    if record.args and type(record.args) == dict:
        user_master = record.args.get('user_master')

    kwargs = {
        'logger_name': record.name,
        'level': record.levelname,
        'message': record.msg,
        'function_name': record.funcName,
        'file_name': record.filename,
        'trace': trace,
        'user_master': user_master
    }

    ErrorLog.objects.create(**kwargs)

in settings.py you have to override settings of logging

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(asctime)s %(message)s'
        },
    },
    'handlers': {  # this will handle (called) log initialize
        'db_log': {
            'level': 'INFO',
            'class': 'servicesApp.logging.handler.ErrorLogHandler'
        },
    },
    'loggers': {
        'db': {  # for django app logs
            'handlers': ['db_log'],
            'level': 'INFO'
        },
    }
}

Leave a comment