feat: historic logs named off the project namespace (cwd basename / history_name)
the live file keeps its defined name (latest.log); rolled/historic files are now named off the PROJECT namespace so you can tell which service a log came from at a glance. default = os.path.basename(os.getcwd()) (run from bestbuy/ -> historic bestbuy.<stamp>.log[.gz]); override with the new history_name= param. - decouple the rolled stem (history) from the live stem (name) in setup.py; thread history_stem into BOTH the namers AND prune/retier (same stem, or retention breaks). - unify size + daily on make_history_namer -> <stem>.<stamp>.log[.gz] (was stdlib .N / .log.<date>); rotate_on_start takes history_stem. behavior-visible: rolled names differ from pre-0.5.0 (were the live stem). pass history_name=name for the old naming. execute-verified across on_start/daily/size (tiered + non-tiered), default-cwd + explicit + history==name + normalization edges; v0.4.x fixes (rotation/tiering/retention) all still hold. bump v0.4.3 -> v0.5.0 Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
@@ -13,12 +13,12 @@ and emit; their records flow into the handlers `log_setup` wired.
|
||||
## Install
|
||||
|
||||
```
|
||||
log_setup @ git+ssh://git@git.rethinkstudios.io/rethink-public/log_setup.git@v0.4.3
|
||||
log_setup @ git+ssh://git@git.rethinkstudios.io/rethink-public/log_setup.git@v0.5.0
|
||||
```
|
||||
|
||||
No dependencies — stdlib only.
|
||||
|
||||
Drop the `@v0.4.3` suffix from the line above to install the latest unpinned.
|
||||
Drop the `@v0.5.0` suffix from the line above to install the latest unpinned.
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -43,14 +43,14 @@ emits; the records land in the configured root.
|
||||
- **Format:** `2026-06-27 19:55:05 | module.name | INFO | message`. `%(name)s` is the
|
||||
`getLogger` name each module used, so you see which lib/module logged.
|
||||
- **Rotation** (`rotate=`):
|
||||
- `"daily"` (default) — rolls at midnight, dated name into `log_dir`, keeps
|
||||
`backup_count` days.
|
||||
- `"size"` — rolls at `max_bytes`; numbered backups (`run.log.1`, `.2`, …) in `log_dir`
|
||||
for the default flat retention, or timestamped names when tiered retention is on (below).
|
||||
- `"on_start"` — on startup, moves an existing `run.log` into `log_dir`
|
||||
(`run.<timestamp>.log[.gz]`) and starts fresh; prunes to `backup_count`.
|
||||
- `"daily"` (default) — rolls at midnight into `log_dir`, keeps `backup_count` days.
|
||||
- `"size"` — rolls at `max_bytes` into `log_dir`, keeps `backup_count`.
|
||||
- `"on_start"` — on startup, moves an existing live file into `log_dir` and starts fresh;
|
||||
prunes to `backup_count`.
|
||||
- `None` — single file, no rotation.
|
||||
- **compress=True** (default) gzips each rolled file (`run.log.2026-06-27.gz`).
|
||||
- **Historic files are named off the project** — see below. Every rolled file is
|
||||
`<project>.<timestamp>.log[.gz]`; the live file keeps its own name.
|
||||
- **compress=True** (default) gzips each rolled file.
|
||||
- **Retention** = `backup_count` (default 14) for every mode — unless tiered retention is
|
||||
enabled (below).
|
||||
- **console=True** (off by default) also logs to stdout in the same format — opt in when
|
||||
@@ -59,6 +59,28 @@ emits; the records land in the configured root.
|
||||
The `name` you pass is normalized so it produces exactly one `.log`: `name="latest"` and
|
||||
`name="latest.log"` both yield the live file `latest.log` (never `latest.log.log`).
|
||||
|
||||
## Historic files are named off the project (`history_name`)
|
||||
|
||||
The **live** file keeps its defined `name` (`latest.log`). The **historic** (rolled/gz)
|
||||
files are named off the **project namespace** — by default the current directory's basename
|
||||
— so you can tell at a glance which service a log came from:
|
||||
|
||||
```python
|
||||
# app run from bestbuy/run.py , with name="latest":
|
||||
setup_logging(name="latest", rotate="daily")
|
||||
# logs/
|
||||
# latest.log <- live (the tail -f target)
|
||||
# bestbuy.2026-07-01_02-00-00.log <- historic, named off the project dir
|
||||
# bestbuy.2026-06-30_02-00-00.log.gz
|
||||
```
|
||||
|
||||
- **Default** = `os.path.basename(os.getcwd())` (the project directory). Zero config.
|
||||
- Override with **`history_name="foo"`** → historic files become `foo.<timestamp>.log[.gz]`.
|
||||
- This changed in **v0.5.0**: historic files used to reuse the live `name`. To keep the old
|
||||
behavior, pass `history_name=name`.
|
||||
- Retention (tier counts / `backup_count`) is unchanged — it's just keyed to the project
|
||||
stem now.
|
||||
|
||||
## Tiered retention (`keep_uncompressed` / `keep_compressed`)
|
||||
|
||||
The default is a flat `backup_count`: every rolled file is gzipped on roll and the oldest
|
||||
@@ -134,6 +156,7 @@ setup_logging(
|
||||
level="INFO", # root level everything inherits (str name or logging constant)
|
||||
module_levels=None, # {logger_name: level} per-logger overrides (exact name match)
|
||||
rotate="daily", # "daily" | "size" | "on_start" | None
|
||||
history_name=None, # stem for rolled/historic files; None -> cwd basename (project)
|
||||
backup_count=14, # rotated files to keep (flat retention; ignored if tiered)
|
||||
keep_uncompressed=None, # tiered: newest N rolled logs kept PLAIN (opt-in)
|
||||
keep_compressed=None, # tiered: next M rolled logs kept GZIPPED (opt-in)
|
||||
|
||||
Reference in New Issue
Block a user