mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-09-12 05:38:42 +00:00
Merge pull request #1221 from shtrom/snmp__if_combined-stacked
Snmp if combined stacked
This commit is contained in:
commit
07220eebae
3 changed files with 281 additions and 159 deletions
BIN
plugins/snmp/example-graphs/snmp_if_combined-1.png
Normal file
BIN
plugins/snmp/example-graphs/snmp_if_combined-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
BIN
plugins/snmp/example-graphs/snmp_if_combined-day.png
Normal file
BIN
plugins/snmp/example-graphs/snmp_if_combined-day.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
|
@ -8,10 +8,32 @@ snmp__if_combined - SNMP card plugin to monitor the network interfaces of any ne
|
|||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Any SNMP capable networked computer equipment. Using a command such
|
||||
as "munin-node-configure --snmp switch.langfeldt.net --snmpversion 2c
|
||||
--snmpcommunity public | sh -x" should auto-detect all applicable
|
||||
interfaces. On a typical switch you will get one plugin pr. ethernet
|
||||
port. On a router you might get one plugin per VLAN interface.
|
||||
as
|
||||
|
||||
munin-node-configure --snmp switch.langfeldt.net --snmpversion 2c --snmpcommunity public | sh -x
|
||||
|
||||
should auto-detect all applicable interfaces. On a typical switch you will get
|
||||
one plugin pr. ethernet port. On a router you might get one plugin per VLAN
|
||||
interface.
|
||||
|
||||
=head2 NOTABLE DIFFERENCE WITH SNMP__IF_MULTI
|
||||
|
||||
The `smnp__if_multi` plugin records data in _bytes_ per second, and shows them
|
||||
as bps by using CDEFs when graphing. This plugin performs the multiplication
|
||||
upon reporting the value, and therefore doesn't have a CDEF in the graphing
|
||||
path.
|
||||
|
||||
This is important when migration from `snmp__if_multi`, for at least two
|
||||
aspects:
|
||||
|
||||
- Reusing RRDs: it is not possible to just rename the old RRD files from
|
||||
`smnp__if_multi`, as historical data will be graphed as 8 times smaller than in
|
||||
reality. The stored values would need to be adjusted.
|
||||
- Data loaning: borrowing graphs no longer need to include a CDEF to convert
|
||||
bytes to bits. Conversely, they do now need a CDEF to convert bits to bytes.
|
||||
|
||||
To reflect this aspect explicitely, the root graph's totals are named
|
||||
recv_bits and send_bits.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
|
@ -19,9 +41,10 @@ As a rule SNMP plugins need site specific configuration. The default
|
|||
configuration (shown here) will only work on insecure sites/devices:
|
||||
|
||||
[snmp_*]
|
||||
env.version 2
|
||||
env.community public
|
||||
env.ifTypeOnly ethernetCsmacd
|
||||
env.version 2
|
||||
env.community public
|
||||
env.ifTypeOnly ethernetCsmacd
|
||||
env.stackedRoot 1
|
||||
|
||||
In general SNMP is not very secure at all unless you use SNMP version
|
||||
3 which supports authentication and privacy (encryption). But in any
|
||||
|
@ -51,13 +74,22 @@ would normally be for VPNs. A minor horde of different interface types
|
|||
are supposted, please see IANAifType-MIB (on your system or find with
|
||||
Google) for a full list.
|
||||
|
||||
The `stackedRoot` option determines whether the root summary graph shows the
|
||||
traffic on each interface separately, or stacks them on top of one another to
|
||||
show the total traffic through the device.
|
||||
|
||||
=head1 INTERPRETATION
|
||||
|
||||
A single graph is generated with all the interfaces overlaid one over
|
||||
the other: incoming traffic is received on the interface from the
|
||||
connected device, outgoing is sent to it instead.
|
||||
|
||||
Sub-graphs are created, one per interface, akin to snmp__if_multi
|
||||
With the `stackedRoot` option, traffic is plotted as stacked areas instead, and
|
||||
two additional series are calculated to show the total usage of the device.
|
||||
Those series are useful for loaning into higher-level summary graphs (but see
|
||||
BUGS below).
|
||||
|
||||
Sub-graphs are created, one per interface, akin to `snmp__if_multi`
|
||||
plugin.
|
||||
|
||||
=head1 MIB INFORMATION
|
||||
|
@ -82,6 +114,8 @@ counters (see FEATURES below).
|
|||
|
||||
=head1 BUGS
|
||||
|
||||
=head2 Missing indexing options
|
||||
|
||||
Should support indexing by
|
||||
|
||||
- ifIndex
|
||||
|
@ -92,12 +126,41 @@ Should support indexing by
|
|||
|
||||
(and anything else MRTG can index by) in addition to OID-index as now.
|
||||
|
||||
Pulling in a user definable set of ifName/ifDescr/ifAlias for textual
|
||||
description and even graph_title would also be nice.
|
||||
=head2 Total traffic oddities in stackedRoot mode.
|
||||
|
||||
When using the `stackedRoot` option, the total lines (`send_bits` and
|
||||
`recv_bits`) may sometimes jump to nonsensical values. This is a bug shared with
|
||||
the original `snmp__if_multi`.
|
||||
|
||||
This seems to be due to the way those series are calculated, by summing the
|
||||
current values of the other counters. The first issue is that of summing 64-bit
|
||||
values into a single variable that is likely to also be 64 bits. The second
|
||||
issue (compounded by the first) is that of wraparound. When one of the counters
|
||||
wraps around, the sum jumps backwards. With a `min` set to 0, and other counters
|
||||
having kept increasing, this looks like a huge increase the total counter.
|
||||
Depending on the `max` (which should match the backplane bandwidth), this may
|
||||
not be correctly recognised as a spurious value, just reconded as valid.
|
||||
|
||||
There is no clear solution to this bug at the moment, save for trying to salvage
|
||||
the data after the fact. This can be done my either clipping all values beyond a
|
||||
maximum (e.g., the known use of the switch, rather that its full backplane
|
||||
bandwith).
|
||||
|
||||
RANGE='[0-9.]\+e+\(0[789]\|[1-9][0-9]\)' # Anything >=1e07
|
||||
rrdtool dump ${RRD_FILE} \
|
||||
| sed "s/<v>${RANGE}/<v>NaN/" \
|
||||
| rrdtool restore - ${RRD_FILE}.new
|
||||
mv ${RRD_FILE}.new ${RRD_FILE} # Make sure you have a backup!
|
||||
|
||||
Alternatively, if you can determine the time at whiche the spurious value was
|
||||
recorded, you can just make that value a NaN.
|
||||
|
||||
TIMESTAMP="1623492000"
|
||||
rrdtool dump "${RRD_FILE}" \
|
||||
| sed "/${TIMESTAMP}/s/<v>.*<\/v>/<v>NaN<\/v>/" \
|
||||
| rrdtool restore - "${RRD_FILE}.new"
|
||||
mv ${RRD_FILE}.new ${RRD_FILE} # Make sure you have a backup!
|
||||
|
||||
If we get a patch to support the .oldname attribute then we may use
|
||||
that to let the operator change the indexing dynamically without data
|
||||
loss.
|
||||
|
||||
=head1 FEATURES
|
||||
|
||||
|
@ -117,7 +180,7 @@ usage of it, it is nothing the plugin can fix. In the future Munin
|
|||
may be able to run the plugin more often than the counter wraps
|
||||
around.
|
||||
|
||||
=head1 AUTHOR
|
||||
=head1 AUTHORS
|
||||
|
||||
Copyright (C) 2012 Diego Elio Pettenò.
|
||||
|
||||
|
@ -136,6 +199,8 @@ Reworked to snmp__if_multi by Nicolai Langfeldt.
|
|||
|
||||
Reworked to snmp__if_combined by Diego Elio Pettenò.
|
||||
|
||||
Stacked option by Olivier Mehani <shtrom+munin@ssji.net>
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2
|
||||
|
@ -173,8 +238,13 @@ my $iface;
|
|||
# .1.3.6.1.2.1.31.1.1.1.10. Counter64 ifHCOutOctets
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq "snmpconf") {
|
||||
print "require 1.3.6.1.2.1.2.2.1.1.\n";
|
||||
exit 0;
|
||||
print "require 1.3.6.1.2.1.2.2.1.1.\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $stackedRoot = 0;
|
||||
if (exists $ENV{'stackedRoot'}) {
|
||||
$stackedRoot = $ENV{'stackedRoot'};
|
||||
}
|
||||
|
||||
my $sysDescr = '1.3.6.1.2.1.1.1.0';
|
||||
|
@ -430,7 +500,7 @@ my %ifTypes = (
|
|||
x86Laps => 242,
|
||||
wwanPP => 243,
|
||||
wwanPP2 => 244
|
||||
);
|
||||
);
|
||||
|
||||
my %ifTypeByNum = map { $ifTypes{$_} => $_; } keys %ifTypes;
|
||||
|
||||
|
@ -444,33 +514,33 @@ sub do_collect {
|
|||
my $session = Munin::Plugin::SNMP->session();
|
||||
|
||||
$snmpinfo = $session->get_hash(
|
||||
-baseoid => $ifOIDBase,
|
||||
-cols =>
|
||||
{ 2 => 'ifDescr',
|
||||
# Type: See above
|
||||
3 => 'ifType',
|
||||
5 => 'ifSpeed',
|
||||
# Oper: 1) up 2) down 3) testing
|
||||
# 4) unknown, 5) dormant 6) not present
|
||||
# 7) lowerLayerDown
|
||||
8 => 'ifOperStatus',
|
||||
10 => 'ifInOctets',
|
||||
13 => 'ifInDiscards',
|
||||
14 => 'ifInErrors',
|
||||
16 => 'ifOutOctets',
|
||||
19 => 'ifOutDiscards',
|
||||
20 => 'ifOutErrors',
|
||||
});
|
||||
-baseoid => $ifOIDBase,
|
||||
-cols => {
|
||||
2 => 'ifDescr',
|
||||
# Type: See above
|
||||
3 => 'ifType',
|
||||
5 => 'ifSpeed',
|
||||
# Oper: 1) up 2) down 3) testing
|
||||
# 4) unknown, 5) dormant 6) not present
|
||||
# 7) lowerLayerDown
|
||||
8 => 'ifOperStatus',
|
||||
10 => 'ifInOctets',
|
||||
13 => 'ifInDiscards',
|
||||
14 => 'ifInErrors',
|
||||
16 => 'ifOutOctets',
|
||||
19 => 'ifOutDiscards',
|
||||
20 => 'ifOutErrors',
|
||||
});
|
||||
|
||||
# ifXEntry - SNMP v2 and up only - on some devices
|
||||
$snmpinfoX = $session->get_hash(
|
||||
-baseoid => $ifv2OIDBase,
|
||||
-cols =>
|
||||
{ 6 => 'ifHCInOctets',
|
||||
10 => 'ifHCOutOctets',
|
||||
15 => 'ifHighSpeed',
|
||||
18 => 'ifAlias',
|
||||
});
|
||||
-baseoid => $ifv2OIDBase,
|
||||
-cols => {
|
||||
6 => 'ifHCInOctets',
|
||||
10 => 'ifHCOutOctets',
|
||||
15 => 'ifHighSpeed',
|
||||
18 => 'ifAlias',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -481,27 +551,27 @@ sub do_preprocess_if {
|
|||
my $response = $snmpinfo->{$if}->{ifType} || 1;
|
||||
|
||||
if (defined($mediatype)) {
|
||||
if (defined($mediatype->{$response})) {
|
||||
# This is one of the interesting media types
|
||||
} else {
|
||||
# This media type is not interesting. Remove.
|
||||
delete $snmpinfo->{$if} if exists $snmpinfo->{$if};
|
||||
delete $snmpinfoX->{$if} if exists $snmpinfoX->{$if};
|
||||
return;
|
||||
}
|
||||
if (defined($mediatype->{$response})) {
|
||||
# This is one of the interesting media types
|
||||
} else {
|
||||
# This media type is not interesting. Remove.
|
||||
delete $snmpinfo->{$if} if exists $snmpinfo->{$if};
|
||||
delete $snmpinfoX->{$if} if exists $snmpinfoX->{$if};
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined ($response = $snmpinfo->{$if}->{ifOperStatus})) {
|
||||
# 1 = up, 2 = down, 7 = lowerLayerDown
|
||||
if ($response == 2 or $response == 7) {
|
||||
# Fold recognized down states into one.
|
||||
$response = $snmpinfo->{$if}->{ifOperStatus} = 2;
|
||||
} elsif ($response != 1) {
|
||||
# This interface is fishy, remove and forget.
|
||||
delete $snmpinfo->{$if} if exists $snmpinfo->{$if};
|
||||
delete $snmpinfoX->{$if} if exists $snmpinfoX->{$if};
|
||||
return;
|
||||
}
|
||||
# 1 = up, 2 = down, 7 = lowerLayerDown
|
||||
if ($response == 2 or $response == 7) {
|
||||
# Fold recognized down states into one.
|
||||
$response = $snmpinfo->{$if}->{ifOperStatus} = 2;
|
||||
} elsif ($response != 1) {
|
||||
# This interface is fishy, remove and forget.
|
||||
delete $snmpinfo->{$if} if exists $snmpinfo->{$if};
|
||||
delete $snmpinfoX->{$if} if exists $snmpinfoX->{$if};
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,7 +580,7 @@ sub do_preprocess {
|
|||
my $mediatypes = 'ALL';
|
||||
|
||||
if (exists( $ENV{'ifTypeOnly'} )) {
|
||||
$mediatypes = $ENV{'ifTypeOnly'};
|
||||
$mediatypes = $ENV{'ifTypeOnly'};
|
||||
}
|
||||
|
||||
my @mediatypes = split(/[ ,]+/,$mediatypes);
|
||||
|
@ -519,19 +589,19 @@ sub do_preprocess {
|
|||
my $mediatype={};
|
||||
|
||||
if ($mediatypes eq 'ALL') {
|
||||
$mediatype = undef;
|
||||
$mediatype = undef;
|
||||
} else {
|
||||
foreach my $type (@mediatypes) {
|
||||
if (exists($ifTypes{$type})) {
|
||||
$mediatype->{$ifTypes{$type}} = 1;
|
||||
} else {
|
||||
die "Unknown media type '$type' specified in ifTypeOnly\n";
|
||||
}
|
||||
}
|
||||
foreach my $type (@mediatypes) {
|
||||
if (exists($ifTypes{$type})) {
|
||||
$mediatype->{$ifTypes{$type}} = 1;
|
||||
} else {
|
||||
die "Unknown media type '$type' specified in ifTypeOnly\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $if (keys %{$snmpinfo}) {
|
||||
do_preprocess_if($mediatype, $if);
|
||||
do_preprocess_if($mediatype, $if);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -539,58 +609,78 @@ sub do_preprocess {
|
|||
sub do_config_root {
|
||||
my ($host, $version) = @_;
|
||||
|
||||
my $extrainfo="";
|
||||
|
||||
if (defined ($snmpinfoX->{0}->{ifHCInOctets})) {
|
||||
# If we get an answer at the 64 bit OID then this switch
|
||||
# supports the extended MIB
|
||||
|
||||
$extrainfo .= " This switch supports 64 bit byte counters and these are used by this plugin.";
|
||||
} else {
|
||||
# If not we only have a 32 bit counter and are lost.
|
||||
$extrainfo .= " NOTE! This switch supports only 32 bit byte counters which makes the plugin unreliable and unsuitable for most 100Mb (or faster) interfaces, where bursts are expected to exceed 50Mbps. This means that for interfaces where much traffic is sent this plugin will report false thruputs and cannot be trusted.";
|
||||
|
||||
# unless perhaps the operator can get us snmp version 2c or 3?
|
||||
$extrainfo .= " I notice that you use SNMP version 1 which does not support 64 bit quantities. You may get better results if you switch to SNMP version 2c or 3. Please refer to the plugin documentation."
|
||||
if $version == 1;
|
||||
}
|
||||
|
||||
print <<END;
|
||||
|
||||
multigraph snmp_if_combined
|
||||
graph_title $host interfaces traffic
|
||||
graph_title All interfaces traffic
|
||||
graph_args --base 1000
|
||||
graph_vlabel bits in (-) / out (+) per \${graph_period}
|
||||
graph_category network
|
||||
graph_info This graph shows the total traffic for $host.$extrainfo
|
||||
graph_info This graph shows the total traffic for $host.
|
||||
END
|
||||
|
||||
print "graph_order";
|
||||
my @ifs;
|
||||
foreach my $if (sort {$a <=> $b} keys %{$snmpinfo}) {
|
||||
print " recv$if=snmp_if_combined.$if.recv send$if=snmp_if_combined.$if.send";
|
||||
print " recv$if=snmp_if_combined.$if.recv send$if=snmp_if_combined.$if.send";
|
||||
push @ifs, "snmp_if_combined.$if";
|
||||
}
|
||||
if ($stackedRoot) {
|
||||
print " recv_bits send_bits";
|
||||
}
|
||||
print "\n";
|
||||
|
||||
# XXX: For some reason, Munin doesn't resolve AREASTACK properly in this case...
|
||||
my $area_or_stack = "AREA";
|
||||
foreach my $if (sort {$a <=> $b} keys %{$snmpinfo}) {
|
||||
my $alias = $snmpinfo->{$if}->{ifDescr} || "Interface $if";
|
||||
my $alias = $snmpinfoX->{$if}->{ifAlias} || $snmpinfo->{$if}->{ifDescr} || "Interface $if";
|
||||
|
||||
if (! ($alias =~ /\d+/) ) {
|
||||
# If there are no numbers in the $alias add the if index
|
||||
$alias .=" (if $if)";
|
||||
}
|
||||
if (! ($alias =~ /\d+/) ) {
|
||||
# If there are no numbers in the $alias add the if index
|
||||
$alias .=" (if $if)";
|
||||
}
|
||||
|
||||
print <<END;
|
||||
print <<END;
|
||||
recv$if.label $alias
|
||||
recv$if.graph no
|
||||
send$if.label $alias
|
||||
send$if.negative recv$if
|
||||
END
|
||||
if ($stackedRoot) {
|
||||
print "send$if.draw $area_or_stack\n";
|
||||
$area_or_stack = "STACK";
|
||||
}
|
||||
}
|
||||
if ($stackedRoot) {
|
||||
|
||||
# If a stacked graph is requested, plot the total. Rather than
|
||||
# aggregating them with CDEFs of SUMs, we sum them in the script, which
|
||||
# allows us to create real series than can be easily borrowed by other
|
||||
# loaning graphs.
|
||||
#
|
||||
# Using CDEFs and SUMs proved difficult anyway. Due to bugs in Munin
|
||||
# 2.0's GraphOld core (negatives and multigraph), the graph_total
|
||||
# behaves weirdly: - only the positive total is plotted (but both
|
||||
# positive and negatives are calculated); - the graph_total is also
|
||||
# included in the single graphs, where it is clearly unecessary.
|
||||
|
||||
print <<END;
|
||||
recv_bits.label Total traffic
|
||||
recv_bits.type DERIVE
|
||||
recv_bits.min 0
|
||||
recv_bits.graph no
|
||||
send_bits.label Total traffic
|
||||
send_bits.type DERIVE
|
||||
send_bits.min 0
|
||||
send_bits.draw LINE1
|
||||
send_bits.colour 000000
|
||||
send_bits.negative recv_bits
|
||||
END
|
||||
}
|
||||
|
||||
print <<END;
|
||||
|
||||
multigraph snmp_if_combined_err
|
||||
graph_title $host interfaces errors
|
||||
graph_title All interfaces errors
|
||||
graph_args --base 1000
|
||||
graph_vlabel errors in (-) / out (+) per \${graph_period}
|
||||
graph_category network
|
||||
|
@ -598,19 +688,19 @@ END
|
|||
|
||||
print "graph_order";
|
||||
foreach my $if (sort {$a <=> $b} keys %{$snmpinfo}) {
|
||||
print " recv$if=snmp_if_combined_err.$if.total_in send$if=snmp_if_combined_err.$if.total_out";
|
||||
print " recv$if=snmp_if_combined_err.$if.total_in send$if=snmp_if_combined_err.$if.total_out";
|
||||
}
|
||||
print "\n";
|
||||
|
||||
foreach my $if (sort {$a <=> $b} keys %{$snmpinfo}) {
|
||||
my $alias = $snmpinfoX->{$if}->{ifAlias} || $snmpinfo->{$if}->{ifDescr} || "Interface $if";
|
||||
my $alias = $snmpinfoX->{$if}->{ifAlias} || $snmpinfo->{$if}->{ifDescr} || "Interface $if";
|
||||
|
||||
if (! ($alias =~ /\d+/) ) {
|
||||
# If there are no numbers in the $alias add the if index
|
||||
$alias .=" (if $if)";
|
||||
}
|
||||
if (! ($alias =~ /\d+/) ) {
|
||||
# If there are no numbers in the $alias add the if index
|
||||
$alias .=" (if $if)";
|
||||
}
|
||||
|
||||
print <<END;
|
||||
print <<END;
|
||||
recv$if.label $alias
|
||||
recv$if.graph no
|
||||
send$if.label $alias
|
||||
|
@ -625,38 +715,55 @@ sub do_config_if {
|
|||
my $alias = $snmpinfoX->{$if}->{ifAlias} || $snmpinfo->{$if}->{ifDescr} || "Interface $if";
|
||||
|
||||
if (! ($alias =~ /\d+/) ) {
|
||||
# If there are no numbers in the $alias add the if index
|
||||
$alias .=" (if $if)";
|
||||
# If there are no numbers in the $alias add the if index
|
||||
$alias .=" (if $if)";
|
||||
}
|
||||
|
||||
my $warn = undef;
|
||||
my $speed = 0;
|
||||
my $extrainfo = "";
|
||||
|
||||
my $extrainfo="";
|
||||
|
||||
if (defined ($snmpinfoX->{$if}->{ifHCInOctets})) {
|
||||
# If we get an answer at the 64 bit OID then this switch
|
||||
# supports the extended MIB
|
||||
|
||||
$extrainfo .= " This switch supports 64 bit byte counters and these are used by this plugin.";
|
||||
} else {
|
||||
# If not we only have a 32 bit counter and are lost.
|
||||
$extrainfo .= " NOTE! This switch supports only 32 bit byte counters which makes the plugin unreliable and unsuitable for most 100Mb (or faster) interfaces, where bursts are expected to exceed 50Mbps. This means that for interfaces where much traffic is sent this plugin will report false throughputs and cannot be trusted.";
|
||||
|
||||
# unless perhaps the operator can get us snmp version 2c or 3?
|
||||
$extrainfo .= " I notice that you use SNMP version 1 which does not support 64 bit quantities. You may get better results if you switch to SNMP version 2c or 3. Please refer to the plugin documentation."
|
||||
if $version == 1;
|
||||
}
|
||||
|
||||
if (defined ($speed = $snmpinfoX->{$if}->{ifHighSpeed}) and $speed) {
|
||||
# Speed in 1,000,000 bits per second
|
||||
$speed = $speed * 1000000;
|
||||
$warn = $speed / 75 * 100;
|
||||
# Speed in 1,000,000 bits per second
|
||||
$speed = $speed * 1000000;
|
||||
$warn = $speed / 75 * 100;
|
||||
|
||||
my $textspeed = scaleNumber($speed,'bps','',
|
||||
'The interface speed is %.1f%s%s.');
|
||||
my $textspeed = scaleNumber($speed,'bps','',
|
||||
'The interface speed is %.1f%s%s.');
|
||||
|
||||
$extrainfo .= ' '.$textspeed if $textspeed;
|
||||
$extrainfo .= ' '.$textspeed if $textspeed;
|
||||
} elsif (defined ($speed = $snmpinfo->{$if}->{ifSpeed}) and $speed) {
|
||||
# Speed in bits pr. second
|
||||
$warn = $speed*100/75;
|
||||
$warn = $speed*100/75;
|
||||
|
||||
my $textspeed = scaleNumber($speed,'bps','',
|
||||
'The interface speed is %.1f%s%s.');
|
||||
my $textspeed = scaleNumber($speed,'bps','',
|
||||
'The interface speed is %.1f%s%s.');
|
||||
|
||||
$extrainfo .= " ".$textspeed if $textspeed;
|
||||
$extrainfo .= " ".$textspeed if $textspeed;
|
||||
}
|
||||
|
||||
$response = $snmpinfo->{$if}->{ifType};
|
||||
$extrainfo .= " This is a '".$ifTypeByNum{$response}."' interface.";
|
||||
|
||||
print <<END;
|
||||
multigraph snmp_if_combined.$if
|
||||
graph_title $alias traffic
|
||||
graph_info This graph shows traffic for the \"$alias\" network interface.$extrainfo
|
||||
graph_args --base 1000
|
||||
graph_vlabel bits in (-) / out (+) per \${graph_period}
|
||||
graph_category network
|
||||
|
@ -672,16 +779,17 @@ send.min 0
|
|||
END
|
||||
|
||||
if ( defined($speed) ) {
|
||||
printf("recv.max %s\nsend.max %s\n", $speed, $speed);
|
||||
printf("recv.max %s\nsend.max %s\n", $speed, $speed);
|
||||
}
|
||||
|
||||
if ( defined($warn) ) {
|
||||
printf("recv.warning %s\nsend.warning %s\n", $warn, $warn);
|
||||
printf("recv.warning %s\nsend.warning %s\n", $warn, $warn);
|
||||
}
|
||||
|
||||
print <<END;
|
||||
multigraph snmp_if_combined_err.$if
|
||||
graph_title $alias errors
|
||||
graph_info This graph shows errors for the \"$alias\" network interface.$extrainfo
|
||||
graph_args --base 1000
|
||||
graph_vlabel errors in (-) / out (+) per \${graph_period}
|
||||
graph_category network
|
||||
|
@ -721,34 +829,18 @@ sub do_fetch_if {
|
|||
|
||||
my $status = $snmpinfo->{$if}->{ifOperStatus} || 1;
|
||||
|
||||
my $response;
|
||||
|
||||
# 1 means up
|
||||
# 2 means set to down
|
||||
# Everything else we ignore.
|
||||
|
||||
print "multigraph snmp_if_combined.$if\n";
|
||||
|
||||
if ($status == 2) {
|
||||
# Interface is down
|
||||
print "recv.value U\n";
|
||||
print "send.value U\n";
|
||||
print "send.extinfo This interface is currently down.\n";
|
||||
goto if_errors;
|
||||
}
|
||||
|
||||
$response = $snmpinfoX->{$if}->{ifHCInOctets} || $snmpinfo->{$if}->{ifInOctets};
|
||||
printf("recv.value %s\n", defined($response) ? ($response * 8) : "U");
|
||||
|
||||
$response = $snmpinfoX->{$if}->{ifHCOutOctets} || $snmpinfo->{$if}->{ifOutOctets};
|
||||
printf("send.value %s\n", defined($response) ? ($response * 8) : "U");
|
||||
|
||||
if_errors:
|
||||
|
||||
print "multigraph snmp_if_combined_err.$if\n";
|
||||
|
||||
if ($status == 2) {
|
||||
print <<END;
|
||||
if ($status != 1) {
|
||||
# Interface is down
|
||||
print <<END;
|
||||
multigraph snmp_if_combined.$if
|
||||
recv.value U
|
||||
send.value U
|
||||
send.extinfo This interface is currently down.
|
||||
multigraph snmp_if_combined_err.$if
|
||||
errors_in.value U
|
||||
errors_out.value U
|
||||
discards_in.value U
|
||||
|
@ -757,28 +849,46 @@ total_in.value U
|
|||
total_out.value U
|
||||
errors_out.extinfo This interface is currently down
|
||||
END
|
||||
return;
|
||||
return (undef, undef);
|
||||
}
|
||||
|
||||
my $response;
|
||||
my $recv;
|
||||
my $send;
|
||||
|
||||
print "multigraph snmp_if_combined.$if\n";
|
||||
|
||||
$response = $snmpinfoX->{$if}->{ifHCInOctets} || $snmpinfo->{$if}->{ifInOctets};
|
||||
$recv = defined($response) ? ($response * 8) : undef;
|
||||
printf("recv.value %s\n", $recv || "U");
|
||||
|
||||
$response = $snmpinfoX->{$if}->{ifHCOutOctets} || $snmpinfo->{$if}->{ifOutOctets};
|
||||
$send = defined($response) ? ($response * 8) : undef;
|
||||
printf("send.value %s\n", $send || "U");
|
||||
|
||||
print "multigraph snmp_if_combined_err.$if\n";
|
||||
|
||||
my $errors = $snmpinfo->{$if}->{ifInErrors};
|
||||
my $discards = $snmpinfo->{$if}->{ifInDiscards};
|
||||
printf("errors_in %s\n".
|
||||
"discards_in %s\n".
|
||||
"total_in %s\n",
|
||||
$errors || "U",
|
||||
$discards || "U",
|
||||
($errors || 0) + ($discards || 0)
|
||||
);
|
||||
printf("errors_in.value %s\n".
|
||||
"discards_in.value %s\n".
|
||||
"total_in.value %s\n",
|
||||
$errors || "U",
|
||||
$discards || "U",
|
||||
($errors || 0) + ($discards || 0)
|
||||
);
|
||||
|
||||
$errors = $snmpinfo->{$if}->{ifOutErrors};
|
||||
$discards = $snmpinfo->{$if}->{ifOutDiscards};
|
||||
printf("errors_out %s\n".
|
||||
"discards_out %s\n".
|
||||
"total_out %s\n",
|
||||
$errors || "U",
|
||||
$discards || "U",
|
||||
($errors || 0) + ($discards || 0)
|
||||
);
|
||||
printf("errors_out.value %s\n".
|
||||
"discards_out.value %s\n".
|
||||
"total_out.value %s\n",
|
||||
$errors || "U",
|
||||
$discards || "U",
|
||||
($errors || 0) + ($discards || 0)
|
||||
);
|
||||
|
||||
return ($recv, $send);
|
||||
}
|
||||
|
||||
sub do_config {
|
||||
|
@ -788,7 +898,7 @@ sub do_config {
|
|||
print "host_name $host\n" unless $host eq 'localhost';
|
||||
|
||||
foreach my $if (sort {$a <=> $b} keys %{$snmpinfo}) {
|
||||
do_config_if($host,$version,$if);
|
||||
do_config_if($host,$version,$if);
|
||||
}
|
||||
|
||||
do_config_root($host,$version);
|
||||
|
@ -804,6 +914,18 @@ if ($ARGV[0] and $ARGV[0] eq "config") {
|
|||
exit 0;
|
||||
}
|
||||
|
||||
my $recv = 0;
|
||||
my $send = 0,
|
||||
my $recv_if;
|
||||
my $send_if;
|
||||
|
||||
foreach my $if (sort {$a <=> $b} keys %{$snmpinfo}) {
|
||||
do_fetch_if($if);
|
||||
($recv_if, $send_if) = do_fetch_if($if);
|
||||
$recv += ($recv_if || 0);
|
||||
$send += ($send_if || 0);
|
||||
}
|
||||
if ($stackedRoot) {
|
||||
print "multigraph snmp_if_combined\n";
|
||||
print "recv_bits.value $recv\n";
|
||||
print "send_bits.value $send\n";
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue