So what's the best way to quickly (i.e. less than a few seconds) get the
current queue count out of Postfix?

Fastest: have a dedicated file system and count the number
of used versus free inodes (df -i). This produces an
instantaneous result regardless of the queue size (*).

Slower: a suitable perl script that exploits the fact that
directories have one-character names. I'll leave that up
to Victor.

Slower: a suitable incantation of the find command.

Slowest: mailq/postqueue -p, because that opens each file.

(*) Except on systems where df(1) secretly invokes sync(2);
   SunOS was such an example.

Slower (perl)

This avoids all lstat(2) operations, reducing the system-call overhead
of counting queued messages to a minimum. The incoming queue number may
be a bit "inflated" because messages that are not yet fully received
are also counted). This overcount of the incoming queue is not generally
a problem.

perl -e '
       use strict;
       use warnings;
       use Symbol;
       sub count {
           my ($dir) = @_;
           my $dh = gensym();
           my $c = 0;
           opendir($dh, $dir) or die "$0: opendir: $dir: $!\n";
           while (my $f = readdir($dh)) {
               if ($f =~ m{^[A-F0-9]{5,}$}) {
               } elsif ($f =~ m{^[A-F0-9]$}) {
                   $c += count("$dir/$f");
           closedir($dh) or die "closedir: $dir: $!\n";
           return $c;
       my $qdir = shift(@ARGV) or die "Usage: $0 queue-directory\n";
       chdir($qdir) or die "$0: chdir: $qdir: $!\n";
       printf "Incoming: %d\n", count("incoming");
       printf "Active: %d\n", count("active");
       printf "Deferred: %d\n", count("deferred");
   ' /var/spool/postfix

Slower (find)

   1 #!/bin/sh
   2 qdir=`postconf -h queue_directory`
   3 incoming=`find $qdir/incoming -type f -print | wc -l | awk '{print $1}'`
   4 activeonly=`find $qdir/active -type f -print | wc -l | awk '{print $1}'`
   5 maildrop=`find $qdir/maildrop -type f -print | wc -l | awk '{print $1}'`
   6 active=`find $qdir/incoming $qdir/active $qdir/maildrop -type f -print | wc -l | awk '{print $1}'`
   7 deferred=`find $qdir/deferred -type f -print | wc -l | awk '{print $1}'`
   8 printf "active: %d\ndeferred: %d\nincoming: %d\nactiveonly: %d\nmaildrop: %d\n" $active $deferred $incoming $activeonly $maildrop

MeidokonWiki: Postfix/Getting_queue_size (last edited 2010-05-06 10:16:03 by furinkan)