Registry / observability / concurrent-log-handler

concurrent-log-handler

JSON →
library0.9.29pypypi✓ verified 26d ago

A robust drop-in replacement for Python's `RotatingFileHandler` and `TimedRotatingFileHandler` that supports safe concurrent writes from multiple processes and threads. It also includes features like gzip compression and better Windows compatibility. The library is actively maintained, with frequent minor releases addressing bugs and adding features, typically every few months.

pip install concurrent-log-handler
INSTALL
IMPORT
SIG · CONCURRENT-LOG-HAN
C
concurrent-log-handler
observabilitypythonv0.9.29
Install
1.6s avg
Import
152ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v0.9.29 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.162s · 18.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.6s · import 0.142s · 19MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

ConcurrentRotatingFileHandler
from concurrent_log_handler import ConcurrentRotatingFileHandler
from logging.handlers import RotatingFileHandler
The standard RotatingFileHandler does not provide robust concurrent access from multiple processes.
ConcurrentTimedRotatingFileHandler
from concurrent_log_handler import ConcurrentTimedRotatingFileHandler
from logging.handlers import TimedRotatingFileHandler
The standard TimedRotatingFileHandler does not provide robust concurrent access from multiple processes.

This example demonstrates how to set up a basic logger using `ConcurrentRotatingFileHandler` to ensure log file rotation works safely across multiple processes, preventing data loss or corruption due to concurrent writes. It configures a log file to rotate after reaching 10MB, keeping 5 backup copies.

import logging import os from concurrent_log_handler import ConcurrentRotatingFileHandler log_file_path = os.path.join(os.getcwd(), 'app.log') # Configure logging log = logging.getLogger('my_app') log.setLevel(logging.INFO) # Use ConcurrentRotatingFileHandler # Rotate log after reaching 10MB, keep 5 old copies. # Set encoding to 'utf-8' to avoid UnicodeEncodeError on some systems. handler = ConcurrentRotatingFileHandler( log_file_path, 'a', 10 * 1024 * 1024, 5, encoding='utf-8' ) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) log.addHandler(handler) log.info('This is an informational message.') log.warning('This is a warning message.') log.error('This is an error message.') print(f"Log messages written to: {log_file_path}")
Debug
Known issues
breakingPython 2.x support was dropped. Versions 0.9.23 and higher require Python 3.6 or higher.
fix
Upgrade your Python environment to 3.6 or newer if you are using an older Python 2.x interpreter.
affects: >=0.9.23
gotchaWhen using `fork()` to create new processes, log handlers inherited by child processes could experience race conditions, leading to corrupted logs or deadlocks.
fix
As of 0.9.29, inherited handlers automatically reopen lock files for isolation. However, it is still strongly recommended to re-initialize your logging configuration *after* calling `os.fork()` in child processes to ensure full isolation and robust behavior.
affects: <0.9.29
deprecatedThe `queue.py` `setup_logging_queues()` function has been deprecated and should no longer be used.
fix
Remove calls to `setup_logging_queues()`. The standard synchronous logging calls with this handler are generally sufficient and recommended.
affects: >=0.9.27
gotchaBefore 0.9.28, if an application shut down during a scheduled rollover time (e.g., for `ConcurrentTimedRotatingFileHandler`), the handler might miss the rollover entirely and skip to the next scheduled time without rotating accumulated logs.
fix
Upgrade to version 0.9.28 or later. The handler now performs catch-up rollovers on initialization if scheduled times were missed.
affects: <0.9.28
gotchaSince 0.9.26, the handler keeps file handles open (`keep_file_open=True` by default) for performance. However, on Windows, the log file must still be closed after each write for rollovers to occur correctly due to filesystem API behavior.
fix
No direct fix needed, but be aware of this internal behavior. If you experience unexpected issues with file handles, you can revert to the old behavior by explicitly setting `keep_file_open=False` in the handler constructor, though this may impact performance.
affects: >=0.9.26
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'concurrent-log-handler'
The 'concurrent-log-handler' package is not installed in the Python environment, or there's a typo in the import statement.
fix
Install the package using pip: `pip install concurrent-log-handler`. Ensure the import statement is `from concurrent_log_handler import ConcurrentRotatingFileHandler` (or `ConcurrentTimedRotatingFileHandler`).
ImportError: No module named 'win32con'
On Windows, 'concurrent-log-handler' relies on the `pywin32` library for robust file locking, which is not an automatic dependency and must be installed separately.
fix
Install the `pywin32` package: `pip install pywin32`.
cannot acquire lock
This typically occurs in multiprocessing environments where child processes inherit logging handlers from the parent. Each process needs its own handler instance to correctly manage file locks.
fix
Ensure that each child process creates its own `ConcurrentRotatingFileHandler` or `ConcurrentTimedRotatingFileHandler` instance after forking, rather than inheriting one from the parent process. Re-initializing logging post-fork is recommended.
AttributeError: 'NoneType' object has no attribute 'write'
This error, particularly prevalent in older versions, could be triggered if a log file rollover occurred while a logging statement was being formatted, leading to the handler's stream being `None`.
fix
Update to the latest version of `concurrent-log-handler` to benefit from bug fixes. If the issue persists, simplify log message formatting or ensure critical log calls are not intertwined with complex formatting that could cause rollovers mid-operation.
Upgrade
Version history
0.9.29latest on PyPI · released Feb 22, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
58 hits · last 30 days
node
50
OpenAI (training)
1
Resources
concurrent-log-handler — pip install concurrent-log-handler · libregistry