Getting logging error while using the custom logger class

158 Views Asked by At

I have developed a custom logger class known as ClassNameLogger, which includes an additional parameter called 'className'. I have integrated this specialized logger class into the settings.py by utilizing the logger.setLoggerClass(ClassNameLogger) method. Consequently, when I initiate the server, it successfully commences; however, I am encountering a logging error. I am also getting the logs as expected. But I want to resolve this logging error. The error says:

--- Logging error ---
Traceback (most recent call last):
  File "C:\Users\z004mtzy\AppData\Local\Programs\Python\Python310\lib\logging\__init__.py", line 440, in format
    return self._format(record)
  File "C:\Users\z004mtzy\AppData\Local\Programs\Python\Python310\lib\logging\__init__.py", line 458, in _format
    return self._fmt.format(**values)
KeyError: 'className'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\z004mtzy\AppData\Local\Programs\Python\Python310\lib\logging\handlers.py", line 73, in emit
    if self.shouldRollover(record):
  File "C:\Users\z004mtzy\AppData\Local\Programs\Python\Python310\lib\logging\handlers.py", line 196, in shouldRollover
    msg = "%s\n" % self.format(record)
  File "C:\Users\z004mtzy\AppData\Local\Programs\Python\Python310\lib\logging\__init__.py", line 943, in format
    return fmt.format(record)
  File "D:\ws1\hmi.dashboard\dashboard\custom_logging.py", line 18, in format
  File "C:\Users\z004mtzy\AppData\Local\Programs\Python\Python310\lib\logging\__init__.py", line 681, in format
    s = self.formatMessage(record)
  File "C:\Users\z004mtzy\AppData\Local\Programs\Python\Python310\lib\logging\__init__.py", line 650, in formatMessage
    return self._style.format(record)
  File "C:\Users\z004mtzy\AppData\Local\Programs\Python\Python310\lib\logging\__init__.py", line 442, in format
    raise ValueError('Formatting field not found in record: %s' % e)
ValueError: Formatting field not found in record: 'className'

Here is my custom_logging.py:

import logging

class ClassNameLogger(logging.Logger):
    def __init__(self, name):
        super().__init__(name)

    def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
        if extra is None:
            extra = {}
        # Automatically add the class name to the extra attributes
        extra['className'] = self.name
        super()._log(level, msg, args, exc_info, extra, stack_info)

class CustomFormatter(logging.Formatter):
    def format(self, record):
        if 'className' in record.__dict__:
            record.msg = f"[{record.__dict__['className']}] {record.msg}"
        return super().format(record)

And my settings.py is like this

import dashboard.custom_logging
LOGS_DIR = os.path.join(Path("D:\practice"), "example")

logging.setLoggerClass(dashboard.custom_logging.ClassNameLogger)

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'dashboard': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # Use the custom handler defined in this script
            #Modify this filename before starting the server, this file name used for deployement
            'filename': os.path.join(LOGS_DIR, "example.log"),
            'backupCount': 14,  # Number of backup files to keep
            'maxBytes': 52428800, #Roll over once the file size reaches 50 MB
            'formatter': 'verbose',
        },
    },
    'formatters': {
        'verbose': {
            '()': 'dashboard.custom_logging.CustomFormatter',
            'format': '{levelname} :::: {asctime} :::: {module} :::: {className} :::: {funcName} :::: {lineno} :::: {message}',
            'style': '{',
        },
    },
    'root': {
        'handlers': ['dashboard'],
        'level': 'DEBUG',  # Adjust the level as needed
        'propagate': False,  # Prevent propagation to the root logger
    }
}

#Set the custom logger class and configure logging
logging.config.dictConfig(LOGGING)

Here is the example of how I used the logger:

from custom_logging import ClassNameLogger

# Create an instance of ClassNameLogger
logger = ClassNameLogger(__class__.__name__)

# Log messages using the custom logger
logger.debug('Debug message')
0

There are 0 best solutions below