]> jfr.im git - munin-plugins.git/commitdiff
make work with journald
authorJohn Runyon <redacted>
Thu, 28 Sep 2023 21:53:37 +0000 (16:53 -0500)
committerJohn Runyon <redacted>
Thu, 28 Sep 2023 21:53:37 +0000 (16:53 -0500)
postfix_mailvolume

index 09373d434b26fd7cb9773233e71286b54a01adf3..d2f88ea6840f1437b80673ba67844e3f404cee83 100755 (executable)
@@ -15,8 +15,8 @@ Any postfix.
 The following shows the default configuration.
 
   [postfix*]
-    env.logdir /var/log
-    env.logfile syslog
+       env.logdir /var/log
+       env.logfile syslog
 
 =head1 INTERPRETATION
 
@@ -64,115 +64,102 @@ my %expired_queue_ids = ();
 # recommended.
 use constant queue_id_expiry => 6 * 3600;
 
-my $LOGDIR  = $ENV{'logdir'}  || '/var/log';
-my $LOGFILE = $ENV{'logfile'} || 'syslog';
-
-
 sub parseLogfile {
-    my ($fname, $start) = @_;
-
-    my ($LOGFILE, $rotated) = tail_open($fname, $start || 0);
-
-    while (my $line = <$LOGFILE>) {
-        chomp ($line);
-
-        if ($line =~ /qmgr.*: ([0-9A-Za-z]+): from=.*, size=([0-9]+)/) {
-            # The line with queue ID and size may pass along multiple times (every time the mail
-            # is moved into the active queue for another delivery attempt). The size should always
-            # be the same.
-            if (not exists($volumes_per_queue_id{$1})) {
-                $volumes_per_queue_id{$1} = {timestamp => time};
-            }
-            # probably it is the same value as before
-            $volumes_per_queue_id{$1}->{size} = $2;
-        } elsif ($line =~ / ([0-9A-Za-z]+): to=.*, status=sent /) {
-            # The "sent" line is repeated for every successful delivery for each recipient.
-            if (exists($volumes_per_queue_id{$1})) {
-                $volume_delivered += $volumes_per_queue_id{$1}->{size};
-                $volumes_per_queue_id{$1}->{timestamp} = time;
-            }
-        }
-    }
-    # remove all expired queue IDs
-    my @expired_queue_ids;
-    for my $key (keys %volumes_per_queue_id) {
-        if (time > $volumes_per_queue_id{$key}->{timestamp} + queue_id_expiry) {
-            push @expired_queue_ids, $key;
-        }
-    }
-    delete(@volumes_per_queue_id{@expired_queue_ids});
-    return tail_close($LOGFILE);
+       my ($start) = @_;
+
+       open(my $LOGFILE, '-|', "journalctl --facility=mail --after-cursor='$start' --show-cursor");
+
+       while (my $line = <$LOGFILE>) {
+               chomp $line;
+
+               if ($line =~ /qmgr.*: ([0-9A-Za-z]+): from=.*, size=([0-9]+)/) {
+                       # The line with queue ID and size may pass along multiple times (every time the mail
+                       # is moved into the active queue for another delivery attempt). The size should always
+                       # be the same.
+                       if (not exists($volumes_per_queue_id{$1})) {
+                               $volumes_per_queue_id{$1} = {timestamp => time};
+                       }
+                       # probably it is the same value as before
+                       $volumes_per_queue_id{$1}->{size} = $2;
+               } elsif ($line =~ / ([0-9A-Za-z]+): to=.*, status=sent /) {
+                       # The "sent" line is repeated for every successful delivery for each recipient.
+                       if (exists($volumes_per_queue_id{$1})) {
+                               $volume_delivered += $volumes_per_queue_id{$1}->{size};
+                               $volumes_per_queue_id{$1}->{timestamp} = time;
+                       }
+               } elsif ($line =~ /^-- cursor: (.+)$/) {
+                       $start = $1;
+               }
+       }
+       close($LOGFILE);
+       # remove all expired queue IDs
+       my @expired_queue_ids;
+       for my $key (keys %volumes_per_queue_id) {
+               if (time > $volumes_per_queue_id{$key}->{timestamp} + queue_id_expiry) {
+                       push @expired_queue_ids, $key;
+               }
+       }
+       delete(@volumes_per_queue_id{@expired_queue_ids});
+       return $start;
 }
 
 if ( $ARGV[0] and $ARGV[0] eq "autoconf" ) {
-    my $logfile;
-    `which postconf >/dev/null 2>/dev/null`;
-    if (!$?) {
-        $logfile = "$LOGDIR/$LOGFILE";
-
-        if (-f $logfile) {
-            if (-r "$logfile") {
-                print "yes\n";
-                exit 0;
-            } else {
-                print "no (logfile '$logfile' not readable)\n";
-            }
-        } else {
-            print "no (logfile '$logfile' not found)\n";
-        }
-    } else {
-        print "no (postfix not found)\n";
-    }
-
-    exit 0;
+       my $logfile;
+       `which postconf >/dev/null 2>/dev/null`;
+       if (!$?) { # if postconf returns success
+               `journalctl --facility=mail --show-cursor -n 0`;
+               if (!$?) { # if journalctl returns success
+                       print "yes\n";
+               } else {
+                       print "no (journalctl returned error)\n";
+               }
+       } else {
+               print "no (postfix not found)\n";
+       }
+
+       exit 0;
 }
 
 
 if ( $ARGV[0] and $ARGV[0] eq "config" ) {
-    print "graph_title Postfix bytes throughput\n";
-    print "graph_args --base 1000 -l 0\n";
-    print "graph_vlabel bytes / \${graph_period}\n";
-    print "graph_scale yes\n";
-    print "graph_category postfix\n";
-    print "volume.label delivered volume\n";
-    print "volume.type DERIVE\n";
-    print "volume.min 0\n";
-    exit 0;
+       print "graph_title Postfix bytes throughput\n";
+       print "graph_args --base 1000 -l 0\n";
+       print "graph_vlabel bytes / \${graph_period}\n";
+       print "graph_scale yes\n";
+       print "graph_category postfix\n";
+       print "volume.label delivered volume\n";
+       print "volume.type DERIVE\n";
+       print "volume.min 0\n";
+       exit 0;
 }
 
 
-my $logfile = "$LOGDIR/$LOGFILE";
-
-if (! -f $logfile) {
-    print "volume.value U\n";
-    exit 0;
-}
-
 # load the stored data
 ($pos, $volume_delivered, $serialized_volumes_queue) = restore_state();
 
 
 if (!defined($volume_delivered)) {
 
-    # No state file present.  Avoid startup spike: Do not read log
-    # file up to now, but remember how large it is now, and next
-    # time read from there.
+       # No state file present.  Avoid startup spike: Do not read log
+       # file up to now, but remember how large it is now, and next
+       # time read from there.
 
-    $pos = (stat $logfile)[7]; # File size
+       my $cursor = `journalctl --facility=mail --show-cursor -n 0 | tail -n 1`;
+       $pos = ($cursor =~ s/^-- cursor: //r);
 
-    $volume_delivered = 0;
-    %volumes_per_queue_id = ();
+       $volume_delivered = 0;
+       %volumes_per_queue_id = ();
 } else {
-    # decode the serialized hash
-    # source format: "$id1=$size1:$timestamp1 $id2=$size2:$timestamp2 ..."
-    # The "serialized" value may be undefined, in case we just upgraded from the version before
-    # 2018, since that old version stored only two fields in the state file.  Tolerate this.
-    for my $queue_item_descriptor (split(/ /, $serialized_volumes_queue || "")) {
-        (my $queue_item_id, my $queue_item_content) = split(/=/, $queue_item_descriptor);
-        (my $size, my $timestamp) = split(/:/, $queue_item_content);
-        $volumes_per_queue_id{$queue_item_id} = { size => int($size), timestamp => int($timestamp) };
-    }
-    $pos = parseLogfile ($logfile, $pos);
+       # decode the serialized hash
+       # source format: "$id1=$size1:$timestamp1 $id2=$size2:$timestamp2 ..."
+       # The "serialized" value may be undefined, in case we just upgraded from the version before
+       # 2018, since that old version stored only two fields in the state file.  Tolerate this.
+       for my $queue_item_descriptor (split(/ /, $serialized_volumes_queue || "")) {
+               (my $queue_item_id, my $queue_item_content) = split(/=/, $queue_item_descriptor);
+               (my $size, my $timestamp) = split(/:/, $queue_item_content);
+               $volumes_per_queue_id{$queue_item_id} = { size => int($size), timestamp => int($timestamp) };
+       }
+       $pos = parseLogfile($pos);
 }
 
 print "volume.value $volume_delivered\n";