#!/usr/bin/perl use strict; use warnings; use YAML; my (%conf, $state, $have_read, $totlines); %conf = (logfile => $ENV{LOGFILE} || '/home/user/.procmail/log', state => $ENV{STATEFILE} || "$ENV{MUNIN_PLUGSTATE}/munin-plugin-procmail.state"); $state = YAML::LoadFile($conf{state}); $have_read = 0; unless (-f $conf{logfile} and -r $conf{logfile}) { die "$conf{logfile} does not exist or is not readable!" ; } if (@ARGV and $ARGV[0] eq 'autoconf') { print "yes\n"; } elsif (@ARGV and $ARGV[0] eq 'config') { print config(); } else { print fetch(); # Update the offset, clear the numbers - Only when fetching! $state->{offset} += $have_read; $state->{folders}{$_} = 0 foreach keys %{$state->{folders}}; } YAML::DumpFile($conf{state}, $state); exit 0; sub config { # If config is ever called without having first a successful run, it should not die! $state->{folders} ||= {}; print "graph_title Destination folders for Postfix\n", "graph_vlabel Received mails\n", "graph_category mail\n", "graph_info Gives you the total mails stored by Postfix by folder\n"; print "$_.label $_\n" foreach sort keys %{$state->{folders}}; } sub fetch { my ($fh); if ($fh = open_log()) { $state->{folders} ||= {}; while (my $folder = next_used_folder($fh)) { $state->{folders}{$folder}++; } } print "$_.value $state->{folders}{$_}\n" foreach sort keys %{$state->{folders}}; } sub next_used_folder { my ($fh); $fh = shift; while (my $lin = <$fh>) { $have_read++; next unless $lin =~ m!^\s*Folder: ([^\s/]+)!; next unless $1; return $1; } return undef; } sub open_log { my ($fh, $offset, $lines_to_read); $offset = get_log_offset(); get_log_size(); $lines_to_read = $totlines - $offset; open($fh, "tail -$lines_to_read $conf{logfile}|") or die $!; return $fh; } sub get_log_size { my $tot = `wc -l $conf{logfile}`; $tot =~ /^(\d+) /; return $totlines = $1; } sub get_log_offset { my ($size); # The offset is expressed as the number of lines to skip. We get to that # point getting the total log size (get_log_size) and using tail for the # difference. If the offset is larger than the file itself, we get it # whole (it might have just been rotated). $size = get_log_size(); $state->{offset} ||= 0; $state->{offset} = 0 if $size < $state->{offset}; return $state->{offset}; } sub hush { return unless $ENV{FOLLOW}; warn @_; }