diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-09-25 14:09:23 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-09-25 14:09:23 +0300 |
commit | 40468ec97480e350dc47e6db44b87ccce35ac67b (patch) | |
tree | f089ebe6bd173a0169e85c92458f20c30b7f8395 | |
parent | a1a667a8341c84ea05572d3997b791d29d0dc440 (diff) | |
download | netsnmp-sendmail-40468ec97480e350dc47e6db44b87ccce35ac67b.tar.gz netsnmp-sendmail-40468ec97480e350dc47e6db44b87ccce35ac67b.tar.bz2 |
Implement per-queue statistics.
* Makefile.PL: Add versions to PREREQ_PM.
* NetSNMP/Sendmail.pm: Require Perl >=5.10; Add queueTable subtree.
* SENDMAIL-STATS.txt: Add queueTable subtree.
-rw-r--r-- | Makefile.PL | 4 | ||||
-rw-r--r-- | NetSNMP/Sendmail.pm | 96 | ||||
-rw-r--r-- | SENDMAIL-STATS.txt | 124 |
3 files changed, 177 insertions, 47 deletions
diff --git a/Makefile.PL b/Makefile.PL index 195b8c6..3a5e151 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -26,7 +26,9 @@ WriteMakefile( 'PM' => { 'NetSNMP/Sendmail.pm' => '$(INST_LIBDIR)/Sendmail.pm' }, - 'PREREQ_PM' => { 'NetSNMP::OID', 'NetSNMP::agent', 'NetSNMP::ASN' }, + 'PREREQ_PM' => { 'NetSNMP::OID' => 0, + 'NetSNMP::agent' => 0, + 'NetSNMP::ASN' => 0 }, ); sub MY::postamble { diff --git a/NetSNMP/Sendmail.pm b/NetSNMP/Sendmail.pm index cf1e3ca..28691ce 100644 --- a/NetSNMP/Sendmail.pm +++ b/NetSNMP/Sendmail.pm @@ -15,7 +15,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. package NetSNMP::Sendmail; - +require 5.10.0; use strict; use feature 'state'; use NetSNMP::OID (':all'); @@ -85,11 +85,14 @@ sub import { } use constant OID_BASE => '.1.3.6.1.4.1.9163.100'; -use constant SUBOID_QUEUE_TOTAL => '1'; +use constant SUBOID_QUEUE => '1'; use constant SUBOID_STAT_MAILERTAB => '2'; use constant SUBOID_STAT_TOTALTAB => '3'; use constant SUBOID_STAT_CONNTAB => '4'; +use constant OID_STAT_QUEUETOTALS => OID_BASE . '.' . SUBOID_QUEUE . '.1'; +use constant OID_STAT_QUEUETAB => OID_BASE . '.' . SUBOID_QUEUE . '.2'; +use constant OID_STAT_QUEUEENTRY => OID_STAT_QUEUETAB . '.1'; use constant OID_STAT_MAILERTAB => OID_BASE . '.' . SUBOID_STAT_MAILERTAB; use constant OID_STAT_MAILERENTRY => OID_STAT_MAILERTAB . '.1'; use constant OID_STAT_TOTALTAB => OID_BASE . '.' . SUBOID_STAT_TOTALTAB; @@ -99,23 +102,35 @@ my $oid_base = new NetSNMP::OID(OID_BASE); sub debug { # nothing +# print STDERR @_; +# print STDERR "\n"; } my %timestamp; -sub queue_totals { - state $n; +sub queue_stats { + state %tmp; if ($ttl{mailq}) { my $now = time(); - return $n if $now - $timestamp{mailq} < $ttl{mailq}; + return %tmp if $now - $timestamp{mailq} < $ttl{mailq}; $timestamp{mailq} = $now; + %tmp = (); } open(my $fd, '-|', $mailq_bin) or die "can't run $mailq_bin: $!"; - $n = shift [map { /Total requests:\s+(\d+)\s*$/ ? $1 : () } <$fd>]; + while (<$fd>) { + chomp; + if (/^(^\S+) is empty/) { + push @{$tmp{q}}, [ $1, 0 ]; + } elsif (/^\s*(\S+) \((\d+) requests\)/) { + push @{$tmp{q}}, [ $1, $2 ]; + } elsif (/Total requests:\s+(\d+)\s*$/) { + $tmp{total} = $1 + } + } close($fd); - return $n; + return %tmp; } sub mailer_stats { @@ -125,6 +140,7 @@ sub mailer_stats { my $now = time(); return %mstats if $now - $timestamp{mailstats} < $ttl{mailstats}; $timestamp{mailstats} = $now; + %mstats = (); debug("calling $mailstats_bin"); open(my $fd, '-|', "$mailstats_bin -P") @@ -153,16 +169,62 @@ sub mailer_stats { return %mstats; } -sub get_queue_totals { +sub get_queue { + my $request = shift; + my $mode = shift; + + debug("get_queue: enter: @_\n"); + my $prim = shift; + if ($prim == 1) { + if ($_[0] == 0) { + if ($mode == MODE_GETNEXT) { + get_queuetab($request, MODE_GETNEXT); + } elsif ($mode == MODE_GET) { + my %s = queue_stats(); + if (exists($s{total})) { + $request->setValue(ASN_COUNTER64, $s{total}); + } + } + } + } elsif ($prim == 2) { + get_queuetab($request, $mode, @_); + } + debug("get_queue: exit\n"); +} + +sub get_queuetab { my $request = shift; my $mode = shift; - if ($#_ == 0 and $_[0] == 0) { + debug("get_queuetab($mode," . join('.', @_) . ")"); + + my @idx = @_; + if ($#idx == -1) { + @idx = (1, 1, -1); + } + return unless shift(@idx) == 1; + return unless $#idx == 1; + + my %qstats = queue_stats(); + if ($idx[1] <= $#{$qstats{q}}) { if ($mode == MODE_GETNEXT) { - get_mailertab($request, MODE_GETNEXT); - } elsif ($mode == MODE_GET) { - $request->setValue(ASN_COUNTER64, queue_totals()); + ++$idx[1]; + if ($idx[1] > $#{$qstats{q}}) { + $idx[1] = 0; + ++$idx[0]; + return get_mailertab($request, MODE_GETNEXT) + unless $idx[0]-2 <= $#{$qstats{q}[$idx[1]]}; + } + ++$idx[0] if $idx[0] == 1; + my $oid = OID_STAT_QUEUEENTRY . '.' . $idx[0] . '.' . $idx[1]; + $request->setOID($oid); + debug("NEXT OID $oid"); + $mode = MODE_GET; } + if ($mode == MODE_GET) { + my $type = ($idx[0] == 2) ? ASN_OCTET_STR : ASN_COUNTER64; + $request->setValue($type, $qstats{q}[$idx[1]][$idx[0]-2]); + } } } @@ -189,6 +251,7 @@ sub get_mailertab { if ($idx[1] > $#{$mstats{mailertab}}) { $idx[1] = 0; ++$idx[0]; + ++$idx[0] if $idx[0] == 1; return get_totaltab($request, MODE_GETNEXT) unless $idx[0]-3 <= $#{$mstats{mailer}{$mstats{mailertab}->[$idx[1]]}}; } @@ -197,7 +260,6 @@ sub get_mailertab { debug("NEXT OID $oid"); $mode = MODE_GET; } - ++$idx[0] if $idx[0] == 1; if ($mode == MODE_GET) { my $mailer = $mstats{mailertab}->[$idx[1]]; if ($idx[0] == 2) { @@ -271,7 +333,7 @@ sub get_conntab { } my %oidhandler = ( - (+SUBOID_QUEUE_TOTAL) => \&get_queue_totals, + (+SUBOID_QUEUE) => \&get_queue, (+SUBOID_STAT_MAILERTAB) => \&get_mailertab, (+SUBOID_STAT_TOTALTAB) => \&get_totaltab, (+SUBOID_STAT_CONNTAB) => \&get_conntab @@ -292,9 +354,9 @@ sub mailstats_handler { if ($#subid == -1) { debug("RESTART"); if ($mode == MODE_GETNEXT) { - $request->setOID($oid_base . '.' . SUBOID_QUEUE_TOTAL . '.0'); - push @subid, 0; - $fun = $oidhandler{+SUBOID_QUEUE_TOTAL}; + $request->setOID(OID_STAT_QUEUETOTALS . '.0'); + push @subid, SUBOID_QUEUE, 0; + $fun = $oidhandler{+SUBOID_QUEUE}; $mode = MODE_GET; } } else { diff --git a/SENDMAIL-STATS.txt b/SENDMAIL-STATS.txt index 8fdb1c2..7761e42 100644 --- a/SENDMAIL-STATS.txt +++ b/SENDMAIL-STATS.txt @@ -7,23 +7,25 @@ SENDMAIL-STATS DEFINITIONS ::= BEGIN -- ************************************************************* IMPORTS - MODULE-IDENTITY, OBJECT-TYPE, enterprises, Counter64 + MODULE-IDENTITY, OBJECT-TYPE, enterprises, Counter64, Integer32 FROM SNMPv2-SMI + TEXTUAL-CONVENTION + FROM SNMPv2-TC OBJECT-GROUP, MODULE-COMPLIANCE FROM SNMPv2-CONF; -sendmail OBJECT IDENTIFIER ::= { enterprises 9163 100 } - -sendmailMIB MODULE-IDENTITY - LAST-UPDATED "201411280837Z" +sendmail MODULE-IDENTITY + LAST-UPDATED "201509250219Z" ORGANIZATION "Gray Software" CONTACT-INFO "Sergey Poznyakoff <gray@gnu.org>" DESCRIPTION "This MIB module defines objects for Sendmail statistics." - REVISION "201411280837Z" + REVISION "201509250219Z" DESCRIPTION "First revision." - ::= { sendmail 0 } + ::= { enterprises 9163 100 } + +queue OBJECT IDENTIFIER ::= { sendmail 1 } queueTotal OBJECT-TYPE SYNTAX Counter64 @@ -31,8 +33,79 @@ queueTotal OBJECT-TYPE STATUS current DESCRIPTION "Number of messages in queue." - ::= { sendmail 1 } + ::= { queue 1 } + +QueueNameString ::= TEXTUAL-CONVENTION + DISPLAY-HINT "1024t" + STATUS current + DESCRIPTION "A string representing Sendmail queue directory." + SYNTAX OCTET STRING (SIZE (0..1024)) + +QueueEntry ::= SEQUENCE { + queueIndex Index32, + queueName QueueNameString, + queueMessages Counter64 +} + +queueTable OBJECT-TYPE + SYNTAX SEQUENCE OF QueueEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Queue table." + ::= { queue 2 } + +queueEntry OBJECT-TYPE + SYNTAX QueuEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "An entry (conceptual row) describing a queue." + INDEX { queueIndex } + ::= { queueTable 1 } + +queueIndex OBJECT-TYPE + SYNTAX Integer32 (0..65535) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A number uniquely identifying each queue." + ::= { queueEntry 1 } + +queueName OBJECT-TYPE + SYNTAX QueueNameString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the mailer." + ::= { queueEntry 2 } + +queueMessages OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of messages in the queue." + ::= { queueEntry 3 } + +MailerNameString ::= TEXTUAL-CONVENTION + DISPLAY-HINT "128t" + STATUS current + DESCRIPTION "A string containing Sendmail mailer name." + SYNTAX OCTET STRING (SIZE (0..128)) +MailerEntry ::= SEQUENCE { + mailerIndex Integer32, + mailerName MailerNameString, + mailerMessagesFrom Counter64, + mailerKBytesFrom Counter64, + mailerMessagesTo Counter64, + mailerKBytesTo Counter64, + mailerMessagesRejected Counter64, + mailerMessagesDiscarded Counter64, + mailerMessagesQuarantined Counter64 +} + mailerTable OBJECT-TYPE SYNTAX SEQUENCE OF MailerEntry MAX-ACCESS not-accessible @@ -50,33 +123,16 @@ mailerEntry OBJECT-TYPE INDEX { mailerIndex } ::= { mailerTable 1 } -MailerEntry ::= SEQUENCE { - mailerIndex Integer32, - mailerName mailerNameString, - mailerMessagesFrom Counter64, - mailerKBytesFrom Counter64, - mailerMessagesTo Counter64, - mailerKBytesTo Counter64, - mailerMessagesRejected Counter64, - mailerMessagesDiscarded Counter64, - mailerMessagesQuarantined Counter64, -} - mailerIndex OBJECT-TYPE - SYNTAX Integer32 + SYNTAX Integer32 (0..65535) MAX-ACCESS not-accessible STATUS current DESCRIPTION "A number uniquely identifying each mailer." ::= { mailerEntry 1 } -mailerNameString TEXTUAL-CONVENTION - SYNTAX OCTET STRING (SIZE (0..128)) - DISPLAY-HINT "128t" - STATUS current - mailerName OBJECT-TYPE - SYNTAX mailerNameString + SYNTAX MailerNameString MAX-ACCESS read-only STATUS current DESCRIPTION @@ -214,7 +270,7 @@ connectionMessagesTo OBJECT-TYPE STATUS current DESCRIPTION "Total number of messages sent over TCP." - ::= { connection 3 } + ::= { connection 2 } connectionMessagesRejected OBJECT-TYPE SYNTAX Counter64 @@ -222,5 +278,15 @@ connectionMessagesRejected OBJECT-TYPE STATUS current DESCRIPTION "Total number of messages rejected over TCP." - ::= { connection 5 } + ::= { connection 3 } +END + +-- Local variables: +-- eval: (add-hook 'write-file-hooks 'time-stamp) +-- time-stamp-start: "\\(LAST-UPDATED\\|REVISION\\) *\"" +-- time-stamp-end: "\"" +-- time-stamp-format: "%:y%02m%02d%02H%02MZ" +-- time-stamp-line-limit: 32 +-- time-stamp-count: 2 +-- end: |