If you’re like me, you abuse ‘print’ and have lots of little warning, or generic exceptions printing various levels of messages to the console of your Python applications. Sometimes the messages are informational, and other times they represent critical errors. You’d like to be able to categorize these levels of printed messages. Sometimes you also have messages printed that come from another software library. In those cases, because the message is dynamically generated, you aren’t sure where in the code, exactly, the error message occurred. In those cases you’d like to have the file and line numbers where the message was printed.
Well, you’re in luck. There’s been a handy little library in Python for a number of years called logging and it does all of this. You can categorize the various levels of messages as: debug, info, warning, error, and critical. Alternatively, you can then set the level of messages that you want to be logged, or printed, so that you would only see messages for level of ‘warning’ or above. Additionally, the messages you log/print can automatically have the time prepended, as well as the file and line number. Here’s a short example.
import logging
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(levelname)-8s %(filename)s:%(lineno)-4d: %(message)s',
datefmt='%m-%d %H:%M',
)
logging.debug('A debug message')
logging.info('Some information')
logging.warning('A shot across the bow')
To give you an idea of what logging is doing for you, you could write your own logging function that did roughly (and I mean roughly), the same thing. Here’s a logging function that prints the file, line, and a prefix (which could be info, warning, error, etc.). There is no concept of filtering the level of messages with this example, however.
import inspect
def logfileline(msg, prefix=''):
''' Utility function to log a message and automatically print the file
and line number the log function was called from. '''
frame, module = None, None
if prefix != '' and not prefix.endswith(' '):
prefix = prefix + ' '
try:
frame = inspect.stack()[1][0]
module = inspect.getmodule(frame)
print '{0}{1}::{2}:\n\t{3}'.format(prefix, frame.f_lineno,
frame.f_code.co_filename, msg)
finally:
if frame is not None:
del frame
if module is not None:
del module
So there you have it. Two little examples of logging/printing messages at different levels with the option for file and line numbers.
Tags: logging, python