3 Multiple handlers and formatters Loggers are plain Python objects. The addHandler() method has no minimum or maximum quota for the number of handlers you may add. Sometimes it will be beneficial for an application to log all messages of all severities to a text file while simultaneously logging errors or above to the console. To set this up, simply configure the appropriate handlers. The logging calls in the application code will remain unchanged. Here is a slight modification to the previous simple module-based configuration example: Notice that the ‘application’ code does not care about multiple handlers. All that changed was the addition and configuration of a new handler named fh . The ability to create new handlers with higher- or lower-severity filters can be very helpful when writing and testing an application. Instead of using many$_{print}$ statements for debugging, use$_{logger.debug}$ : Unlike the print statements, which you will have to delete or comment out later, the logger.debug statements can remain intact in the source code and remain dormant until you need them again. At that time, the only change that needs to happen is to modify the severity level of the logger and/or handler to debug. Let’s say you want to log to console and file with different message formats and in differing circumstances. Say you want to log messages with levels of DEBUG and higher to file, and those messages at level INFO and higher to the console. Let’s also assume that the file should contain timestamps, but the console messages should not. Here’s how you can achieve this: import logging # set up logging to file - see previous section for more details logging.basicConfig(level =logging.DEBUG, format=' %(asctime)s %(name)-12s %(levelname)-8s %(message)s ', datefmt='%m- %d %H:%M ', filename='/temp/myapp.log ', filemode='w') # define a Handler which writes INFO messages or higher to the sys.stderr (continues on next page) 4 Logging to multiple destinations import logging logger=logging.getLogger('simple_example ') logger.setLevel(logging .DEBUG) # create file handler which logs even debug messages fh =logging.FileHandler('spam.log ') fh.setLevel(logging .DEBUG) # create console handler with a higher log level ch =logging.StreamHandler() ch.setLevel(logging .ERROR) # create formatter and add it to the handlers formatter =logging.Formatter(' %(asctime)s - %(name)s - %(levelname)s - %(message)s ↪ → ') ch.setFormatter(formatter) fh.setFormatter(formatter) # add the handlers to logger logger.addHandler(ch) logger.addHandler(fh) # 'application' code logger.debug( 'debug message') logger.info('info message') logger.warning( 'warn message') logger.error('error message') logger.critical( 'critical message') 5