]>
jfr.im git - munin-plugins.git/blob - postfix_mailvolume
09373d434b26fd7cb9773233e71286b54a01adf3
6 postfix_mailvolume - Plugin to monitor the volume of mails delivered
9 =head1 APPLICABLE SYSTEMS
15 The following shows the default configuration.
23 The plugin shows the number of bytes of mail that has passed through
24 the postfix installation.
29 #%# capabilities=autoconf
38 * calculate extra field for mail volume that is actually delivered ("volume_delivered")
42 Copyright (C) 2002-2008.
44 No author is documented.
57 # the volume that was actually delivered
58 my $volume_delivered = 0;
59 my %volumes_per_queue_id = ();
60 my $serialized_volumes_queue;
61 my %expired_queue_ids = ();
62 # Discard old queue IDs after a while (otherwise the state storage grows infinitely). We need to
63 # store the IDs long enough for the gap between two delivery attempts. Thus multiple hours are
65 use constant queue_id_expiry
=> 6 * 3600;
67 my $LOGDIR = $ENV{'logdir'} || '/var/log';
68 my $LOGFILE = $ENV{'logfile'} || 'syslog';
72 my ($fname, $start) = @_;
74 my ($LOGFILE, $rotated) = tail_open
($fname, $start || 0);
76 while (my $line = <$LOGFILE>) {
79 if ($line =~ /qmgr.*: ([0-9A-Za-z]+): from=.*, size=([0-9]+)/) {
80 # The line with queue ID and size may pass along multiple times (every time the mail
81 # is moved into the active queue for another delivery attempt). The size should always
83 if (not exists($volumes_per_queue_id{$1})) {
84 $volumes_per_queue_id{$1} = {timestamp
=> time};
86 # probably it is the same value as before
87 $volumes_per_queue_id{$1}->{size
} = $2;
88 } elsif ($line =~ / ([0-9A-Za-z]+): to=.*, status=sent /) {
89 # The "sent" line is repeated for every successful delivery for each recipient.
90 if (exists($volumes_per_queue_id{$1})) {
91 $volume_delivered += $volumes_per_queue_id{$1}->{size
};
92 $volumes_per_queue_id{$1}->{timestamp
} = time;
96 # remove all expired queue IDs
97 my @expired_queue_ids;
98 for my $key (keys %volumes_per_queue_id) {
99 if (time > $volumes_per_queue_id{$key}->{timestamp
} + queue_id_expiry
) {
100 push @expired_queue_ids, $key;
103 delete(@volumes_per_queue_id{@expired_queue_ids});
104 return tail_close
($LOGFILE);
107 if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) {
109 `which postconf >/dev/null 2>/dev/null`;
111 $logfile = "$LOGDIR/$LOGFILE";
118 print "no (logfile '$logfile' not readable)\n";
121 print "no (logfile '$logfile' not found)\n";
124 print "no (postfix not found)\n";
131 if ( $ARGV[0] and $ARGV[0] eq "config" ) {
132 print "graph_title Postfix bytes throughput\n";
133 print "graph_args --base 1000 -l 0\n";
134 print "graph_vlabel bytes / \${graph_period}\n";
135 print "graph_scale yes\n";
136 print "graph_category postfix\n";
137 print "volume.label delivered volume\n";
138 print "volume.type DERIVE\n";
139 print "volume.min 0\n";
144 my $logfile = "$LOGDIR/$LOGFILE";
147 print "volume.value U\n";
151 # load the stored data
152 ($pos, $volume_delivered, $serialized_volumes_queue) = restore_state
();
155 if (!defined($volume_delivered)) {
157 # No state file present. Avoid startup spike: Do not read log
158 # file up to now, but remember how large it is now, and next
159 # time read from there.
161 $pos = (stat $logfile)[7]; # File size
163 $volume_delivered = 0;
164 %volumes_per_queue_id = ();
166 # decode the serialized hash
167 # source format: "$id1=$size1:$timestamp1 $id2=$size2:$timestamp2 ..."
168 # The "serialized" value may be undefined, in case we just upgraded from the version before
169 # 2018, since that old version stored only two fields in the state file. Tolerate this.
170 for my $queue_item_descriptor (split(/ /, $serialized_volumes_queue || "")) {
171 (my $queue_item_id, my $queue_item_content) = split(/=/, $queue_item_descriptor);
172 (my $size, my $timestamp) = split(/:/, $queue_item_content);
173 $volumes_per_queue_id{$queue_item_id} = { size
=> int($size), timestamp
=> int($timestamp) };
175 $pos = parseLogfile
($logfile, $pos);
178 print "volume.value $volume_delivered\n";
180 # serialize the hash to a string (see "source format" above)
181 $serialized_volumes_queue = join(" ", map { sprintf("%s=%s", $_, sprintf("%d:%d", $volumes_per_queue_id{$_}->{size
}, $volumes_per_queue_id{$_}->{timestamp
})) } keys %volumes_per_queue_id);
182 save_state
($pos, $volume_delivered, $serialized_volumes_queue);