|
Rotary Logger
1.0.2
The middleware rotary logger
|
stdout/, stderr/, stdin/)[STDOUT], [STDERR], [STDIN]) and optional per-call function tracing (e.g. [WRITE], [READLINE])<root>/logs/<year>/<month>/<day>/[<stream>/]<timestamp>.logutf-8)RLock; see developer notes on lock ordering)From PyPI (when published):
From source (recommended for development):
If you only need the package without dev dependencies:
You can use the package as a CLI similar to tee:
You can also use the shortcut: pytee.
It works similarly to python -m rotary_logger.
The positional argument is the base folder where logs will be stored. The package always builds the rest of the path automatically in the following way: path/to/folder/year/month/day/. If you pass -m (--merge), all streams are written to timestamped files directly under the day folder; otherwise two subfolders stdout/ and stderr/ are created, each containing their own timestamped files.
If multiple destination folders are passed, only the first is used and a warning is printed to stderr.
Embed RotaryLogger in your application:
This replaces sys.stdout and sys.stderr with TeeStream wrappers. To stop logging in-process call RL.stop_logging() — this restores the original streams, flushes any buffered data, and unregisters the atexit flush handlers.
The following symbols are exported from the top-level rotary_logger package:
You can find documentation here: docs as well as here: https://hanra-s-work.github.io/rotary_logger/
The source of the logo used in the documentation: https://deepai.org, then edited in gimp.
| Flag | Long form | Description |
|---|---|---|
| (positional) | files | Base folder for log output (optional; disables file logging when omitted) |
-a | --append | Append to existing log files instead of overwriting |
-m | --merge | Merge stdout and stderr into a single log file |
-i | --ignore-interrupts | Ignore Ctrl+C (SIGINT) |
-s N | --max-size N | Maximum log file size in MB before rotation |
RotaryLogger(log_to_file, override, raw_log_folder, default_log_folder, default_max_filesize, merge_streams, *, encoding, merge_stdin, capture_stdin, capture_stdout, capture_stderr, prefix_in_stream, prefix_out_stream, prefix_err_stream, log_function_calls_stdin, log_function_calls_stdout, log_function_calls_stderr) — constructor; does not start loggingRotaryLogger.start_logging(*, log_folder=None, max_filesize=None, merged=None, log_to_file=True, merge_stdin=None) — begin capturing and rotating logsRefer to the module docs (or docstrings) for full API details.
The project uses pytest. From the repository root (inside your virtualenv):
To run the CI-like test harness used during development, use action_test.sh (requires Docker):
threading.RLock instances. The recommended pattern is to snapshot minimal state while holding the lock, release the lock to perform blocking I/O, then re-acquire to commit state. This avoids holding locks during filesystem operations.logs/ folder inside the package directory unless a log_folder is supplied.RotaryLogger exposes a small set of control functions to manage in-process log capturing. These are safe to call from multiple threads, but there are a few rules and guarantees to understand:
start_logging(*, log_folder=None, max_filesize=None, merged=None, log_to_file=True, merge_stdin=None) -> Nonesys.stdout and sys.stderr to TeeStream wrappers and begin writing to rotating files.log_folder — optional base folder to write logs; max_filesize — override rotation size in MB; merged — whether to merge stdout/stderr into a single file; log_to_file — whether to enable file writes; merge_stdin — whether stdin is merged into the shared file.sys.stdout/sys.stderr is performed atomically while holding the lock.stop_logging() -> Nonesys.stdout/sys.stderr/sys.stdin objects.start_logging.pause_logging(*, toggle: bool = True) -> booltoggle=True and logging is active, pause it (uninstall TeeStreams, restore originals); when toggle=True and already paused, resume it. When toggle=False, always pause regardless of current state.resume_logging(*, toggle: bool = False) -> booltoggle=False (default), always resume. When toggle=True and logging is already active, pauses instead.pause_logging.is_logging() -> boolis_redirected(stream: StdMode) -> boolStdMode.STDOUT, STDIN, STDERR) is currently redirected to a TeeStream.atexit.register to attempt a final flush at process exit; those handlers are unregistered when stop_logging() is called. The implementation stores the exact bound-methods used to guarantee atexit.unregister works reliably.start_logging/stop_logging concurrently from multiple threads is heavier and may involve filesystem operations — avoid such patterns in production unless you synchronize externally.capture_stdin=True to the RotaryLogger constructor to wrap sys.stdin.The following environment variables are read at import time and can override default configuration:
| Variable | Type | Default | Description |
|---|---|---|---|
LOG_TO_FILE | bool (1/true/yes) | true | Whether file logging is enabled |
LOG_FOLDER_NAME | str (path) | <package_dir>/logs | Base folder for log output |
LOG_MAX_SIZE | int (bytes) | 2 GB | Maximum log file size before rotation |
The project uses generated Doxygen in different formats:
HTMLLaTeX (every time a version is released)RTF (every time a version is released)You can view the documentation online, by going here: https://hanra-s-work.github.io/rotary_logger/
Please read CONTRIBUTING.md and CODE_OF_CONDUCT.md before opening issues or PRs.
See the LICENSE file in the repository.