4

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

1
  • 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. Commented Aug 8, 2019 at 21:15

3 Answers 3

1

A quick way if you just wish to view the LogRecord attributes, you can specify a subset of them as string replacements in a giant string like below.

import logging view_all_logrecord_attributes = """ asctime - %(asctime)s created - %(created)f filename - %(filename)s funcName - %(funcName)s levelname - %(levelname)s levelno - %(levelno)s lineno - %(lineno)d message - %(message)s module - %(module)s msecs - %(msecs)d name - %(name)s pathname - %(pathname)s process - %(process)d processName - %(processName)s relativeCreated - %(relativeCreated)d thread - %(thread)d threadName - %(threadName)s """ logging.basicConfig(format= view_all_logrecord_attributes, level=logging.DEBUG) logging.debug('Message text here') 

The list is from the documentation: https://docs.python.org/3/library/logging.html#logrecord-attributes

And an example output would be:

asctime - 2024-02-21 08:42:10,428 created - 1708465330.428894 filename - <stdin> funcName - <module> levelname - DEBUG levelno - 10 lineno - 1 message - Message text here module - <stdin> msecs - 428 name - root pathname - <stdin> process - 94365 processName - MainProcess relativeCreated - 749 thread - 8042958848 threadName - MainThread 
Sign up to request clarification or add additional context in comments.

Comments

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

5 Comments

I want to view the Logrecord created. What you show is about returning the message.
so, you wanna get Logrecord printed?
Yes, As you know the Logrecord has lot of attributes like thread, asctime, pathname, processName etc (check docs.python.org/3/library/logging.html#logrecord-attributes). So i wanted to view that.
Thank you for sharing the custom loglevel thing
my pleasure. :)
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">] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.