What's the postfix equivalent to sendmail -bp?
11 Answers
qshape active
will show you the number of emails being sent to each domain and how long they have been in the active queue
qshape deferred
will show you the same but for the deferred queue
Here's what I use, culled from the postfix mailing list. I removed the author's name, in case he doesn't want it here (you can see it at the source). It only displays totals.
#!/usr/bin/env perl
# postfix queue/s size
# author:
# source: http://tech.groups.yahoo.com/group/postfix-users/message/255133
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,}$}) {
++$c;
} elsif ($f =~ m{^[A-F0-9]$}) {
$c += count("$dir/$f");
}
}
closedir($dh) or die "closedir: $dir: $!\n";
return $c;
}
my $qdir = `postconf -h queue_directory`;
chomp($qdir);
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");
printf "Bounced: %d\n", count("bounce");
printf "Hold: %d\n", count("hold");
printf "Corrupt: %d\n", count("corrupt");
EDIT: Fixed a typo on line 26.
- 1,215
postqueue -p | tail -n 1
Last line in the postqueue -p shows how many requests and size:
-- 317788 Kbytes in 11860 Requests.
If you don't have qshape you can install it via the following yum commands:
yum groupinstall perl development
yum install postfix-perl-scripts
qshape prints Postfix queue domain and age distribution information. You can read more about it here:
http://www.postfix.org/QSHAPE_README.html
Example output
% qshape -s hold | head
T 5 10 20 40 80 160 320 640 1280 1280+
TOTAL 486 0 0 1 0 0 2 4 20 40 419
yahoo.com 14 0 0 1 0 0 0 0 1 0 12
extremepricecuts.net 13 0 0 0 0 0 0 0 2 0 11
ms35.hinet.net 12 0 0 0 0 0 0 0 0 1 11
winnersdaily.net 12 0 0 0 0 0 0 0 2 0 10
hotmail.com 11 0 0 0 0 0 0 0 0 1 10
worldnet.fr 6 0 0 0 0 0 0 0 0 0 6
ms41.hinet.net 6 0 0 0 0 0 0 0 0 0 6
osn.de 5 0 0 0 0 0 1 0 0 0 4
- 8,010
- 609
[root@server ~]# time mailq | grep -c '^[0-9A-Z]'
10
real 0m1.333s
user 0m0.003s
sys 0m0.003s
(above result indicating that there are 10 email is queue)
I have jq on my system.
I like the following approach a lot:
postqueue -j | jq -s 'group_by(.queue_name) | map({"queue": .[0].queue_name, "count": length})'
[
{
"queue": "active",
"count": 2
},
{
"queue": "deferred",
"count": 314
},
{
"queue": "hold",
"count": 2630
}
]
- 31
- 1
Here is an example.
#!/bin/bash
for q in active bounce corrupt defer deferred flush hold incoming maildrop pid private public saved trace
do
count=$(find /var/spool/postfix/$q ! -type d -print | wc -l)
echo $q $count
done
- 105
- 31
Elaborating on @mikewater's answer here, since it didn't fit in a comment: this should handle old and new postfix and also shows the total.
#!/usr/bin/env perl
pfq - quickly print postfix queue sizes.
Unlike mailq/postqueue returns immediate answer for a queue under duress.
http://tech.groups.yahoo.com/group/postfix-users/message/255133,
https://serverfault.com/a/329884/52485,
SM
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]|[0-9B-Zb-z]){5,}$}) {
++$c;
} elsif ($f =~ m{^[A-F0-9]$}) {
$c += count("$dir/$f");
}
}
closedir($dh) or die "closedir: $dir: $!\n";
return $c;
}
my $qdir = postconf -h queue_directory;
chomp($qdir);
chdir($qdir) or die "$0: chdir: $qdir: $!\n";
my $incoming = count("incoming");
my $active = count("active");
my $deferred = count("deferred");
my $bounce = count("bounce");
my $hold = count("hold");
my $corrupt = count("corrupt");
printf "Incoming: %7d\n", $incoming;
printf "Active: %7d\n", $active;
printf "Deferred: %7d\n", $deferred;
printf "Bounced: %7d\n", $bounce;
printf "Hold: %7d\n", $hold;
printf "Corrupt: %7d\n", $corrupt;
printf "-----------------\n";
printf "Total: %7d\n", $incoming + $active + $deferred + $bounce + $hold + $corrupt;
And a wrapper to make testing easy:
#!/bin/bash
# pfqcheck [N] - Check for no more than N queued postfix messages, default 50.
MAX="${1:-50}"
NUM=$(pfq | tail -1 | awk '{print $2;}')
MSG="$NUM queued emails, limit is $MAX"
if [[ $(expr "$NUM" '<=' "$MAX") == 1 ]]
then echo "ok: $MSG"; exit 0;
else echo "fail: $MSG"; exit 1;
fi
- 121
Similar to @JayZee I like jq, but instead of a group_by I'd use reduce - should be more efficient that way.
postqueue -j | jq -s 'reduce .[].queue_name as $q ({}; . + { ($q): (1 + .[$q]) })'
{
"active": 3,
"deferred": 14
}
Append | to_entries | map({queue: .key, count: .value}) to the jq-filter to get the same output as @JayZee.
- 879