Documentation
¶
Overview ¶
Package pflog parses Postfix mail log entries.
It supports the standard BSD syslog format used by Postfix:
Jan 1 00:00:00 hostname postfix/process[pid]: message
Use Parse to parse individual log lines, or Scanner to iterate over records from an io.Reader.
Each parsed entry is returned as a Record whose [Record.Message] field contains one of the concrete message types: Connect, Disconnect, Queued, Removed, Cleanup, Delivery, Reject, BounceNotification, Warning, or Unknown.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BounceNotification ¶
type BounceNotification struct {
// BounceQueueID is the queue ID of the bounce notification message.
BounceQueueID string
}
BounceNotification is produced by the bounce daemon when a non-delivery report is generated.
type Cleanup ¶
type Cleanup struct {
// MessageID is the value of the Message-Id header (without angle brackets).
MessageID string
}
Cleanup is produced by the cleanup daemon and carries the Message-Id header.
type Connect ¶
type Connect struct {
// Hostname is the connecting client's reported hostname (may be "unknown").
Hostname string
// IP is the connecting client's IP address.
IP string
}
Connect is produced by smtpd when a client connects.
type Delivery ¶
type Delivery struct {
// To is the recipient envelope address.
To string
// Relay is the relay host used for delivery (e.g., "mail.example.com[1.2.3.4]:25",
// "local", or "none").
Relay string
// Delay is the total message delay as reported by Postfix.
Delay string
// Delays is the per-stage delay breakdown (queuing/connection/setup/data).
Delays string
// DSN is the delivery status notification code (e.g., "2.0.0").
DSN string
// Status is the delivery outcome.
Status DeliveryStatus
// Detail is the SMTP response or error detail.
Detail string
}
Delivery is produced by smtp, local, virtual, lmtp, or pipe for each recipient delivery attempt.
type DeliveryStatus ¶
type DeliveryStatus string
DeliveryStatus is the final disposition of a delivery attempt.
const ( // StatusSent indicates the message was successfully delivered. StatusSent DeliveryStatus = "sent" // StatusBounced indicates the message was returned to the sender. StatusBounced DeliveryStatus = "bounced" // StatusDeferred indicates delivery was temporarily deferred. StatusDeferred DeliveryStatus = "deferred" // StatusExpired indicates the message exceeded the maximum queue lifetime. StatusExpired DeliveryStatus = "expired" )
type Disconnect ¶
type Disconnect struct {
// Hostname is the client's reported hostname (may be "unknown").
Hostname string
// IP is the client's IP address.
IP string
// Stats contains per-command counts reported at disconnect
// (e.g., {"ehlo": 1, "mail": 1, "rcpt": 1, "commands": 3}).
Stats map[string]int
}
Disconnect is produced by smtpd when a client disconnects.
type FormatError ¶
type FormatError struct {
// Line is the full input line that failed to parse.
Line string
// Reason is a short description of what part of the format was not
// recognised (e.g., "line too short", "missing hostname",
// "missing PID bracket", "missing message separator").
Reason string
}
FormatError is returned by Parse when the input line does not conform to the expected BSD syslog format.
func (*FormatError) Error ¶
func (e *FormatError) Error() string
type Message ¶
type Message interface {
// contains filtered or unexported methods
}
Message is the interface implemented by all specific log message types. Use a type switch to distinguish between concrete types.
type PIDError ¶
type PIDError struct {
// PID is the raw PID string that failed to parse.
PID string
// Err is the underlying parse error.
Err error
}
PIDError is returned by Parse when the PID field cannot be parsed as an integer. The underlying parse error is accessible via errors.Unwrap.
type Queued ¶
type Queued struct {
// From is the envelope sender address (empty for bounce messages).
From string
// Size is the message size in bytes.
Size int
// NRcpt is the number of recipients.
NRcpt int
}
Queued is produced by qmgr when a message enters the active queue.
type Record ¶
type Record struct {
// Time is the log entry timestamp. Because the BSD syslog format omits the
// year, it is set to the current UTC year at parse time. Logs that span a
// year boundary (e.g., December entries parsed in January) will receive an
// incorrect year.
Time time.Time
// Hostname is the name of the host that produced the log entry.
Hostname string
// Process is the Postfix daemon that produced the entry (e.g., "smtpd",
// "smtp", "qmgr").
Process string
// PID is the process identifier.
PID int
// QueueID is the Postfix message queue ID, if present.
QueueID string
// Message is the parsed message payload. Use a type switch or type
// assertion to access the concrete type.
Message Message
}
Record is a parsed Postfix log entry.
func Parse ¶
Parse parses a single Postfix log line and returns a Record.
The line must be in the standard BSD syslog format:
Jan 1 00:00:00 hostname postfix/process[pid]: message
An error is returned when the line does not match the expected syslog header. If the message body cannot be parsed into a specific type, the [Record.Message] field is set to Unknown and no error is returned.
type Reject ¶
type Reject struct {
// Stage is the SMTP stage where rejection occurred (e.g., "RCPT", "DATA").
Stage string
// ClientHostname is the rejecting client's hostname (may be "unknown").
ClientHostname string
// ClientIP is the rejecting client's IP address.
ClientIP string
// Code is the SMTP rejection code (e.g., 550).
Code int
// Detail is the full rejection reason.
Detail string
}
Reject is produced when a message or connection is rejected.
type Removed ¶
type Removed struct{}
Removed is produced by qmgr when a message is removed from the queue.
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner reads Postfix log [Record]s from an io.Reader one line at a time. Lines that do not match the expected syslog format are silently skipped, making it safe to use on mixed syslog files.
To be notified when a line is skipped due to a parse error, register a callback with Scanner.SetErrorHandler before calling Scanner.Scan.
Usage:
s := pflog.NewScanner(r)
for s.Scan() {
rec := s.Record()
// process rec…
}
if err := s.Err(); err != nil {
log.Fatal(err)
}
func NewScanner ¶
NewScanner returns a new Scanner that reads from r.
func (*Scanner) Record ¶
Record returns the most recent record parsed by Scanner.Scan. The returned pointer is valid until the next call to Scanner.Scan.
func (*Scanner) Scan ¶
Scan advances the scanner to the next record and returns true if one is available. It returns false at the end of input or on a read error. Lines that cannot be parsed as Postfix entries are silently skipped; register an error handler with Scanner.SetErrorHandler to observe those errors.
func (*Scanner) SetErrorHandler ¶
SetErrorHandler registers fn to be called whenever a line is skipped because it cannot be parsed as a Postfix log entry. fn receives the raw line and the parse error. Passing nil clears a previously set handler. SetErrorHandler must be called before the first call to Scanner.Scan.
type TimestampError ¶
type TimestampError struct {
// Timestamp is the raw timestamp string that failed to parse.
Timestamp string
// Err is the underlying parse error.
Err error
}
TimestampError is returned by Parse when the timestamp portion of the input line cannot be parsed. The underlying parse error is accessible via errors.Unwrap.
func (*TimestampError) Error ¶
func (e *TimestampError) Error() string
func (*TimestampError) Unwrap ¶
func (e *TimestampError) Unwrap() error
Unwrap returns the underlying timestamp parse error.