fix: rotate-mode-aware zero-retention delete in make_rotator (logsetup-1)

v0.5.1's rotate="size" fix added an unconditional os.remove(dest) at
backup_count<=0 in make_rotator to bound the live file, but the rotator is
shared with rotate="daily" and had no mode awareness - every midnight roll
under daily with backup_count=0 was deleting the just-rolled log instead of
leaving it unpruned. make_rotator/attach_rolling now take rotate_mode and
gate the delete-on-land branch to "size" only, matching the documented
contract that only size always bounds the live file. Bump 0.6.1 -> 0.6.2.

Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
2026-07-03 16:15:03 -04:00
parent 4d1acc3a47
commit e78a384f1a
5 changed files with 30 additions and 16 deletions
+8 -2
View File
@@ -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.6.1
log_setup @ git+ssh://git@git.rethinkstudios.io/rethink-public/log_setup.git@v0.6.2
```
No dependencies — stdlib only.
Drop the `@v0.6.1` suffix from the line above to install the latest unpinned.
Drop the `@v0.6.2` suffix from the line above to install the latest unpinned.
## Quick start
@@ -248,6 +248,12 @@ setup_logging(name="run", queue=True)
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.
- **`"daily"` regression fixed (v0.6.2).** v0.5.1's `rotate="size"` fix above shared its
rotator with `"daily"`, so a `rotate="daily", backup_count=0` roll was incorrectly
deleted at every midnight rollover instead of just landing unpruned. The rotator is now
rotate-mode aware: the zero-retention delete only ever fires for `"size"`, matching the
contract in the bullet above — `"daily"`/`"on_start"` with `backup_count=0` were always
meant to roll without pruning and now do again.
- **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