Deduplicate and compact structured logs in real time: YAML config, regex or key=value parsing, Unix pipes, CLI (logcompact).
Project description
Log Compactor
Log Compactor merges duplicate log lines and compacts repeated structured events in real time. Use it as a Python library or logcompact CLI to process stdin/stdout (e.g. your-app | logcompact stream), with YAML configuration, optional regex parsing, key=value fallback, and raw pass-through for stack traces. Features include time-window deduplication, ERROR → CRITICAL escalation, HTTP-style level overrides, and field aliases.
If you are looking for log deduplication, log compaction, pipe-friendly log tools, or reduce noisy logs in development and CI, this package is a small, configurable building block.
Installation
From the project root (development):
pip install -e ".[dev]"
Or install the package only:
pip install -e .
The dev extra includes pytest.
Pipe any command’s output
Install the package, add a config.yaml (or pass --config), and pipe stdout through the CLI:
pytest -q 2>&1 | logcompact stream -c /path/to/config.yaml
python app.py 2>&1 | logcompact stream
If you omit -c, the CLI looks for config.yaml in the current working directory.
Configuration (config.yaml)
The CLI loads a YAML file into the same structure SmartCompactor expects as a dict. Example:
# Seconds: identical structured lines (same level + fields) within this span are compacted together.
# If no duplicates arrive within this window, the group is emitted (enabling real-time output).
dedup_window_seconds: 5
# If the level is ERROR and the same message repeats at least this many times in one group, output shows CRITICAL.
error_threshold: 2
# Optional. Named groups must include ts and level; other groups become fields. If no match, key=value parsing is tried.
log_pattern: '^(?P<ts>\S+)\s+(?P<level>\S+)\s+(?P<action>login|logout|upload)\s+(?P<user>\S+)$'
# {ts} is the formatted time range, {level} the level, {fields} sorted key=value; extra {field_name} come from captured fields.
output_template: "{ts} [{level}] {fields}"
# Rename keys (e.g. user_id -> user). If both old and new keys exist with different values, the line is passed through unchanged.
aliases:
user_id: "user"
# If field value parses as an integer in [min, max], replace the log level with new_level (e.g. HTTP 5xx -> ERROR).
level_overrides:
- field: "code"
min: 500
max: 599
new_level: "ERROR"
A copy of this example lives in config.yaml at the repo root.
Library usage
import yaml
from compactor import SmartCompactor
with open("config.yaml") as f:
settings = yaml.safe_load(f)
compactor = SmartCompactor(settings)
for line in compactor.compact_stream(open("app.log")):
print(line)
You can also pass the same keys as a plain dict (no file) for quick experiments.
Tests
pytest
Changelog
See CHANGELOG.md for version history and release notes.
License
This project is licensed under the GNU General Public License v3.0 only. See the LICENSE file for the full license text.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file log_compactor-0.2.0.tar.gz.
File metadata
- Download URL: log_compactor-0.2.0.tar.gz
- Upload date:
- Size: 20.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e554cab91bce2b87751c5c6d7fcea3e1035f39328a0c76d81af9a75918d99c60
|
|
| MD5 |
ef6f6a100871a0b459a9e5affcdd49fb
|
|
| BLAKE2b-256 |
ca9cb4c2213ce5f309207ef3ddbdd006c6f22a2c3da06d44b1e70ce3cfc51097
|
File details
Details for the file log_compactor-0.2.0-py3-none-any.whl.
File metadata
- Download URL: log_compactor-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
983c018c5a265b25ad59efb031d046bc443459342b8273a3b354a495eb69047f
|
|
| MD5 |
7e1de9852f3adb9dde7a6f8452ab4b21
|
|
| BLAKE2b-256 |
8881faddec8288f7d702284e3d425a0dc22d549eda61172dd32eecdba19383ce
|