docs: split README into overview and operator guide for release
test / test (push) Has been cancelled

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
mixeme
2026-08-08 10:36:24 +03:00
parent 2f01edff19
commit c304c92955
24 changed files with 493 additions and 433 deletions
+14 -7
View File
@@ -40,7 +40,7 @@ const (
// startup). The window itself is configurable; the cadence need not be.
retentionInterval = 6 * time.Hour
// defaultRetentionDays applies when the configured value is unset/invalid
// (README § Environment variables: SEND_LOG_RETENTION_DAYS).
// (guide § Environment variables: SEND_LOG_RETENTION_DAYS).
defaultRetentionDays = 90
)
@@ -280,12 +280,19 @@ func isQueueIDByte(b byte) bool {
return b >= '0' && b <= '9' || b >= 'A' && b <= 'Z' || b >= 'a' && b <= 'z'
}
// Timestamps at the head of a mail.log line. The first is what Postfix's own
// postlogd writes, which is what this server runs (maillog_file in
// build/postfix-config.sh) — RFC 3339 down to microseconds and with an offset.
// The second is syslog's traditional format, for a deployment that routes the
// log through syslogd instead; it carries no year and no zone, which is why it
// is not the one being matched first.
// Timestamps at the head of a mail.log line, in the two formats postlogd
// writes (maillog_file in build/postfix-config.sh).
//
// syslogStampRe is the one that matches in practice today: the format is
// controlled by maillog_file_format, which arrived in Postfix 3.9, and the
// image is built on Debian's 3.7 — where the parameter does not exist and the
// only format is syslog's traditional one. It carries no year and no zone, so
// the stamp shown is a wall clock and nothing more, which is all this column
// claims to be.
//
// isoStampRe is for the RFC 3339 format that same parameter selects once the
// base image carries a Postfix new enough to offer it. Matching it first costs
// one failed anchor per line and means the upgrade needs no change here.
var (
isoStampRe = regexp.MustCompile(`^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?\s`)
syslogStampRe = regexp.MustCompile(`^([A-Z][a-z]{2}\s+\d{1,2} \d{2}:\d{2}:\d{2})\s`)
+11 -2
View File
@@ -465,7 +465,7 @@ func TestSplitTimestamp(t *testing.T) {
stamp, rest string
}{
{
name: "postlogd, which is what this server writes",
name: "RFC 3339, which maillog_file_format selects on Postfix 3.9 and up",
line: "2026-08-03T05:15:52.219218+00:00 mail postfix/smtp[26]: 4A1B2C3D: to=<a@example.net>, status=sent (250 OK)",
stamp: "2026-08-03 05:15:52",
rest: "mail postfix/smtp[26]: 4A1B2C3D: to=<a@example.net>, status=sent (250 OK)",
@@ -483,11 +483,20 @@ func TestSplitTimestamp(t *testing.T) {
rest: "mail opendkim[30]: 4A1B2C3D: DKIM-Signature field added",
},
{
name: "syslog's traditional format, padded day",
name: "syslog's traditional format, space-padded day",
line: "Aug 3 05:15:52 mail postfix/smtpd[20]: 4A1B2C3D: client=app.example.ru[203.0.113.4]",
stamp: "Aug 3 05:15:52",
rest: "mail postfix/smtpd[20]: 4A1B2C3D: client=app.example.ru[203.0.113.4]",
},
{
// Copied off the live relay (Postfix 3.7, which has no
// maillog_file_format), so this is the shape the panel actually
// meets: zero-padded day, and the host is the container's name.
name: "syslog's traditional format as the live relay writes it",
line: "Aug 08 07:26:41 selfpost postfix/master[231]: daemon started -- version 3.7.11, configuration /etc/postfix",
stamp: "Aug 08 07:26:41",
rest: "selfpost postfix/master[231]: daemon started -- version 3.7.11, configuration /etc/postfix",
},
{
name: "unrecognised head keeps the whole line",
line: "mail postfix/smtp[26]: 4A1B2C3D: to=<a@example.net>, status=sent (250 OK)",