aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-09-25 14:09:23 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2015-09-25 14:09:23 +0300
commit40468ec97480e350dc47e6db44b87ccce35ac67b (patch)
treef089ebe6bd173a0169e85c92458f20c30b7f8395
parenta1a667a8341c84ea05572d3997b791d29d0dc440 (diff)
downloadnetsnmp-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.PL4
-rw-r--r--NetSNMP/Sendmail.pm96
-rw-r--r--SENDMAIL-STATS.txt124
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:

Return to:

Send suggestions and report system problems to the System administrator.