Rather than simply using
print() statements, I tend to use the logging module for generating console output.
It has a number of advantages over
print() statements. The first is that we can specify a logging threshold
import logging # initialise the Root logger logging.basicConfig(format="%(asctime)s.%(msecs)03d:%(levelname)s:%(name)s:\t%(message)s", datefmt='%H:%M:%S') # now get a named instance of the logger for our application logger = logging.getLogger(__name__) # Set the logging threshold of our logging instance to DEBUG logger.setLevel(logging.DEBUG) # print some stuff logger.debug("We'll see this.") logger.info("And this.") # now set threshold to INFO; everything below INFO is now suppressed logger.setLevel(logging.INFO) # print some more stuff logger.debug("We will NOT see this.") logger.info("But we will see this.")
The output from the above looks like this:
09:08:46.929:DEBUG:__main__: We'll see this. 09:08:46.929:INFO:__main__: And this 09:08:46.929:INFO:__main__: But we will see this.
Note that we must first
Another advantage is that you can customise what appears in the console messages. For example, this initial configuration tells the logger to print the time, the logging level, the name of the logger, and then the message.
# It will print the time (including milliseconds), the logging level, and the logger name logging.basicConfig(format="%(asctime)s.%(msecs)03d:%(levelname)s:%(name)s:\t%(message)s", datefmt='%H:%M:%S')
We can also configure our logger to print logging messages to a file, rather than to the console. For example:
logging.basicConfig( filename='example.log', encoding='utf-8', level=logging.DEBUG, format='%(asctime)s:%(levelname)s:\t%(message)s') logging.debug('This message should go to the log file')
The logging configuration itself can also be placed externalised to a file, rather than coded into the program.
It’s worth noting how we can pass varaibles into a logging statement. This is a typical example:
import logging # setup logging.basicConfig(format="%(asctime)s.%(msecs)03d:%(levelname)s:%(name)s:\t%(message)s", datefmt='%H:%M:%S') logger = logging.getLogger("FooBar-App") logger.setLevel(logging.INFO) my_key = "foo" my_val = "bar" logger.info("My key is named %s, and it's value is %s", my_key, my_val)
%s within the string message itself is a placeholder for a variable. The variables are passed after the string message, as a comma-separated list.
The output looks like this:
08:41:25.172:INFO:FooBar-App: My key is named foo, and it's value is bar
To wrap up: the Python logging module is pretty sophisticated. I’ve only touched the surface here. Check the documentation for more details.