3

Recently I came across logging in python.

I have the following code in test.py file

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
logger.debug("test Message")

Now, is there any way I can print the resulting Logrecord object generated by logger.debug("test Message") because it's stated in the documentation that

LogRecord instances are created automatically by the Logger every time something is logged

https://docs.python.org/3/library/logging.html#logrecord-objects

I checked saving debug into a variable and print it

test = logger.debug("test Message")
print(test)

the output is NONE

My goal is to check/view the final Logrecord object generated by logging.debug(test.py) in the same test.py by using print() This is for my own understanding.

print(LogrecordObject.__dict__)

So how to get hold of the Logrecord object generated by logger.debug("test Message")

DennisLi
  • 3,915
  • 6
  • 30
  • 66
Santhosh
  • 9,965
  • 20
  • 103
  • 243
  • 2
    debug() doesn't return anything. The logging record it generates is sent down to the logging module and processed through whatever handlers you have configured. If you really want to examine the record that gets passed through, you might want to implement your own handler and add it to the logger. – Mad Wombat Aug 08 '19 at 21:15

2 Answers2

1

There is no return in debug()

# Here is the snippet for the source code
    def debug(self, msg, *args, **kwargs):
        if self.isEnabledFor(DEBUG):
            self._log(DEBUG, msg, args, **kwargs)

If you wanna get LogRecord return, you need to redefine a debug(), you can overwrite like this:

import logging

DEBUG_LEVELV_NUM = 9 
logging.addLevelName(DEBUG_LEVELV_NUM, "MY_DEBUG")

def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
    sinfo = None
    fn, lno, func = "(unknown file)", 0, "(unknown function)"
    if exc_info:
        if isinstance(exc_info, BaseException):
            exc_info = (type(exc_info), exc_info, exc_info.__traceback__)
        elif not isinstance(exc_info, tuple):
            exc_info = sys.exc_info()
    record = self.makeRecord(self.name, level, fn, lno, msg, args,
                             exc_info, func, extra, sinfo)
    self.handle(record)
    return record


def my_debug(self, message, *args, **kws):
    if self.isEnabledFor(DEBUG_LEVELV_NUM):
        # Yes, logger takes its '*args' as 'args'.
        record = self._log(DEBUG_LEVELV_NUM, message, args, **kws)
        return record

logger = logging.getLogger(__name__)
logging.Logger.my_debug = my_debug
logging.Logger._log = _log
logger.setLevel(DEBUG_LEVELV_NUM)
logger.addHandler(logging.StreamHandler())
test = logger.my_debug('test custom debug')
print(test)

Reference: How to add a custom loglevel to Python's logging facility

DennisLi
  • 3,915
  • 6
  • 30
  • 66
1

You can create a handler that instead of formatting the LogRecord instance to a string, just save it in a list to be viewed and inspected later:

import logging
import sys


# A new handler to store "raw" LogRecords instances
class RecordsListHandler(logging.Handler):
    """
    A handler class which stores LogRecord entries in a list
    """
    def __init__(self, records_list):
        """
        Initiate the handler
        :param records_list: a list to store the LogRecords entries
        """
        self.records_list = records_list
        super().__init__()

    def emit(self, record):
        self.records_list.append(record)


# A list to store the "raw" LogRecord instances
logs_list = []

# Your logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# Add the regular stream handler to print logs to the console, if you like
logger.addHandler(logging.StreamHandler(sys.stdout))

# Add the RecordsListHandler to store the log records objects
logger.addHandler(RecordsListHandler(logs_list))


if __name__ == '__main__':

    logger.debug("test Message")
    print(logs_list)

Output:

test Message
[<LogRecord: __main__, 10, C:/Automation/Exercises/222.py, 36, "test Message">]
jonpinto
  • 11
  • 2