fix: gzip crash-safety + size rotation always bounds live file (logsetup-7/8/9)
_gzip_file now writes to a .tmp sibling and atomically os.replaces it onto the final .gz path, so a crash/OOM mid-write can never leave a truncated .gz where retention trusts it; retier's plain/gz dedupe additionally verifies a .gz decompresses cleanly before removing its plain twin, so a corrupt .gz is never preferred over the last intact copy. rotate="size" now always forces the handler's backupCount to fire regardless of backup_count, so backup_count=0 means "keep zero rolled files" (each roll deletes itself immediately) instead of silently disabling rotation and growing the live file unbounded. Also mirrors retier's mtime+roll-counter sort key into prune() so a same-second burst with tied mtimes prunes the oldest files instead of arbitrary listdir order (logsetup-9, adjacent one-line fix). Bumps to v0.5.1. 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.5.0
|
||||
log_setup @ git+ssh://git@git.rethinkstudios.io/rethink-public/log_setup.git@v0.5.1
|
||||
```
|
||||
|
||||
No dependencies — stdlib only.
|
||||
|
||||
Drop the `@v0.5.0` suffix from the line above to install the latest unpinned.
|
||||
Drop the `@v0.5.1` suffix from the line above to install the latest unpinned.
|
||||
|
||||
## Quick start
|
||||
|
||||
@@ -44,7 +44,10 @@ emits; the records land in the configured root.
|
||||
`getLogger` name each module used, so you see which lib/module logged.
|
||||
- **Rotation** (`rotate=`):
|
||||
- `"daily"` (default) — rolls at midnight into `log_dir`, keeps `backup_count` days.
|
||||
- `"size"` — rolls at `max_bytes` into `log_dir`, keeps `backup_count`.
|
||||
- `"size"` — rolls at `max_bytes` into `log_dir`, keeps `backup_count`. `backup_count=0`
|
||||
means **keep no rolled history**: the live file still rolls at `max_bytes` (size is
|
||||
always bounded), each rolled file is deleted immediately after landing — it does not
|
||||
disable rotation (see **Retention** below).
|
||||
- `"on_start"` — on startup, moves an existing live file into `log_dir` and starts fresh;
|
||||
prunes to `backup_count`.
|
||||
- `None` — single file, no rotation.
|
||||
@@ -52,7 +55,8 @@ emits; the records land in the configured root.
|
||||
`<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).
|
||||
enabled (below). For `rotate="size"`, `backup_count=0` is "keep none" (not "disable
|
||||
rotation") — see the `size` bullet above and the note at the bottom of this section.
|
||||
- **console=True** (off by default) also logs to stdout in the same format — opt in when
|
||||
you want live terminal output alongside the file.
|
||||
|
||||
@@ -228,6 +232,21 @@ setup_logging(name="run", queue=True)
|
||||
duplicate lines) and leaves handlers your app added itself alone.
|
||||
- **Never crashes the app over logging:** if `log_dir` isn't writable, it falls back to
|
||||
console-only with a warning instead of raising.
|
||||
- **`rotate="size"` always bounds the live file (v0.5.1+).** Previously, `backup_count=0`
|
||||
with `rotate="size"` silently disabled rotation entirely (the live file grew forever,
|
||||
ignoring `max_bytes`). As of v0.5.1, the live file always rolls at `max_bytes`
|
||||
regardless of `backup_count`; `backup_count=0` means "keep zero rolled files" (each roll
|
||||
is deleted right after it lands) rather than "never roll." `backup_count>=1` behaves as
|
||||
documented (keeps that many rolled files). This does not change `"daily"`/`"on_start"`,
|
||||
where `backup_count=0` still means "roll, but don't prune the rolled files" (unbounded
|
||||
`log_dir` growth) — that is a separate, pre-existing knob, not this fix's scope.
|
||||
- **Gzip writes are crash-safe (v0.5.1+).** `_gzip_file` now writes to a `.tmp` sibling and
|
||||
atomically `os.replace`s it onto the final `.gz` path, so a crash/OOM/power-loss mid-write
|
||||
can never leave a truncated `.gz` at the path retention logic trusts. Tiered retention's
|
||||
plain/gz dedupe additionally verifies a `.gz` decompresses cleanly before deleting its
|
||||
plain twin — a corrupt `.gz` (from before this fix, or an external cause) is never
|
||||
preferred over an intact plain copy; the plain is kept and the `.gz` gets rewritten
|
||||
cleanly on the next retier pass instead of being deleted.
|
||||
|
||||
## Scope — what this is NOT
|
||||
|
||||
|
||||
Reference in New Issue
Block a user