logset¶
Convenience functions for setting up console and file logs.
About¶
Python’s logging library is powerful, but comes with a steep learning curve and several common “gotchas”. The logset library helps address this by providing convenience functions for setting up basic console (sys.stderr) and file logs. Each function lets you configure a log at a given logging level using a single function call.
Critically, logset requires minimal familiarity with the logging library, so developers can simply focus on what their logs should do, without needing to manage complex logging objects. The commands also help prevent issues wherein (1) messages are not logged as expected, and (2) messages are duplicated in a logging target.
Examples¶
Log messages to the console (sys.stderr) at a given level:
import logset
logset.console.debug("my-logger") # Logs at the DEBUG level
logset.console.info("my-logger") # Logs at the INFO level
# Also includes functions for the "warning", "error", and "critical" levels
Log messages to file at a given level:
logset.file.debug("my-logger", "my-file.log")
logset.file.info("my-logger", "my-file.log")
# Also includes functions for the "warning", "error", and "critical" levels
Customize the format of different logs:
logset.console.info("my-logger", "%(message)s")
logset.file.debug("my-logger", "my-file.log", "%(asctime)s - %(name)s - %(message)s)
Log to a file that rotates after reaching a maximum allowed size:
# Rotates after reaching 1MB, saving backups of the 2 most recent rotated logs
logset.file.info("my-logger", "my-file.log", rotate_bytes=1000000, backup_count=2)
Log to a file that rotates on a fixed time interval:
# Rotates after 7 days, saving backups of the 2 previous logs
logset.file.info(
"my-logger", "my-file.log", rotate_when="D", rotate_interval=7, backup_count=2
)
Caution
Rotating on a fixed time interval is only supported for long-running processes. Consult the user guide for more details.
Why use logset?¶
Action oriented¶
The motivation for logset is to allow developers to focus on what their logs should do, without requiring familiarity with the complex logging ecosystem. For example, to implement an application that:
Logs messages to the console at the info level, and
Logs timestamped messages to a file at the debug level
you can use the simple and readable:
logset.console.info("my-logger")
logset.file.debug("my-logger", "my-file.log", format="%(asctime)s - %(message)s")
By contrast, implementing the same task with the logging library would require you to create a Logger, StreamHandler, FileHandler, and two Formatter objects, and then configure the logger and handler logging levels to ensure the correct messages are emitted to the correct places.
Preventing common “gotchas”¶
Another motivation for logset is to help prevent two common “gotchas” that can occur when working the with the logging library.
The first common issue occurs when a handler is attached to a Logger with a certain logging level, but then seemingly fails to emit messages because the associated Logger object is incorrectly set to a higher logging level. Logset addresses this by ensuring loggers are set to a logging level at least as low as any new handlers.
A second common issue occurs when a logger has multiple handlers logging to sys.stderr or to the same file. When this occurs, the console or file is filled with duplicated messages as multiple handlers emit the same message to the same place. Logset addresses this by removing handlers with duplicate targets whenever a new handler is added.