2
0
mirror of https://github.com/munin-monitoring/contrib.git synced 2018-11-08 00:59:34 +01:00
contrib-munin/plugins/tplink/tl_sg

214 lines
6.4 KiB
Perl
Executable File

#!/usr/bin/perl
# -*- perl -*-
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Magic markers (used by munin-node-configure and some installation scripts):
#%# family=auto
#%# capabilities=autoconf
use strict;
use warnings;
use WWW::Mechanize;
=pod
=encoding UTF-8
=head1 NAME
tl_sg - Plugin to monitor packets per second and link speed for TP-Link SG108E/SG1016E switches
=head1 APPLICABLE SYSTEMS
TP-Link SG108E/SG1016E switches with web management (http). Tested with software version 1.0.2 Build 20160526 Rel.34615 on TL SG108E
=head1 CONFIGURATION
Add this to the relevant munin-node config file. You can specify switch address, username, password and description for each port
(the switch management doesn't allow port descriptions)
[tl_sg]
env.host 192.168.1.12
env.port 80
env.numberOfPorts 8
env.username admin
env.password mySecretPassword
env.p1 'Link to PC1'
env.p2 'Link to server1'
env.p3 'Not used'
env.p4 'Link to AP'
env.p5 'Link to PC2'
env.p6 'Link to PC3'
env.p7 'Not used'
env.p8 'Uplink'
If you're monitoring multiple switches, create different symlinks in /etc/munin/plugins pointing to this plugin and use the symlink
name as a configuration section as described above.
Requires WWW:Mechanize module:
sudo apt-get install libwww-mechanize-perl
=head1 BUGS/GOTCHAS
The link speed is represented as a number:
0 - down
5 - 100Mbps full
6 - 1Gbps
=head1 AUTHOR
Adrian Popa (https://github.com/mad-ady)
=head1 COPYRIGHT
Copyright (c) 2018, Adrian Popa
All rights reserved. This program is free software; you can
redistribute it and/or modify it under the terms of the GNU General
Public License as published by the Free Software Foundation; version 2
dated June, 1991.
=head1 VERSION
1.1
=cut
# read parameters from munin
my $host = ( $ENV{host} || '192.168.1.1' );
my $tcpport = ( $ENV{port} || '80' );
my $username = ( $ENV{username} || 'admin' );
my $password = ( $ENV{password} || 'admin' );
my $numberOfPorts = ( $ENV{numberOfPorts} || '8' );
#populate the ports and descriptions based on ENV
my %ports = ();
for ( 1 .. $numberOfPorts ) {
my $i = $_;
if ( defined $ENV{"p$i"} ) {
$ports{$i} = $ENV{"p$i"};
}
else {
#no description
$ports{$i} = "Port $i";
}
}
if ( $ARGV[0] and $ARGV[0] eq 'autoconf' ) {
print "no (manual configuration needed)\n";
exit 0;
}
if ( $ARGV[0] and $ARGV[0] eq "config" ) {
foreach my $graphType (qw/Packets Speed/) {
foreach my $port ( sort keys %ports ) {
print "multigraph ${graphType}_if_$port\n",
"graph_title $graphType for $host port $port $ports{$port}\n",
"graph_info $graphType graph for port $port $ports{$port}\n",
"graph_args --base 1000 -l 0\n",
"graph_scale yes\n",
"graph_category network\n";
if ( $graphType eq 'Speed' ) {
print "graph_vlabel speed\n";
print "p${port}.label Port $port Link speed\n";
print "p${port}.type GAUGE\n";
}
else {
print "graph_vlabel packets\n";
foreach my $gb (qw/good bad/) {
foreach my $direction (qw/tx rx/) {
print "p${port}${direction}${gb}.label Port $port $direction ($gb)\n";
print "p${port}${direction}${gb}.type COUNTER\n";
}
}
}
}
}
exit 0;
}
# extract data from the switch - uses web scraping (tested with 1.0.2 Build 20160526 Rel.34615)
# print STDERR "Connecting to $host with user $username";
my $mech = WWW::Mechanize->new(
autocheck => 0,
requests_redirectable => [ 'GET', 'HEAD', 'POST' ]
);
my $result = $mech->post(
"http://$host:$tcpport/logon.cgi",
[ username => $username, password => $password, logon => 'Login' ],
"Referer" => "http://$host:$tcpport/"
);
my $response = $mech->response();
# navigate to the page with the network stats
$result = $mech->get("http://$host:$tcpport/PortStatisticsRpm.htm");
$response = $mech->response();
# print STDERR $response->code()."\n";
# get the data
my $data = $mech->content( raw => 1 );
# print STDERR "$data\n";
# The page stores the data in a table, but internally it is stored in 3 javascript arrays:
# state:[1,1,1,1,1,1,1,1,0,0],
# link_status:[0,5,0,0,5,5,5,6,0,0],
# pkts:[0,0,0,0,14141090,0,10461386,0,14226,0,12252,0,0,0,0,0,2872063,0,1402200,0,59764503,0,34619246,0,4913873,0,4393574,0,44170456,0,68499653,0,0,0]
# state: 1 - Enabled, 0 - Disabled (administratively)
# link_status: 0 - down, 5 - 100Mbps full, 6 - 1Gbps
# pkts: every group of 4 values represent txGoodPkt, txBadPkt, rxGoodPkt, rxBadPkt
# parse good/bad packets
if ( $data =~ /pkts:\[([0-9,]+)\]/ ) {
my $packetString = $1;
my @packets = split( /,/, $packetString );
for ( 1 .. $numberOfPorts ) {
my $currentPort = $_;
my $txGoodPkt = $packets[ ( $currentPort - 1 ) * 4 ];
my $txBadPkt = $packets[ ( $currentPort - 1 ) * 4 + 1 ];
my $rxGoodPkt = $packets[ ( $currentPort - 1 ) * 4 + 2 ];
my $rxBadPkt = $packets[ ( $currentPort - 1 ) * 4 + 3 ];
print "multigraph Packets_if_$currentPort\n";
print "p${currentPort}txgood.value $txGoodPkt\n";
print "p${currentPort}rxgood.value $rxGoodPkt\n";
print "p${currentPort}txbad.value $txBadPkt\n";
print "p${currentPort}rxbad.value $rxBadPkt\n";
}
}
# parse link speed
if ( $data =~ /link_status:\[([0-9,]+)\]/ ) {
my $linkString = $1;
my @links = split( /,/, $linkString );
for ( 1 .. $numberOfPorts ) {
my $currentPort = $_;
my $link = $links[ $currentPort - 1 ];
print "multigraph Speed_if_$currentPort\n";
print "p${currentPort}.value $link\n";
}
}
# vim: ft=perl : ts=4 : expandtab