Read Procmail Delivery Totals Safely with mailstat
mailstat turns a Procmail delivery log into per-folder totals, counts and average sizes, but its default run quietly rewrites your logfile. The examples use the installed Procmail 3.24-1ubuntu2 package and its mailstat 3.24 script. Allow about ten minutes if you already have a Procmail logfile.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide assumes Procmail is writing a log in the format it generates, and that your account can read that file and write to its directory. Nothing below needs sudo. Do not give a mail-reporting command more access to another user's mailbox logs than it needs.
1. Check the Installed Command
The installed manual page identifies mailstat as part of Procmail 3.24, but most of the practical documentation lives in the command's own help output. Check the executable and package version first:
$ command -v mailstat
/usr/bin/mailstat
$ dpkg-query -W -f='${Package} ${Version}\n' procmail
procmail 3.24-1ubuntu2
$ mailstat -h
Usage: mailstat [-klmots] [logfile]
-k keep logfile intact
-l long display format
-m merge any errors into one line
-o use the old logfile
-t terse display format
-s silent in case of no mail
Checkpoint
If command -v turns up a copy in a personal bin directory, check that copy's own help before trusting the examples here. This is a shell script, and local copies get customised.
2. Locate the Procmail Logfile
Procmail's LOGFILE setting is the input mailstat reads. A typical configuration might contain a path such as /home/alice/mail/procmail.log. Check the actual path without changing it:
$ printf '%s\n' "$LOGFILE"
/home/alice/mail/procmail.log
$ test -r "$LOGFILE" && echo readable
readable
If the variable is not set in your current shell, use the literal path from the Procmail configuration instead:
$ LOG='/home/alice/mail/procmail.log'
$ test -r "$LOG" && echo readable
readable
Swap in your own path. Quoting it keeps spaces or shell metacharacters in the path from being interpreted by the shell.
3. Run the Normal Report, but Mind the Rotation
Run the command with the logfile as its final argument:
$ mailstat "$LOG"
Total Number Folder
----- ------ ------
6912 2 /home/alice/mail/inbox
1234 1 /var/mail/alice
----- ------
8146 3
The first numeric column is the total size recorded for deliveries to that folder, the second is the message count, and the final lines are grand totals. An error or diagnostic line shows up as a folder beginning ## and contributes zero to the size, but this installed script still counts it toward the overall message total.
Here is the catch: unless you pass -k, mailstat moves the input to a sibling file ending in .old, then creates a fresh, empty logfile with restrictive permissions so Procmail can keep logging. That means the very first report consumes the current log. Do not treat the plain form as a casual, read-only look.
4. Keep the Current Logfile for Inspection
Use -k when you want a report without moving or truncating the logfile:
$ mailstat -k "$LOG"
Total Number Folder
----- ------ ------
6912 2 /home/alice/mail/inbox
1234 1 /var/mail/alice
----- ------
8146 3
$ test -s "$LOG" && echo logfile still contains data
logfile still contains data
This is the safest default for a first look. It will not undo a previous run that already moved data to .old; use -o for that.
5. Report on the Previous Snapshot
After a normal run, the previous contents sit in LOGFILE.old. The -o option selects that file and leaves it intact:
$ mailstat -o "$LOG"
Total Number Folder
----- ------ ------
6912 2 /home/alice/mail/inbox
1234 1 /var/mail/alice
----- ------
8146 3
$ ls -l "$LOG" "$LOG.old"
Do not confuse -o with a way to preserve the current logfile: it reads the old snapshot, full stop. Pass a filename that already ends in .old and the script treats that as the old logfile without appending another suffix.
6. Choose a Format for Scripts or for People
-l adds an average-size column to each folder row, calculated with integer division, so fractions get dropped:
$ mailstat -kl "$LOG"
Total Average Number Folder
----- ------- ------ ------
6912 3456 2 /home/alice/mail/inbox
1234 1234 1 /var/mail/alice
----- ------- ------
8146 2715 3
-t strips the headings and per-folder rows, leaving only totals. It is a terse report for a human, not a stable machine-readable API, so treat the output as presentation text rather than a CSV format. Options combine freely, so -kl keeps the logfile and adds the long output.
-m merges diagnostic lines into a single category. Without it, each distinct error gets its own ## row, which is useful right up until several delivery errors start drowning out the folder totals.
7. Handle Empty Logs and Exit Statuses
A successful report returns status 0 when mail records were found. An empty or missing logfile returns status 1, handy for a monitoring check:
$ mailstat -s "$LOG"
$ printf 'mailstat status: %s\n' "$?"
mailstat status: 1
-s just suppresses the normal message, something like No mail arrived since ... or Can't find your LOGFILE=.... It does not turn an empty logfile into a success. An invalid option prints the usage text and exits 64, the standard command-line usage error:
$ mailstat -z "$LOG"
Usage: mailstat [-klmots] [logfile]
$ printf 'mailstat status: %s\n' "$?"
mailstat status: 64
In a script, distinguish 0, 1 and 64 rather than treating every non-zero status as an operational failure. A missing log can mean a wrong path, changed permissions, or simply no delivery yet.
Done means
- Confirmed the version. The installed
mailstatand Procmail version match what this guide expects. - Found the real logfile. You identified the path Procmail actually writes.
- Kept it safe. You used
-kfor read-only inspection, or deliberately checked the generated.oldsnapshot. - Read the numbers right. Totals, averages, diagnostic rows and exit status all made sense.
- Stayed unprivileged. No elevated privileges, and no logfile overwritten without understanding the rotation.