Send Postfix Logs to a File with postlogd
By default Postfix's internal log records go to syslog, which is fine until you need them isolated in their own file: that is what postlogd is for. This walks through pointing Postfix at a chosen logfile, confirming records actually land there, and reverting cleanly if the result is not what you wanted. Examples use Postfix 3.8.6 from the installed postfix package.
The route
Jump straight to the step you need, or tick off Done means at the end.
Budget fifteen minutes. You need a shell, access to the Postfix configuration, and a directory with enough free space for the log. Reading configuration is an ordinary command; changing main.cf, reloading Postfix and reading a root-owned log usually need elevated privileges. Nothing here rotates, deletes or truncates an existing log.
1. Check the installed version and service
Start with read-only checks, so you know exactly which installation you are about to change:
$ dpkg-query -W -f='${Package} ${Version}\n' postfix
postfix 3.8.6-1ubuntu0.1
$ postconf -h config_directory
/etc/postfix
$ postconf -M postlog
postlog unix-dgram n - n - 1 postlogd
That last line is the master.cf service entry: it tells Postfix to run the postlog Unix datagram service through the postlogd server. You do not start postlogd by hand; the installed binary lives at /usr/lib/postfix/sbin/postlogd, off the ordinary command path on purpose.
Checkpoint
If postconf -M postlog shows nothing, stop and inspect the local master.cf instead. Do not invent a service definition by copying one from a different Postfix release.
2. Inspect the current logging setting
Ask postconf for the effective value of maillog_file:
$ postconf -h maillog_file
An empty line means this setting is not selecting a Postfix logfile, not that every Postfix diagnostic has vanished: programs can still use the system logging service, and early messages can reach syslog before configuration is even processed. The postlogd service only becomes relevant once maillog_file is non-empty.
Pick a path reserved for Postfix logging. The example below uses /var/log/postfix/postfix.log; swap in whatever path your host's logging policy requires. Check whether it already exists before changing anything:
$ sudo ls -l /var/log/postfix/postfix.log
ls: cannot access '/var/log/postfix/postfix.log': No such file or directory
That error is safe and expected for a brand-new destination. If a file already exists there, do not assume it is disposable: check its owner, contents and rotation policy before pointing Postfix at it.
3. Set a new logfile
Make the change with elevated privileges:
$ sudo postconf -e 'maillog_file = /var/log/postfix/postfix.log'
postconf -e updates the configuration for you, instead of you hand-editing spacing or parameter order. It does not, on its own, generate a log record. Check the stored value straight away:
$ postconf -h maillog_file
/var/log/postfix/postfix.log
Checkpoint
If that value is not exactly the path you meant, fix it before reloading. Nothing in this guide's shell redirection touches an existing logfile, so none has been truncated at this point.
4. Reload Postfix to pick up the change
Reload as root:
$ sudo postfix reload
postfix/postfix-script: refreshing the Postfix mail system
The manual notes that configuration changes get picked up automatically anyway, because postlogd processes are short-lived, but postfix reload speeds that up. Treat the reload as the explicit checkpoint: it tells the running installation to reread its configuration. It is not a substitute for testing the service after a broader change.
A successful reload is not proof the file is receiving anything. Check the service and the destination directly:
$ postconf -M postlog
postlog unix-dgram n - n - 1 postlogd
$ sudo ls -l /var/log/postfix/postfix.log
-rw------- 1 postfix postfix 0 Sep 26 12:00 /var/log/postfix/postfix.log
Size and timestamp are host-specific. A zero-byte file right after reload is not a failure: it may just mean nothing has happened yet that Postfix wanted to record.
5. Generate and verify one safe record
Use a normal administrative query to exercise the install without sending mail:
$ postconf myhostname
myhost.example.invalid
$ sudo tail -n 20 /var/log/postfix/postfix.log
The first command only reads configuration and may not produce a log entry by itself. For a stronger check, do the routine Postfix operation you actually care about, such as an ordinary postfix status or a controlled queue operation, then look again:
$ sudo tail -n 20 /var/log/postfix/postfix.log
Sep 26 12:01:14 myhost postfix/postfix-script[1234]: the Postfix mail system is running
Timestamps, process IDs, hostname and wording will all vary. What matters is a new record in the configured file. No record at all means checking postfix status, the system journal or syslog, the file's ownership, and free space on its filesystem. Do not make the file world-writable just to get past a permission error.
6. Undo the change without deleting the log
Turning this destination off is reversible; it does not remove the file or its history. Set the parameter back to empty and reload:
$ sudo postconf -e 'maillog_file ='
$ sudo postfix reload
$ postconf -h maillog_file
Keep the old logfile until you have checked your retention requirements. Running sudo rm on it would be an irreversible data change, not part of undoing the setting itself. If those records need to live elsewhere, copy or rotate the file through your normal logging process before removing anything.
Common traps
- Do not run the postlogd binary directly. It is an internal server; Postfix invokes it through the
postlogservice inmaster.cf. - An empty maillog_file only disables this one destination. It does not guarantee every diagnostic uses the same route, especially before a program has processed its own configuration.
- Only a handful of programs write straight to $maillog_file when Postfix is down. The manual names
postfix,postsuper,postmultiandpostlog; everything else depends on the internal service and privilege rules. - Do not add set-gid permission to arbitrary Postfix programs. The manual limits that exception to
postdrop,postqueue, and, from Postfix 3.7,postlog.
Done means
- Version and service checked. Installed Postfix version and the
postlogservice entry both confirmed. - Destination set.
maillog_filenames the intended path, and that path was checked before use. - Reload verified. Postfix reloaded with elevated privileges and a new record confirmed, or its absence explained.
- File left intact. Not made world-writable, truncated or deleted.
- Rollback ready. The previous empty setting restores with
postconf -e 'maillog_file ='followed bypostfix reload.