log tailer: the rotated mail.log read until postlogd lets it go
test / test (push) Canceled after 0s

postlogd opens maillog_file once per process (Postfix 3.7.11,
src/postlogd/postlogd.c, pre_jail_init()) and leaves it only when it
exits: at "postfix reload" master closes the service's status pipe
(src/master/master_service.c, master_restart_service() ->
master_status_cleanup()) and dgram_server_abort() exits on reading its end
(src/master/dgram_server.c). logrotate renames and creates, then runs the
reload (build/logrotate-mail.conf postrotate; logrotate 3.21.0,
logrotate.c, rotateLogSet(), after rotateSingleLog()), so lines go to the
renamed file in between, and the tailer, already on the new one, never
read them (assumptions A-33). follow() now keeps the renamed file open as a
rotatedTail and reads it on each tick for rotatedGrace (a minute, far
longer than the gap); its places are never saved as the resume point, so a
restart still reads the rotated file through readRotated. A truncated file
is not kept.

The RFC 3339 stamp goes (A-12): it was written for a maillog_file_format
said to arrive in Postfix 3.9; there is none in 3.7.11 nor in the 3.12
snapshot of 2026-09-25 (proto/postconf.proto; msg_logger.c,
msg_logger_print() keeps strftime("%b %d %H:%M:%S ")). Every fixture now
carries the stamp Postfix writes; logtail's TestMain fixes time.Local to
UTC, since the stamp is local time and this PC is UTC+3.

Tests: TestFollowReadsTheRotatedFileAfterTheSwitch (Linux: a line appended
to the renamed file after the switch reaches the store). Stand
(2026-10-14): go vet and go test ./... pass on the server (23 packages);
make e2e exit 0, delivery_log_survives_rotation included. The tested tree
was this commit plus the previous one; the CHANGELOG entry was written
after the run, and a comment's logrotate citation corrected
(rotateLogSet runs postrotate, not rotateSingleLog).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-14 23:12:37 +03:00
co-authored by Claude Opus 5.5
parent e174537512
commit 463d4ff3fe
11 changed files with 216 additions and 116 deletions
+6
View File
@@ -43,6 +43,12 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); version
message forced to expire (`postsuper -e`, `#` in the queue listing) is
still counted as held (audit 2026-10-12, stage 2c; assumptions A-8,
B-PQ1).
- **Lines Postfix writes while `mail.log` is being rotated are read.**
Postfix's log writer keeps the old file open until the reload that
follows the rotation; the log tailer switched to the new file at once,
so a delivery written in between never reached its row, which the sweep
later closed as `bounced`. The tailer now reads the rotated file for a
minute more (assumptions A-33).
- **Postfix's time values are read as Postfix reads them.** A bare number
took seconds, so `maximal_queue_lifetime = 3` was three seconds to the
panel and three days to Postfix; `1h7m` was 67 minutes to the panel and