Read Procmail Delivery Totals Safely with mailstat
You will use mailstat to turn a Procmail delivery log into per-folder totals, message counts and average sizes, while keeping the original log available when you need it. 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 that Procmail is writing a log in the format it generates, and that your account can read that file and write its directory. No command below needs sudo. Do not give a mail-reporting command unnecessary access to another user's mailbox logs.
1. Check the installed command
The installed manual page identifies mailstat as part of Procmail 3.24, but most of the practical documentation is in the command's 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 finds a copy in a personal bin directory, inspect that copy's help before relying on the examples. This program is a shell script, and local copies can be customised.
2. Locate the Procmail logfile
Procmail's LOGFILE setting is the input to mailstat. 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 available in your current shell, use the literal path from the Procmail configuration:
$ LOG='/home/alice/mail/procmail.log'
$ test -r "$LOG" && echo readable
readable
Replace that example path with your own. Quoting it prevents spaces or shell metacharacters in a path from being interpreted by the shell.
3. Run the normal report, with the rotation warning in mind
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 number of messages. The final lines are grand totals. An error or diagnostic line is shown with a folder beginning ## and contributes zero to the size, but it still contributes to the overall message count in this installed script.
There is a state change here. Unless you pass -k, mailstat moves the input to a sibling file ending in .old, then creates an empty logfile with restrictive permissions. This lets Procmail continue logging, but it also means the first report consumes the current log. Do not use the normal form as a casual read-only inspection.
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 an initial investigation. It does not undo a previous run that already moved data to .old; use -o to report on that old file instead.
5. Report on the previous snapshot
After a normal run, the previous contents are in LOGFILE.old. The -o option selects that file and keeps 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 request to preserve the current logfile. It reads the old snapshot. If you pass a filename that already ends in .old, the script treats that as the old logfile and does not append another suffix.
6. Choose a format for scripts or people
-l adds an average-size column to each folder row. The average is calculated with integer division, so fractions are discarded:
$ mailstat -kl "$LOG"
Total Average Number Folder
----- ------- ------ ------
6912 3456 2 /home/alice/mail/inbox
1234 1234 1 /var/mail/alice
----- ------- ------
8146 2715 3
-t suppresses the headings and per-folder rows, leaving only totals. It is intended for a terse report, not a stable machine-readable API; treat the output as presentation text rather than a CSV format. The options may be combined, so -kl means keep the logfile and use long output.
-m merges diagnostic lines into one diagnostic category. Without it, distinct errors are displayed as separate ## rows. Use it when several delivery errors would distract from 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, which is useful for a monitoring check:
$ mailstat -s "$LOG"
$ printf 'mailstat status: %s\n' "$?"
mailstat status: 1
The -s flag suppresses the normal message such as No mail arrived since ... or Can't find your LOGFILE=.... It does not turn an empty logfile into success. An invalid option produces the usage text and exit status 64, the standard command-line usage error:
$ mailstat -z "$LOG"
Usage: mailstat [-klmots] [logfile]
$ printf 'mailstat status: %s\n' "$?"
mailstat status: 64
For a script, distinguish 0, 1 and 64 instead of treating every non-zero status as an operational failure. A missing log can mean that the path is wrong, permissions changed, or no delivery has happened yet.
Done means
- You confirmed the installed
mailstatand Procmail version. - You identified the logfile Procmail actually writes.
- You used
-kfor read-only inspection, or deliberately retained and checked the generated.oldsnapshot. - You interpreted totals, averages, diagnostic rows and exit status correctly.
- You did not use elevated privileges or overwrite a logfile without understanding the rotation.