A handler routes log records from a logger to a destination. Attach a FileHandler to preserve events in a file, or a StreamHandler to display them in a console. section 12.1.2 section 12.1.3
Listing 12.2 Adding a file handler to the logger
logger = logging.getLogger(__name__)
file_handler = logging.FileHandler("taskier.log") #1
logger.addHandler(file_handler) #2
See the focused pattern for creating a file handler and attaching it to a logger. section 12.1.2
Use multiple handlers when records need different destinations or filtering:
- Send the same record to a file and the console for persistent storage and real-time feedback. section 12.1.3
- Set different handler levels so separate files capture different thresholds, such as WARNING and above versus CRITICAL only. section 12.2.2
- Other available destinations include email, web servers, and queues; these are noted but not explored in detail. section 12.1.3
Listing 12.6 Setting levels to individual file handlers
logger.setLevel(logging.DEBUG) #1
handler_warning = logging.FileHandler("taskier_warning.log")
handler_warning.setLevel(logging.WARNING) #2
logger.addHandler(handler_warning)
handler_critical = logging.FileHandler("taskier_critical.log")
handler_critical.setLevel(logging.CRITICAL) #3
logger.addHandler(handler_critical)
logging_messages_all_levels()
warning_log_records = check_log_content("taskier_warning.log")
print(warning_log_records)
# output the following lines:
--Critical message
--Error message
--Warning message
critical_log_records = check_log_content("taskier_critical.log")
print(critical_log_records)
# output the following line:
--Critical message
Compare two file handlers configured to capture different logging levels. section 12.2.2
Avoid attaching the same file handler repeatedly: repeated setup can produce duplicate records. A logger checks its own level before sending a record to handlers, so a handler’s lower threshold cannot make the logger pass a record it rejected. section 12.1.5 section 12.2.5





















