From 2b4deca937d3ec7c9ef44be6b3fce81cf5c88912 Mon Sep 17 00:00:00 2001 From: Thomas Diener Date: Sat, 14 Jan 2012 22:13:30 +0100 Subject: [PATCH 01/76] snmp fortigate plugin: first draft --- plugins/other/snmp__fn | 127 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100755 plugins/other/snmp__fn diff --git a/plugins/other/snmp__fn b/plugins/other/snmp__fn new file mode 100755 index 00000000..dc869c0a --- /dev/null +++ b/plugins/other/snmp__fn @@ -0,0 +1,127 @@ +#!/bin/bash + +#set -x + +### Constants ------------------------------------------------------------------ +SNMPCLIENT=`basename $0 | sed 's/^snmp_//g' | cut -d "_" -f1` +SNMPGET="/usr/bin/snmpget -c $community -v 2c $SNMPCLIENT" + + +### Variables ------------------------------------------------------------------ +fnSysVersion="1.3.6.1.4.1.12356.1.3.0" +FGTcpu="1.3.6.1.4.1.12356.1.8.0" +fnSysVersion="1.3.6.1.4.1.12356.1.3.0" +fnSysMemUsage="1.3.6.1.4.1.12356.1.9.0" +fnSysSesCount="1.3.6.1.4.1.12356.1.10.0" +fnVPNSslStatsLoginUsers="1.3.6.1.4.1.12356.9.5.1.3.1" +fnVPNSslStatsActiveWebSessions="1.3.6.1.4.1.12356.9.5.1.5.1" +fnVPNSslStatsActiveTunnels="1.3.6.1.4.1.12356.9.5.1.7.1" +UNIT=`$SNMPGET $fnSysVersion | cut -d ":" -f4 | cut -d " " -f2 | cut -d "\"" -f2` +SCPU=`$SNMPGET $FGTcpu | cut -d ":" -f4 | cut -d " " -f2` +SMEM=`$SNMPGET $fnSysMemUsage | cut -d ":" -f4 | cut -d " " -f2` +SCNT=`$SNMPGET $fnSysSesCount | cut -d ":" -f4 | cut -d " " -f2` +USER=`$SNMPGET $fnVPNSslStatsLoginUsers | cut -d ":" -f4 | cut -d " " -f2` +WEBS=`$SNMPGET $fnVPNSslStatsActiveWebSessions | cut -d ":" -f4 | cut -d " " -f2` +ATUN=`$SNMPGET $fnVPNSslStatsActiveTunnels | cut -d ":" -f4 | cut -d " " -f2` + + +### Functions ------------------------------------------------------------------ + +autoconf() +{ + if [ $SCPU ]; then + echo yes, OID $FGTcpu can be readed. + else + echo no, one or multiple OID can not be readed. + exit 1 + fi + + if [ $SMEM ]; then + echo yes, OID $fnSysMemUsage can be readed. + else + echo no, one or multiple OID can not be readed. + exit 1 + fi + if [ $SCNT ]; then + echo yes, OID $fnSysSesCount can be read. + else + echo no, one or multiple OID can not be read. + exit 1 + fi +exit 0 +} + +config() +{ + echo "multigraph fn_cpu" + echo "host_name $SNMPCLIENT" + echo "graph_title $UNIT - CPU usage" + echo 'graph_category system' + echo 'graph_vlabel %' + echo 'graph_info This graph shows current CPU usage.' + echo 'graph_args --base 1000 -r --lower-limit 0 --upper-limit 100' + echo 'forticpu.label CPU' + echo 'forticpu.info CPU usage' + echo 'forticpu.draw AREA' + echo '' + + echo "multigraph fn_memory" + echo "host_name $SNMPCLIENT" + echo "graph_title $UNIT - Memory usage" + echo 'graph_category system' + echo 'graph_vlabel %' + echo 'graph_info This graph shows current memory usage.' + echo 'graph_args --base 1000 -r --lower-limit 0 --upper-limit 100' + echo 'fortimemory.label Memory' + echo 'fortimemory.info Memory usage' + echo 'fortimemory.draw AREA' + echo '' + echo "multigraph fn_sessions" + echo "host_name $SNMPCLIENT" + echo "graph_title $UNIT - Sessions" + echo 'graph_category Other' + echo 'graph_vlabel Active Sessions' + echo 'graph_info Active session count on the Fortigate firewall' + echo 'fortisessions.label Sessions' + echo 'fortisessions.info Active session count' + echo 'fortisessions.draw AREA' + echo '' + echo "multigraph fn_vpnsessions" + echo "host_name $SNMPCLIENT" + echo "graph_title $UNIT - SSLvpn Sessions" + echo 'graph_category Other' + echo 'graph_vlabel Sessions/Users' + echo 'graph_info Loged in users with SSLvpn (WebSession or Tunnel-Mode)' + echo 'fortiuser.label Users' + echo 'fortiuser.info Loged in SSLvpn users' + echo 'fortiwebs.label WebSessions' + echo 'fortiwebs.info Active SSLvpn WebSessions' + echo 'fortiatun.label ActiveTunnels' + echo 'fortiatun.info Active SSLvpn Tunnels' + exit 0 +} + +values() +{ +echo "multigraph fn_cpu" +echo "forticpu.value $SCPU" +echo "" +echo "multigraph fn_memory" +echo "fortimemory.value $SMEM" +echo "" +echo "multigraph fn_sessions" +echo "fortisessions.value $SCNT" +echo "" +echo "multigraph fn_vpnsessions" +echo "fortiuser.value $USER" +echo "fortiwebs.value $WEBS" +echo "fortiatun.value $ATUN" +} + +### Main ----------------------------------------------------------------------- + +if [ "$1" = "autoconf" ]; then autoconf +fi +if [ "$1" = "config" ]; then config +fi +values From 0e17b4698209d229fdb57f9d313621b73003affe Mon Sep 17 00:00:00 2001 From: Thomas Diener Date: Sat, 14 Jan 2012 22:35:09 +0100 Subject: [PATCH 02/76] documentation added --- plugins/other/snmp__fn | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/plugins/other/snmp__fn b/plugins/other/snmp__fn index dc869c0a..1cad6bc4 100755 --- a/plugins/other/snmp__fn +++ b/plugins/other/snmp__fn @@ -1,4 +1,38 @@ #!/bin/bash +# +# File: snmp__fn +# Description: SNMP plugin to monitor open sessions, sslvpn, CPU and Memory on a +# Fortigate firewall. +# +# Author: Thom Diener +# License: 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. +# +# Version: v1.00 30.10.2011 First draft of the fortigate plugin +# +# Parameters: config (required) +# autoconf (optional) +# +# Usage: place in /etc/munin/plugins/ (or link it there using ln -s) +# (Example: ln -s /usr/share/munin/plugins/snmp__fn \ +# /etc/munin/plugins/snmp_foo.example.com_fn) +# +# Global community string /etc/munin/plugin-conf.d/munin-node +# [snmp_*] +# env.community private +# timeout 45 # In case low latency or timeout +# +# Fortigate Activate snmp on your Fortigate firewall. Fortigate documentation +# at https://support.fortinet.com +# +# Tested with Fortinet Fortigate-50B, Firmware 3.00(MR6) on Ubuntu 10.04 LTS +# with Munin 1.4.4 installed. +# +#%# family=manual +# + #set -x From 932b38d08698510643590070cbe932debd393475 Mon Sep 17 00:00:00 2001 From: Thomas Diener Date: Sat, 14 Jan 2012 23:07:42 +0100 Subject: [PATCH 03/76] sample images --- images/snmp__fn-cpu.png | Bin 0 -> 16039 bytes images/snmp__fn-memory.png | Bin 0 -> 16135 bytes images/snmp__fn-sessions.png | Bin 0 -> 16407 bytes images/snmp__fn-vpnsessions.png | Bin 0 -> 18150 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/snmp__fn-cpu.png create mode 100644 images/snmp__fn-memory.png create mode 100644 images/snmp__fn-sessions.png create mode 100644 images/snmp__fn-vpnsessions.png diff --git a/images/snmp__fn-cpu.png b/images/snmp__fn-cpu.png new file mode 100644 index 0000000000000000000000000000000000000000..91cdc83516afa1632a11d10e018cf91c1b6e9187 GIT binary patch literal 16039 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 literal 0 HcmV?d00001 diff --git a/images/snmp__fn-memory.png b/images/snmp__fn-memory.png new file mode 100644 index 0000000000000000000000000000000000000000..ab57b1aaf687f421d9f2b43dac66354f27a236c2 GIT binary patch literal 16135 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 Tv;sHVsjkSPWD+mlee!<*^Gp1s literal 0 HcmV?d00001 diff --git a/images/snmp__fn-sessions.png b/images/snmp__fn-sessions.png new file mode 100644 index 0000000000000000000000000000000000000000..24e56dd2a7ca8ad8b6d081dee9ff61540a451e0c GIT binary patch literal 16407 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�xl8cj=dp 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 literal 0 HcmV?d00001 diff --git a/images/snmp__fn-vpnsessions.png b/images/snmp__fn-vpnsessions.png new file mode 100644 index 0000000000000000000000000000000000000000..e98472760388cedd45c7b50363653206adff0812 GIT binary patch literal 18150 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 literal 0 HcmV?d00001 From 5174d082109749825ad87a1fd15e298d58d95b63 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 19 Jan 2012 14:38:28 +0100 Subject: [PATCH 04/76] Initial add of emc_comprehensive --- .../san/emc_comprehensive/emc_comprehensive | 325 ++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100755 plugins/san/emc_comprehensive/emc_comprehensive diff --git a/plugins/san/emc_comprehensive/emc_comprehensive b/plugins/san/emc_comprehensive/emc_comprehensive new file mode 100755 index 00000000..174944aa --- /dev/null +++ b/plugins/san/emc_comprehensive/emc_comprehensive @@ -0,0 +1,325 @@ +#! /usr/bin/perl + +use strict; +use warnings; + +use IO::File; +use Data::Dumper; +use POSIX qw(strftime); + +$ENV{LANG} = "C"; + +my $spool_fetch_epoch = (shift || 0); + +# Don't reply for too old $spool_fetch_epoch) +# Max 7 days +$spool_fetch_epoch = time - 3600 * 24 * 7 if $spool_fetch_epoch < time - 3600 * 24 * 7; + +my $max_epoch = ($ENV{MAX_EPOCH} || 0); +my %fieldset; + +my @files = sort glob($ENV{FILES} || "*.tsv*"); +FILE: for my $file (@files) { + my $values = {}; + my $nb_epochs = 0; my $first_epoch; + + # Read file + { + # Skipping if the file is too old + # (more that one day older than asked) + next if file_mtime($file) < $spool_fetch_epoch - (3600 *24); + + print STDERR "opening $file\n" if $ENV{DEBUG}; + my $fh = new IO::File( ($file =~ m/\.gz$/) ? "gunzip < $file |" : $file); + next unless $fh; + + $_ = <$fh>; chomp; + my @headers = split(/\t/); + + # Ignore 3 first fields (Object Name, Epoch & Owner Array Name) + shift @headers; shift @headers; shift @headers; + + my $nb_headers = $#headers; + LINE: while(<$fh>) { + chomp; + my @row = split(/\t/, $_); + my $object_name = shift @row; + my $epoch = shift @row; + my $owner_array_name = shift @row; + + # Ignore if too old + next if ($epoch <= $spool_fetch_epoch); + + # Don't do too much work : 4h each time is enough + $first_epoch ||= $epoch; + next if $epoch > $first_epoch + 60 * 60 * 4; + + + # Store Values + for (my $idx = 0; $idx < $nb_headers; $idx ++) { + my $value = $row[$idx]; + my $field_name = $headers[$idx]; + + # Ignore empty values + next unless (defined $value && $value ne ""); + + # Ignore non numeric values + next unless $value =~ m/^[0-9.]+$/; + + # Ignore Optimal/NonOptimal valuse + next unless ($fieldset{$field_name} || $field_name !~ /[oO]ptimal/); + $fieldset{$field_name} = 1 unless $fieldset{$field_name}; + + if ($ENV{DEBUG}) { + no warnings; + print "object_name:$object_name, field_name:$field_name, epoch:$epoch, value:$value\n"; + } + + + $values->{$object_name}->{$field_name} .= "$epoch:$value "; + $nb_epochs ++; + } + } + } + + # Don't emit anything if the file didn't contain any useful value + next unless $nb_epochs; + + # Restitution MultiGraph + print <{$object_names->[0]} }; + for my $field (@fields) { + my $graph_name = hash_field_name($field); + print "multigraph san.$category.$graph_name\n"; + print "graph_title $field\n"; + + for my $object_name (@$object_names) { + my $label = &$convert_to_label($object_name); + my $field_name = hash_field_name(&$convert_to_field($object_name)); + print "$field_name.label $label\n"; + print "$field_name.info $object_name\n"; + for my $value (split(/ /, $values->{$object_name}->{$field})) { + print $field_name , ".value " , $value , "\n"; + } + } + } +} + +sub hash_field_name +{ + my $name = shift; + $name = lc($name); + $name =~ s/[^a-z0-9]+/_/g; + $name =~ s/^_//; + $name =~ s/_$//; + return $name; +} + +sub trim +{ + my $line = shift; + $line =~ s/^ +//; + $line =~ s/ +$//; + return $line; +} + +sub file_mtime +{ + my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat(shift); + return $mtime; +} + +__DATA__ + +sb + + +multigraph san.cpu +graph_title Usage CPU +cpu_sp_a.value $epoch:$cpu_sp_a +cpu_sp_b.value $epoch:$cpu_sp_b +multigraph san.resptime +graph_title Response Time +resp_time_a.value $epoch:$resp_time_a +resp_time_b.value $epoch:$resp_time_b +multigraph san.iops +graph_title IOPS +read_io_a.value $epoch:$read_io_a +write_io_a.value $epoch:$write_io_a +read_io_b.value $epoch:$read_io_b +write_io_b.value $epoch:$write_io_b +multigraph san.io +graph_title IO +read_mb_a.value $epoch:$read_mb_a +write_mb_a.value $epoch:$write_mb_a +read_mb_b.value $epoch:$read_mb_b +write_mb_b.value $epoch:$write_mb_b +multigraph san.cache +graph_title Cache +cache_mb_flush_a.value $epoch:$cache_mb_flush_a +write_cache_mb_flush_a.value $epoch:$write_cache_mb_flush_a +cache_mb_flush_b.value $epoch:$cache_mb_flush_b +write_cache_mb_flush_b.value $epoch:$write_cache_mb_flush_b +EOF +; + } +} + +print ".\n"; + +my %MONTHS = get_months(); +sub convert_to_epoch +{ + # converts "05/12/2011 03:57" to EPOCH + my ($date, $time) = split(/ /); + my ($mday, $mon, $year) = split(/\//, $date); + my ($hour, $min, $sec) = split(/:/, $time); + $sec ||= 0; + + use Time::Local; + $mon = $MONTHS{lc($mon)} unless $mon =~ m/\d+/; + my $epoch = timelocal($sec,$min,$hour,$mday,$mon-1,$year); + return $epoch; +} + +sub get_months { + return ( + "jan" => 0, + "fev" => 1, + "mar" => 2, + "apr" => 3, + "may" => 4, + "jun" => 5, + "jul" => 6, + "aug" => 7, + "sep" => 8, + "oct" => 9, + "nov" => 10, + "dec" => 11, + ); +} + +sub trim { + shift; + s/^\s+//; + s/\s+$//; + return $_; +} + +__DATA__ + +05/12/2011 03:57 + + + print <{"SP A"}->{"Utilization (%)"} +cpu_sp_b.value $values->{"SP B"}->{"Utilization (%)"} +multigraph san.bw +graph_title Total Bandwidth (MB/s) +iops_a.label Total Throughput (IO/s) for SP A +iops_b.label Total Throughput (IO/s) for SP B +iops_a.value $values->{"SP A"}->{"Total Throughput (IO/s)"} +iops_b.value $values->{"SP B"}->{"Total Throughput (IO/s)"} +multigraph san.iops +graph_title Total Throughput (IO/s) +iops_a.label Total Throughput (IO/s) for SP A +iops_b.label Total Throughput (IO/s) for SP B +iops_a.value $values->{"SP A"}->{"Total Throughput (IO/s)"} +iops_b.value $values->{"SP B"}->{"Total Throughput (IO/s)"} +EOF +; From 6df2ce234039b907d12459d75436d31bb803d127 Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Sat, 21 Jan 2012 12:44:03 +0100 Subject: [PATCH 05/76] Add a simple graph testing plugin, and use critical instead of alarm --- tools/munin-node-from-hell/README.rst | 4 +-- tools/munin-node-from-hell/basic.conf | 15 +++++++++ .../munin-node-from-hell/muninnode-from-hell | 32 +++++++++++++++++-- tools/munin-node-from-hell/notifications.conf | 2 +- 4 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 tools/munin-node-from-hell/basic.conf diff --git a/tools/munin-node-from-hell/README.rst b/tools/munin-node-from-hell/README.rst index 5731e589..2e7a04aa 100644 --- a/tools/munin-node-from-hell/README.rst +++ b/tools/munin-node-from-hell/README.rst @@ -10,8 +10,8 @@ stuff we do at http://hostedmunin.com/ . Use it as you feel fit :) Current features controlled via config file: * Respond slowly or never to queries. -* Have plugins that always are in warning or alarm. -* Extensive number of plugins. +* Have plugins that always are in warning or critical. +* Extensive number of plugins runnint at once. * Run on multiple ports at the same time, to test huge amounts of clients. diff --git a/tools/munin-node-from-hell/basic.conf b/tools/munin-node-from-hell/basic.conf new file mode 100644 index 00000000..64c83add --- /dev/null +++ b/tools/munin-node-from-hell/basic.conf @@ -0,0 +1,15 @@ +# +# Initialise plugins that test the basic functions of Munin. +# +# + +[instance:basic] +pluginprofile = basic +port = 4000 + +[pluginprofile:basic] +plugins = always_warning, always_critical, graph_area + +[base] +# when building an example config with --muninconf, what hostname to output. +hostname = localhost diff --git a/tools/munin-node-from-hell/muninnode-from-hell b/tools/munin-node-from-hell/muninnode-from-hell index 187c4138..5106a123 100755 --- a/tools/munin-node-from-hell/muninnode-from-hell +++ b/tools/munin-node-from-hell/muninnode-from-hell @@ -91,7 +91,7 @@ class always_warning(MuninPlugin): return """graph_title Always in warning graph_vlabel Level graph_scale no -graph_info A simple graph that is always in warning or alarm +graph_info A simple graph that is always in warning or critical graph_category active_notification generic.label Level generic.info Level usually above warning level @@ -99,10 +99,36 @@ generic.warn 5 generic.crit 10""" modules["always_warning"] = always_warning() -class always_alarm(always_warning): +class always_critical(always_warning): def fetch(self, conf): return "generic.value 20" -modules["always_alarm"] = always_alarm() +modules["always_critical"] = always_critical() + +class graph_area(MuninPlugin): + "A plugin that uses STACK and AREA. From proc_pri. Use: testing the grapher" + def fetch(self, conf): + return """high.value 3 + low.value 2 + locked.value 1""" + + def config(self, conf): + return """graph_title AREA and STACK +graph_order low high locked +graph_category graphtes t +graph_info This graph shows nuber of processes at each priority +graph_args --base 1000 -l 0 +graph_vlabel Number of processes +high.label high priority +high.draw STACK +high.info The number of high-priority processes (tasks) +low.label low priority +low.draw AREA +low.info The number of low-priority processes (tasks) +locked.label locked in memory +locked.draw STACK +locked.info The number of processes that have pages locked into memory (for real-time and custom IO) +""" +modules["graph_area"] = graph_area() class ArgumentTCPserver(SocketServer.ThreadingTCPServer): diff --git a/tools/munin-node-from-hell/notifications.conf b/tools/munin-node-from-hell/notifications.conf index 5a7b2c91..61f05118 100644 --- a/tools/munin-node-from-hell/notifications.conf +++ b/tools/munin-node-from-hell/notifications.conf @@ -12,7 +12,7 @@ port = 3000 #port = 4940 #sleepyness = 30 [pluginprofile:notif] -plugins = always_warning, always_alarm +plugins = always_warning, always_critical [base] # when building an example config with --muninconf, what hostname to output. From 071b1cace3495654a46e964784f6b3ec8ff154ab Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Sat, 21 Jan 2012 13:22:30 +0100 Subject: [PATCH 06/76] clean up alarm plugins, fix typo in graphtest --- .../munin-node-from-hell/muninnode-from-hell | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/tools/munin-node-from-hell/muninnode-from-hell b/tools/munin-node-from-hell/muninnode-from-hell index 5106a123..83a725e6 100755 --- a/tools/munin-node-from-hell/muninnode-from-hell +++ b/tools/munin-node-from-hell/muninnode-from-hell @@ -84,37 +84,42 @@ class tarpit(MuninPlugin): modules["tarpit"] = tarpit() class always_warning(MuninPlugin): + conftext = """graph_title Always in LEVEL +graph_vlabel Level +graph_scale no +graph_info A simple graph that is always in LEVEL +graph_category active_notification +generic.label Level +generic.info Level usually above warning level +generic.warning 5 +generic.critical 10""" + def fetch(self, conf): return "generic.value 10" def config(self, conf): - return """graph_title Always in warning -graph_vlabel Level -graph_scale no -graph_info A simple graph that is always in warning or critical -graph_category active_notification -generic.label Level -generic.info Level usually above warning level -generic.warn 5 -generic.crit 10""" + return self.conftext.replace("LEVEL","warning") modules["always_warning"] = always_warning() class always_critical(always_warning): def fetch(self, conf): return "generic.value 20" + + def config(self, conf): + return self.conftext.replace("LEVEL","critical") modules["always_critical"] = always_critical() class graph_area(MuninPlugin): "A plugin that uses STACK and AREA. From proc_pri. Use: testing the grapher" def fetch(self, conf): return """high.value 3 - low.value 2 - locked.value 1""" +low.value 2 +locked.value 1""" def config(self, conf): return """graph_title AREA and STACK graph_order low high locked -graph_category graphtes t +graph_category graphtest graph_info This graph shows nuber of processes at each priority graph_args --base 1000 -l 0 graph_vlabel Number of processes From 851979ebad828989b61a3a488a326337deda4c7b Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Sat, 21 Jan 2012 14:14:44 +0100 Subject: [PATCH 07/76] use a different category for always_XX --- tools/munin-node-from-hell/muninnode-from-hell | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-node-from-hell/muninnode-from-hell b/tools/munin-node-from-hell/muninnode-from-hell index 83a725e6..06f0ef60 100755 --- a/tools/munin-node-from-hell/muninnode-from-hell +++ b/tools/munin-node-from-hell/muninnode-from-hell @@ -88,7 +88,7 @@ class always_warning(MuninPlugin): graph_vlabel Level graph_scale no graph_info A simple graph that is always in LEVEL -graph_category active_notification +graph_category always_LEVEL generic.label Level generic.info Level usually above warning level generic.warning 5 From db72714eb4c50835f0ffcce813d19b3c234c1ca5 Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Sat, 21 Jan 2012 20:42:53 +0100 Subject: [PATCH 08/76] rename dses to easier check correct graphing --- .../munin-node-from-hell/muninnode-from-hell | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/munin-node-from-hell/muninnode-from-hell b/tools/munin-node-from-hell/muninnode-from-hell index 06f0ef60..b7130742 100755 --- a/tools/munin-node-from-hell/muninnode-from-hell +++ b/tools/munin-node-from-hell/muninnode-from-hell @@ -112,26 +112,26 @@ modules["always_critical"] = always_critical() class graph_area(MuninPlugin): "A plugin that uses STACK and AREA. From proc_pri. Use: testing the grapher" def fetch(self, conf): - return """high.value 3 -low.value 2 -locked.value 1""" + return """first.value 3 +second.value 2 +third.value 1""" def config(self, conf): return """graph_title AREA and STACK -graph_order low high locked +graph_order first second third graph_category graphtest graph_info This graph shows nuber of processes at each priority graph_args --base 1000 -l 0 graph_vlabel Number of processes -high.label high priority -high.draw STACK -high.info The number of high-priority processes (tasks) -low.label low priority -low.draw AREA -low.info The number of low-priority processes (tasks) -locked.label locked in memory -locked.draw STACK -locked.info The number of processes that have pages locked into memory (for real-time and custom IO) +first.label first +first.draw STACK +first.info The number of first-priority processes (tasks) +second.label second +second.draw AREA +second.info The number of second-priority processes (tasks) +third.label third +third.draw STACK +third.info The number of processes that have pages third into memory (for real-time and custom IO) """ modules["graph_area"] = graph_area() From 1c70bc928e088c7cc2cb13fe8502f20b11f32c5a Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Sat, 21 Jan 2012 20:51:40 +0100 Subject: [PATCH 09/76] Revert "rename dses to easier check correct graphing" Really, not a good idea. This reverts commit db72714eb4c50835f0ffcce813d19b3c234c1ca5. --- .../munin-node-from-hell/muninnode-from-hell | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/munin-node-from-hell/muninnode-from-hell b/tools/munin-node-from-hell/muninnode-from-hell index b7130742..06f0ef60 100755 --- a/tools/munin-node-from-hell/muninnode-from-hell +++ b/tools/munin-node-from-hell/muninnode-from-hell @@ -112,26 +112,26 @@ modules["always_critical"] = always_critical() class graph_area(MuninPlugin): "A plugin that uses STACK and AREA. From proc_pri. Use: testing the grapher" def fetch(self, conf): - return """first.value 3 -second.value 2 -third.value 1""" + return """high.value 3 +low.value 2 +locked.value 1""" def config(self, conf): return """graph_title AREA and STACK -graph_order first second third +graph_order low high locked graph_category graphtest graph_info This graph shows nuber of processes at each priority graph_args --base 1000 -l 0 graph_vlabel Number of processes -first.label first -first.draw STACK -first.info The number of first-priority processes (tasks) -second.label second -second.draw AREA -second.info The number of second-priority processes (tasks) -third.label third -third.draw STACK -third.info The number of processes that have pages third into memory (for real-time and custom IO) +high.label high priority +high.draw STACK +high.info The number of high-priority processes (tasks) +low.label low priority +low.draw AREA +low.info The number of low-priority processes (tasks) +locked.label locked in memory +locked.draw STACK +locked.info The number of processes that have pages locked into memory (for real-time and custom IO) """ modules["graph_area"] = graph_area() From ce8b1121ec331708bc5307d44395faead0c608af Mon Sep 17 00:00:00 2001 From: Thomas Diener Date: Sun, 22 Jan 2012 21:44:37 +0100 Subject: [PATCH 10/76] OID to MIB changed --- plugins/other/snmp__fn | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/plugins/other/snmp__fn b/plugins/other/snmp__fn index 1cad6bc4..5b3b9dd3 100755 --- a/plugins/other/snmp__fn +++ b/plugins/other/snmp__fn @@ -11,6 +11,7 @@ # June, 1991. # # Version: v1.00 30.10.2011 First draft of the fortigate plugin +# v1.01 19.01.2012 OID to MIB changed, plugins gets faster # # Parameters: config (required) # autoconf (optional) @@ -27,6 +28,10 @@ # Fortigate Activate snmp on your Fortigate firewall. Fortigate documentation # at https://support.fortinet.com # +# MIB Download and copy the Fortigate MIB defintion file to +# /usr/share/snmp/mibs/FORTINET-300-MIB.txt (Filename depends on +# used Version) +# # Tested with Fortinet Fortigate-50B, Firmware 3.00(MR6) on Ubuntu 10.04 LTS # with Munin 1.4.4 installed. # @@ -38,18 +43,22 @@ ### Constants ------------------------------------------------------------------ SNMPCLIENT=`basename $0 | sed 's/^snmp_//g' | cut -d "_" -f1` -SNMPGET="/usr/bin/snmpget -c $community -v 2c $SNMPCLIENT" +MIBFILE="/usr/share/snmp/mibs/FORTINET-300-MIB.20080414.txt" +FNTYPE=`echo $MIBFILE | cut -d "." -f1 | cut -d "/" -f6` +SNMPGET="/usr/bin/snmpget -m $MIBFILE -c $community -v 2c $SNMPCLIENT" ### Variables ------------------------------------------------------------------ fnSysVersion="1.3.6.1.4.1.12356.1.3.0" -FGTcpu="1.3.6.1.4.1.12356.1.8.0" -fnSysVersion="1.3.6.1.4.1.12356.1.3.0" -fnSysMemUsage="1.3.6.1.4.1.12356.1.9.0" -fnSysSesCount="1.3.6.1.4.1.12356.1.10.0" -fnVPNSslStatsLoginUsers="1.3.6.1.4.1.12356.9.5.1.3.1" -fnVPNSslStatsActiveWebSessions="1.3.6.1.4.1.12356.9.5.1.5.1" -fnVPNSslStatsActiveTunnels="1.3.6.1.4.1.12356.9.5.1.7.1" +FGTcpu="$FNTYPE::fnSysCpuUsage.0" +fnSysVersion="$FNTYPE::fnSysVersion.0" +fnSysMemUsage="$FNTYPE::fnSysMemUsage.0" +fnSysSesCount="$FNTYPE::fnSysSesCount.0" +fnVPNSslStatsLoginUsers="$FNTYPE::fnVpnSslStatsLoginUsers.1" +fnVPNSslStatsActiveWebSessions="$FNTYPE::fnVpnSslStatsActiveWebSessions.1" +fnVPNSslStatsActiveTunnels="$FNTYPE::fnVpnSslStatsActiveTunnels.1" +mibfile="/usr/share/snmp/mibs/FORTINET-300-MIB.20080414.txt" + UNIT=`$SNMPGET $fnSysVersion | cut -d ":" -f4 | cut -d " " -f2 | cut -d "\"" -f2` SCPU=`$SNMPGET $FGTcpu | cut -d ":" -f4 | cut -d " " -f2` SMEM=`$SNMPGET $fnSysMemUsage | cut -d ":" -f4 | cut -d " " -f2` From 6db166599184da8c7b7f500118067fb1d6a34514 Mon Sep 17 00:00:00 2001 From: Thomas Diener Date: Wed, 25 Jan 2012 16:59:33 +0100 Subject: [PATCH 11/76] MIB file availability check added --- plugins/other/snmp__fn | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/plugins/other/snmp__fn b/plugins/other/snmp__fn index 5b3b9dd3..b481995a 100755 --- a/plugins/other/snmp__fn +++ b/plugins/other/snmp__fn @@ -12,6 +12,7 @@ # # Version: v1.00 30.10.2011 First draft of the fortigate plugin # v1.01 19.01.2012 OID to MIB changed, plugins gets faster +# v1.02 25.01.2012 MIB file availability check added # # Parameters: config (required) # autoconf (optional) @@ -28,7 +29,7 @@ # Fortigate Activate snmp on your Fortigate firewall. Fortigate documentation # at https://support.fortinet.com # -# MIB Download and copy the Fortigate MIB defintion file to +# MIB Download and copy the original Fortigate MIB defintion file to # /usr/share/snmp/mibs/FORTINET-300-MIB.txt (Filename depends on # used Version) # @@ -45,8 +46,12 @@ SNMPCLIENT=`basename $0 | sed 's/^snmp_//g' | cut -d "_" -f1` MIBFILE="/usr/share/snmp/mibs/FORTINET-300-MIB.20080414.txt" FNTYPE=`echo $MIBFILE | cut -d "." -f1 | cut -d "/" -f6` -SNMPGET="/usr/bin/snmpget -m $MIBFILE -c $community -v 2c $SNMPCLIENT" - +if [ -r $MIBFILE ]; then + SNMPGET="/usr/bin/snmpget -m $MIBFILE -c $community -v 2c $SNMPCLIENT" +else + echo no, MIB definition file not available or readable. + exit 1 +fi ### Variables ------------------------------------------------------------------ fnSysVersion="1.3.6.1.4.1.12356.1.3.0" @@ -57,10 +62,9 @@ fnSysSesCount="$FNTYPE::fnSysSesCount.0" fnVPNSslStatsLoginUsers="$FNTYPE::fnVpnSslStatsLoginUsers.1" fnVPNSslStatsActiveWebSessions="$FNTYPE::fnVpnSslStatsActiveWebSessions.1" fnVPNSslStatsActiveTunnels="$FNTYPE::fnVpnSslStatsActiveTunnels.1" -mibfile="/usr/share/snmp/mibs/FORTINET-300-MIB.20080414.txt" -UNIT=`$SNMPGET $fnSysVersion | cut -d ":" -f4 | cut -d " " -f2 | cut -d "\"" -f2` -SCPU=`$SNMPGET $FGTcpu | cut -d ":" -f4 | cut -d " " -f2` +UNIT=`$SNMPGET $fnSysVersion | cut -d ":" -f4 | cut -d " " -f2 | cut -d "\"" -f2` +SCPU=`$SNMPGET $FGTcpu | cut -d ":" -f4 | cut -d " " -f2` SMEM=`$SNMPGET $fnSysMemUsage | cut -d ":" -f4 | cut -d " " -f2` SCNT=`$SNMPGET $fnSysSesCount | cut -d ":" -f4 | cut -d " " -f2` USER=`$SNMPGET $fnVPNSslStatsLoginUsers | cut -d ":" -f4 | cut -d " " -f2` @@ -86,7 +90,7 @@ autoconf() exit 1 fi if [ $SCNT ]; then - echo yes, OID $fnSysSesCount can be read. + echo yes, OID $fnSysSesCount can be readed. else echo no, one or multiple OID can not be read. exit 1 @@ -107,7 +111,6 @@ config() echo 'forticpu.info CPU usage' echo 'forticpu.draw AREA' echo '' - echo "multigraph fn_memory" echo "host_name $SNMPCLIENT" echo "graph_title $UNIT - Memory usage" From 8497d32ae65cb8c7b793957b2a852fbe2d2d3d17 Mon Sep 17 00:00:00 2001 From: Thomas Diener Date: Fri, 27 Jan 2012 14:17:37 +0100 Subject: [PATCH 12/76] new sample image for session graph --- images/snmp__fn-sessions.png | Bin 16407 -> 19376 bytes 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 images/snmp__fn-sessions.png diff --git a/images/snmp__fn-sessions.png b/images/snmp__fn-sessions.png old mode 100644 new mode 100755 index 24e56dd2a7ca8ad8b6d081dee9ff61540a451e0c..0f113036ab576b106de3ff042667f6616ce79aa6 GIT binary patch literal 19376 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�xl8cj=dp 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 From f6330cbd5f75cf8ef96ddeb0f15eacff897ef615 Mon Sep 17 00:00:00 2001 From: Thomas Diener Date: Fri, 27 Jan 2012 14:25:57 +0100 Subject: [PATCH 13/76] new sample image --- images/snmp__fn-cpu.png | Bin 16039 -> 16093 bytes images/snmp__fn-memory.png | Bin 16135 -> 15698 bytes images/snmp__fn-sessions.png | Bin 19376 -> 18473 bytes images/snmp__fn-vpnsessions.png | Bin 18150 -> 18958 bytes 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 images/snmp__fn-cpu.png mode change 100644 => 100755 images/snmp__fn-memory.png mode change 100644 => 100755 images/snmp__fn-vpnsessions.png diff --git a/images/snmp__fn-cpu.png b/images/snmp__fn-cpu.png old mode 100644 new mode 100755 index 91cdc83516afa1632a11d10e018cf91c1b6e9187..a2f50b0d4065675105af49a4b378c852e30d72f0 GIT binary patch literal 16093 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 literal 16039 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 diff --git a/images/snmp__fn-memory.png b/images/snmp__fn-memory.png old mode 100644 new mode 100755 index ab57b1aaf687f421d9f2b43dac66354f27a236c2..198465835c302a3c9958895168ed9c8370c5cbc1 GIT binary patch literal 15698 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 JDbl)+{vQDb81VoA literal 16135 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 Tv;sHVsjkSPWD+mlee!<*^Gp1s diff --git a/images/snmp__fn-sessions.png b/images/snmp__fn-sessions.png index 0f113036ab576b106de3ff042667f6616ce79aa6..e6a6153e4716171440147356ed01f24089e1b3f6 100755 GIT binary patch literal 18473 zcma*P2RzmN`#*lPh!P29CPlK6k*yROq9|mKGPCzQDza(G$S5kCWbe`8BrDmQgO1I~ zIQIEp@4CPD_x^nDzK`GkQ9V35&Un9Huh;dwuIu@HUMJ|Liqb(!CQ1|vb@1wy%W5bT z83F#$QS5_9xGLqA;m1DX>q?hVB;?PVij)^9)N$0+%NK9E#m&XLdmWkB#>!on7T5j4 zO2Kilmi5BHCzdp1*N+ExrN7zYW0I%ZMW(>F>u~VIPZVvaG&4lNaTGZtiv|>uqXkDagxfz;Am@MBX!%UGgI4mP|oAyel+rd=gyotV>jKwGcd08E!RZJp#Bo_oS00#G6qz15S=^) z#}1{GJ^a9^8gZ+@@78$EyAQ!DDL52ATC{W3Of)n!JZg-Ar!t9XWOU{bRhby!p(`pX z^-no2#gVSpsKiAxB^=-0U8(9fi7l||wwvt{(&A&#Eq9|OBO^=d|3t@~o~xa;;*&q$ z%33ydwU8>O8GLExwFO?iU-4$dhI?FZ}6L!ubBLp?ak}SH6a%;s0`Jw@Gxpk zkTLJhj-Om*q2rD<&*ZjE>)uY0+ujeam3MIwLyc%wZP07v=!d<0`O;&fuTNXI*p93* zN)Y?y87E<`XgEEb=hUgaMZ-Q)m0LfrUsh0fo0)k)%4N2i*|z*4+3tO*LxLO_aY`zx zwlY`S{0F^wL?x%Mx8|CHF((B_d%m+(F^_0T#p3XbWZU7&wN~^FX9jBlT*%**Ai^#l8w53>+LBH6~?h1CFgS$ab#I4~BgGdacGM z&#%Ih_*EMp97o*gx2>vs#jo=;F)>1k&3#X+9H|`V^75l2UIo^MJb;?Dc6|vSPf(7R zq|d3^k+ih5jO(x5*_eqwYxHO&$Z39{q}XnB7d5M--$Lak^|05{jrbKc?3?d}SH|wO zf4K2T&RC1((1p?bjLSS~COz>|uJ!d{%(TqRR48%xpC_MCvj&@B!zBu^5$rjR8DA_5 zx@M~NqMWC`?|psVR&jH6jtrHe5?{;eI>6C4Wl-sL41()Rb2I%QT344v>_LyOO1vZ) zDmWy>exZVRf}0yVHdEy?#}v*c6Kv7`;jLL~g4^~=HyJ8RyFmW#-D9yLB|c%g>gtb2 zMhss@MTKlI96cJCQ@KGoSn9mglYNw)o?ffmO$ZKKAnXww$kAs?Y&Eb)G)Iq~o>_63 z={op=Tebf4A-T{(>;A6Zst!p_+lg|bSxel-n>T5EXBO1^3$1TyX#B`!71hepV3BsC zfzyXVjgOBTPJVm4HX6W=LhasnpxSRg-QxHQRmtwT;VSm#*XMJJas>2B4ae%kTD;?> z-4DACI!Dc#+`Ovu&R$(dCj_3sDIsy}wU~9f=KB^4%^(5sb2`KWMa9KEy}i3Gz(U>9 z)zwv+vB<>6CnY6G?qzFhYjf^efIWo6stBh)Q-k-!i4!-~)J~MBzHWZ9w&sSnUWHi3 z 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 ALjV8( literal 19376 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 From 8051623fe4a7c8566fe94aca87302f32024dcb67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Gross?= Date: Fri, 27 Jan 2012 17:07:41 +0100 Subject: [PATCH 14/76] Fix lvdisplay path on some hosts. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sébastien Gross --- plugins/other/lvm_snap_used | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/plugins/other/lvm_snap_used b/plugins/other/lvm_snap_used index cfcdc241..87574a24 100755 --- a/plugins/other/lvm_snap_used +++ b/plugins/other/lvm_snap_used @@ -14,17 +14,19 @@ #%# capabilities=autoconf # # 2011/05/20 - pmoranga - initial version +# +# 2012/01/27 - Sébastien Gross +# - Fix lvdisplay path + +lvdisplay=$(which lvdisplay) if [ "$1" = "autoconf" ]; then - /usr/sbin/lvdisplay 2>/dev/null >/dev/null - if [ $? -eq 0 ] - then - echo yes - exit 0 - else - echo "no lvdisplay found" - fi - exit 1 + if test -n "${lvdisplay}"; then + echo yes + exit 0 + fi + echo "no lvdisplay found" + exit 1 fi @@ -34,9 +36,9 @@ if [ "$1" = "config" ]; then echo 'graph_vlabel %' echo 'graph_category disk' echo 'graph_args --base 100' - /usr/sbin/lvdisplay -C | awk '$3 ~ /^s/{print $1".label "$1" snapshot of "$5} ' + ${lvdisplay} -C | awk '$3 ~ /^s/{print $1".label "$1" snapshot of "$5} ' exit 0 fi -/usr/sbin/lvdisplay -C | awk '$3 ~ /^s/{print $1".value",int($6)} ' +${lvdisplay} -C | awk '$3 ~ /^s/{print $1".value",int($6)} ' From 8ea0ef824838ed8b6c0eb37c028dd5888f7d507d Mon Sep 17 00:00:00 2001 From: Kenyon Ralph Date: Thu, 2 Feb 2012 04:18:02 -0800 Subject: [PATCH 15/76] make the graphs more like the if_ plugin Show traffic in bits instead of bytes, use negative values for incoming traffic, improve wording, simplify authentication, add documentation. --- plugins/other/tor-bandwidth-usage | 181 +++++++++++++++--------------- 1 file changed, 90 insertions(+), 91 deletions(-) diff --git a/plugins/other/tor-bandwidth-usage b/plugins/other/tor-bandwidth-usage index 26a5f070..316d57ca 100755 --- a/plugins/other/tor-bandwidth-usage +++ b/plugins/other/tor-bandwidth-usage @@ -1,6 +1,6 @@ #!/usr/bin/perl -w # -# tor_bandwidth_acct - munin plugin to monitor Tor routers traffic +# tor-bandwidth-usage - munin plugin to monitor Tor traffic # # To use this plugin you need the following: # o Enable accounting on torrc configuration file (even if you dont want to limit bandwidth usage, @@ -9,145 +9,144 @@ # AccountingStart day 12:00 # AccountingMax 100 GB # o Enable CookieAuthentication (CookieAuthentication 1 in torrc) or define a HashedControlPassword +# o Add something like the following to /etc/munin/plugin-conf.d/munin-node: +# [tor-bandwidth-usage] +# user debian-tor +# env.cookiefile /var/run/tor/control.authcookie # -# tested with Tor releases: 0.2.1.28, 0.2.1.29 # -# Author: tazoi , based on a plugin by Ævar Arnfjörð Bjarmason , based on a plugin by Ævar Arnfjörð Bjarmason # # Parameters understood (defined in file /etc/munin/plugin-conf.d/munin-node or in environment) -# host - Change which host to graph (default localhost) -# port - Change which port to connect to (default 9051) +# host - Change which host to graph (default localhost) +# port - Change which port to connect to (default 9051) # password - Plain-text control channel password (see torrc -# HashedControlPassword parameter) +# HashedControlPassword parameter) # cookiefile - Name of the file containing the control channel cookie -# (see torrc CookieAuthentication parameter) +# (see torrc CookieAuthentication parameter) # -# Using HashedControlPassword authentication has the problem that you must -# include the plain-text password in the munin config file. To have any -# effect, that file shouldn't be world-readable. -# If you're using CookieAuthentication, you should run this plugin as a user -# which has read access to the tor datafiles. Also note that bugs in versions -# upto and including 0.1.1.20 prevent CookieAuthentication from working. +# Using HashedControlPassword authentication has the problem that you +# must include the plain-text password in the munin config file. To +# have any effect, that file shouldn't be world-readable. # -# Usage: place in /etc/munin/node.d/ or in /etc/munin/plugins (or link it there using ln -s) +# If you're using CookieAuthentication, you should run this plugin as +# a user which has read access to the tor datafiles. Also note that +# bugs in versions upto and including 0.1.1.20 prevent +# CookieAuthentication from working. # -# Parameters understood: -# config (required) -# autoconf (optional - used by munin-config) -# -# todo: -# try using "graph_period" option "to make graph_sums usable" -# -# Magic markers - optional - used by installation scripts and -# munin-config: +# Usage: place in /etc/munin/plugins (or link it there using ln -s) # #%# family=contrib #%# capabilities=autoconf use strict; +use feature ':5.10'; use IO::Socket::INET; +use Munin::Plugin; # Config -our $address = $ENV{host} || "localhost"; # Default: localhost -our $port = $ENV{port} || 9051; # Default: 9051 +my $address = $ENV{host} || "localhost"; +my $port = $ENV{port} || 9051; # Don't edit below this line sub Authenticate { - my ($socket) = @_; - my $authline = "AUTHENTICATE"; - if (defined($ENV{cookiefile})) { - if (open(COOKIE, "<$ENV{cookiefile}")) { - binmode COOKIE; - my $cookie; - $authline .= " "; - while (read(COOKIE, $cookie, 32)) { - foreach my $byte (unpack "C*", $cookie) { - $authline .= sprintf "%02x", $byte; - } - } - close COOKIE; - } - } elsif (defined($ENV{password})) { - $authline .= ' "' . $ENV{password} . '"'; - } - print $socket "$authline\r\n"; - my $replyline = <$socket>; - if (substr($replyline, 0, 1) != '2') { - $replyline =~ s/\s*$//; - return "Failed to authenticate: $replyline"; - } + my ($socket) = @_; + my $authline = "AUTHENTICATE"; + if (defined($ENV{cookiefile})) { + if (open(COOKIE, "<$ENV{cookiefile}")) { + my $cookie; + binmode COOKIE; + read(COOKIE, $cookie, 32); + close COOKIE; + $authline .= ' "' . $cookie . '"'; + } + } elsif (defined($ENV{password})) { + $authline .= ' "' . $ENV{password} . '"'; + } + say $socket "$authline"; + my $replyline = <$socket>; + if (substr($replyline, 0, 1) != '2') { + $replyline =~ s/\s*$//; + return "Failed to authenticate: $replyline"; + } - return; + return; } if ($ARGV[0] and $ARGV[0] eq "autoconf") { - # Try to connect to the daemon - my $socket = IO::Socket::INET->new("$address:$port") - or my $failed = 1; + # Try to connect to the daemon + my $socket = IO::Socket::INET->new("$address:$port") or my $failed = 1; - if ($failed) { - print "no (failed to connect to $address port $port)\n"; - exit 1; - } + if ($failed) { + say "no (failed to connect to $address port $port)"; + exit 1; + } - my $msg = Authenticate($socket); - if (defined($msg)) { - print $socket "QUIT\r\n"; - close($socket); - print "no ($msg)\n"; - exit 1; - } + my $msg = Authenticate($socket); + if (defined($msg)) { + say $socket "QUIT"; + close($socket); + say "no ($msg)"; + exit 1; + } - print $socket "QUIT\r\n"; - close($socket); - print "yes\n"; - exit 0; + say $socket "QUIT"; + close($socket); + say "yes"; + exit 0; } if ($ARGV[0] and $ARGV[0] eq "config") { - print "graph_title Tor bandwidth usage (in/out)\n"; - print "graph_args --base 1000\n"; - print "graph_vlabel bytes/sec\n"; - print "graph_category Tor\n"; - print "graph_info This graph shows the flowing incoming/outgoing bytes on a Tor node\n"; - print "down.label Download\n"; - print "down.type DERIVE\n"; - print "down.min 0\n"; - print "up.label Upload\n"; - print "up.type DERIVE\n"; - print "up.min 0\n"; + say "graph_order down up"; + say "graph_title Tor traffic"; + say "graph_args --base 1000"; + say "graph_vlabel bits in (-) / out (+) per \${graph_period}"; + say "graph_category network"; + say "graph_info This graph shows the traffic through this Tor node."; + say "down.label received"; + say "down.type DERIVE"; + say 'down.graph no'; + say "down.cdef down,8,*"; + say "down.min 0"; + say "up.label b/s"; + say "up.type DERIVE"; + say "up.negative down"; + say "up.cdef up,8,*"; + say "up.min 0"; - exit 0; + exit 0; } my $socket = IO::Socket::INET->new("$address:$port") - or die("Couldn't connect to $address port $port: $!"); + or die("Couldn't connect to $address port $port: $!"); my $msg = Authenticate($socket); if (defined($msg)) { - print $socket "QUIT\r\n"; - close($socket); - die "$msg\n"; + say $socket "QUIT"; + close($socket); + die "$msg\n"; } -print $socket "GETINFO accounting/bytes\r\n"; +say $socket "GETINFO accounting/bytes"; my $down = 0; my $up = 0; my $replyline = <$socket>; chomp($replyline); -if ( $replyline =~ /^250-accounting\/bytes=(\d+)\s(\d+)\r$/ ) { - $down = $1; - $up = $2; +if ($replyline =~ /^250-accounting\/bytes=(\d+)\s(\d+)/) { + $down = $1; + $up = $2; } else { - die "Failed to get accounting info: $replyline\n"; + die "Failed to get accounting info: $replyline\n"; } -print $socket "QUIT\r\n"; +say $socket "QUIT"; close($socket); -print "down.value $down\n"; -print "up.value $up\n"; +say "down.value $down"; +say "up.value $up"; exit 0; From e215f1569918fab16701146d123b6e27424bac4c Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Sat, 4 Feb 2012 16:50:48 +0100 Subject: [PATCH 16/76] fix typos --- tools/munin-node-from-hell/README.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/munin-node-from-hell/README.rst b/tools/munin-node-from-hell/README.rst index 2e7a04aa..9cc61d74 100644 --- a/tools/munin-node-from-hell/README.rst +++ b/tools/munin-node-from-hell/README.rst @@ -11,7 +11,7 @@ Current features controlled via config file: * Respond slowly or never to queries. * Have plugins that always are in warning or critical. -* Extensive number of plugins runnint at once. +* Extensive number of plugins running at once. * Run on multiple ports at the same time, to test huge amounts of clients. @@ -21,8 +21,8 @@ Usage munin-node-from-hell takes two arguments; the mode and which config file to use. Mode is either --run or --muninconf. -This software is meant to run as an ordinary unix user, please don't run -it as root without some thought. +This software is meant to run as an ordinary Unix user, please don't run +it as root. You probably want: From 3b485e4546a650f0e2869a685177f43b45295081 Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Sat, 4 Feb 2012 18:56:29 +0100 Subject: [PATCH 17/76] moar plugins --- tools/munin-node-from-hell/tarpit.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-node-from-hell/tarpit.conf b/tools/munin-node-from-hell/tarpit.conf index 3a0995de..ecc6cc29 100644 --- a/tools/munin-node-from-hell/tarpit.conf +++ b/tools/munin-node-from-hell/tarpit.conf @@ -6,7 +6,7 @@ pluginprofile = tarpit port = 3000 [pluginprofile:tarpit] -plugins = tarpit, load, locks +plugins = load, locks, tarpit, load, locks [pluginprofile:base] plugins = load, locks, locks, load, load, locks, locks, load, load, load From 9694ad80283ad10a16f24b41de94f3282b7e96b7 Mon Sep 17 00:00:00 2001 From: Alejandro Olivan Alvarez Date: Mon, 6 Feb 2012 16:36:30 +0100 Subject: [PATCH 18/76] - new plugin for shoutcast v2 --- plugins/other/shoutcast2 | 158 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100755 plugins/other/shoutcast2 diff --git a/plugins/other/shoutcast2 b/plugins/other/shoutcast2 new file mode 100755 index 00000000..5e0ed963 --- /dev/null +++ b/plugins/other/shoutcast2 @@ -0,0 +1,158 @@ +#!/usr/bin/php + (string)$xml->CURRENTLISTENERS, + 'PEAKLISTENERS' => (string)$xml->PEAKLISTENERS, + 'MAXLISTENERS' => (string)$xml->MAXLISTENERS, + 'UNIQUELISTENERS' => (string)$xml->UNIQUELISTENERS, + ); + + // this is the usual case, generating a label and value + echo("max_connections.value {$dnas_data['MAXLISTENERS']}\n"); + echo("ax_used_connections.value {$dnas_data['PEAKLISTENERS']}\n"); + echo("all_connections.value {$dnas_data['CURRENTLISTENERS']}\n"); + echo("unique_connections.value {$dnas_data['UNIQUELISTENERS']}\n"); + + +} +else +{ + $dnas_data = array('ERROR' => 'Could not connect to dnas-server!'); + echo("\n"); +} + + + +// this is for munin's configuration tool +// could do something more complicated here +if(count($argv) == 2 && $arv[1] == 'authconf') { + exit('yes'); +} + + + +// this is for rrdtool to know how to label the graph + + // Default Settings +if(count($argv) == 2 && $argv[1] == 'config') { + echo("graph_title SHOUTcast Online on GlobalMobile port 8026\n"); + echo("graph_args --base 1000\n"); + echo("graph_category shoutcast\n"); + echo("graph_vlabel Connections per \${graph_period}\n"); + + // Max Listeners Allowed to Connect to Server + echo("max_connections.draw AREA\n\n"); + echo("max_connections.colour cdcfc4\n"); + echo("max_connections.min 0\n"); + echo("max_connections.label Max Slots\n"); + echo("max_connections.type GAUGE\n"); + + // Peak Listeners + echo("ax_used_connections.draw AREA\n"); + echo("ax_used_connections.colour ffd660\n"); + echo("ax_used_connections.min 0\n"); + echo("ax_used_connections.label Peak Listeners\n"); + echo("ax_used_connections.type GAUGE\n"); + + // Max Listeners Connected to Server + echo("all_connections.draw LINE1\n"); + echo("all_connections.colour a00e95\n"); + echo("all_connections.min 0\n"); + echo("all_connections.label Listeners\n"); + echo("all_connections.type GAUGE\n"); + + // Max Unique Listeners Connected to Server + echo("unique_connections.draw LINE1\n"); + echo("unique_connections.colour 330099\n"); + echo("unique_connections.min 0\n"); + echo("unique_connections.label Unique Listeners\n"); + echo("unique_connections.type GAUGE\n"); + + exit(); + +} + +//closing the connection +curl_close($ch); + + +?> From b9f04c70a0c01f32f5896613e7347aa42be43b9b Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 6 Feb 2012 18:18:40 +0100 Subject: [PATCH 19/76] - adding a CGI for a JSON-ified datafile --- tools/munin2json/cgi-bin/munin-cgi-datafile | 74 +++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 tools/munin2json/cgi-bin/munin-cgi-datafile diff --git a/tools/munin2json/cgi-bin/munin-cgi-datafile b/tools/munin2json/cgi-bin/munin-cgi-datafile new file mode 100644 index 00000000..497a7bb2 --- /dev/null +++ b/tools/munin2json/cgi-bin/munin-cgi-datafile @@ -0,0 +1,74 @@ +#! /usr/bin/perl + +use warnings; +use strict; + +use CGI; +use Scalar::Util qw(isweak); + +use JSON; +use Munin::Master::Utils; +use Munin::Common::Defaults; + +my $conffile = $Munin::Common::Defaults::MUNIN_CONFDIR . "/munin.conf"; +my $config = munin_config($conffile); + + +# Header +my $cgi = CGI->new(); +print $cgi->header( + -status => 200, + -type => "application/json", + -expires=>'+5m', +); + +# Body +my $json = JSON->new->allow_nonref; + +# Remove all recursive refs +remove_weak($config); + +print $json->pretty->encode($config); + +sub remove_weak { + my $cur = shift; + if (ref($cur) eq 'HASH') { + for my $key (keys %$cur) { + # Ignore scalars + next unless ref $cur->{$key}; + + my $to_remove = isweak $cur->{$key}; + $to_remove ||= ($key eq "#%#parent"); + $to_remove ||= ($key eq "#%#root"); + # Remove weak refs + if ($to_remove) { + delete $cur->{$key}; + next; + } + + # Not weak, go down. + remove_weak($cur->{$key}) if ref $cur->{$key}; + } + } elsif (ref($cur) eq 'ARRAY') { + for (my $i = 0 ; $i < @$cur ; $i++) { + # Ignore scalars + next unless ref $cur->[$i]; + + # Remove weak refs + if (isweak $cur->[$i]) { + delete $cur->[$i]; + next; + } + + # Not weak, go down. + remove_weak($cur->[$i]); + } + } elsif (ref($cur) eq 'SCALAR') { + # Ignore scalars + next unless ref $$cur; + + remove_weak($$cur); + } else { + # This cannot be circular, ignoring + } +} From 293ce084088f71f038dc4b06c17a3c1e1799f4aa Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 6 Feb 2012 18:19:22 +0100 Subject: [PATCH 20/76] - chmod +x --- tools/munin2json/cgi-bin/munin-cgi-datafile | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 tools/munin2json/cgi-bin/munin-cgi-datafile diff --git a/tools/munin2json/cgi-bin/munin-cgi-datafile b/tools/munin2json/cgi-bin/munin-cgi-datafile old mode 100644 new mode 100755 From 3716785b5ce3575c40fa607260e57ba77937b756 Mon Sep 17 00:00:00 2001 From: Bjorn Ruberg Date: Tue, 7 Feb 2012 15:05:02 +0100 Subject: [PATCH 21/76] - Adding a new squeezebox plugin, multigraph-enabled --- plugins/other/squeezebox_multi | 226 +++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100755 plugins/other/squeezebox_multi diff --git a/plugins/other/squeezebox_multi b/plugins/other/squeezebox_multi new file mode 100755 index 00000000..92ca0e61 --- /dev/null +++ b/plugins/other/squeezebox_multi @@ -0,0 +1,226 @@ +#!/usr/bin/perl + +=head1 NAME + +squeezebox_ - plugin to monitor a Logitech Media Server and associated +players. + +=head1 APPLICABLE SYSTEMS + +Probably any system running Logitech Media Server. Change the host to +enable remote monitoring. + +=head1 CONFIGURATION + +No configuration should be required if run on the same server as +the Logitech Media Server. If the plugin is run from another unit or +in a non-default configuration, please use the environment variables +'squeezebox_host' and 'squeezebox_port' to connect. + +Sample content for plugin-conf.d/ follows: + + [squeezebox] + env.squeezecenter_host 192.168.100.10 + env.squeezecenter_port 9095 + +=head1 INTERPRETATION + +The "volume" graphs only graphs the player volume levels, not the +amplifier or whatever the player may be connected to. + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf suggest + +=head1 BUGS + +None known + +=head1 AUTHOR + +Bjørn Ruberg + +=head1 LICENSE + +GPLv2 + +=cut + +#%# family=auto +#%# capabilities=autoconf suggest + +use strict; + +my $ret = undef; +if (! eval "require Net::Telnet;") { + $ret = "Net::Telnet not found"; +} +if (! eval "require URI::Escape;") { + $ret = "URI::Escape not found"; +} + +use vars qw ($host $port $config); + +# Define connection settings, from plugin environment file or use defaults +my $host = exists $ENV{'squeezecenter_host'} ? $ENV{'squeezecenter_host'} : "127.0.0.1"; +my $port = exists $ENV{'squeezecenter_port'} ? $ENV{'squeezecenter_port'} : "9090"; + +# Argument handling: autoconf, suggest, update, config + +if (@ARGV) { + if ($ARGV[0] eq "autoconf") { + # autoconf for magically self-configuring the plugin + if ($ret) { + print "no ($ret)"; + exit 0; + } + my $conn = new Net::Telnet (Telnetmode => 0); + $conn->open (Host => $host, + Port => $port, + Errmode => "return"); + if ($conn->errmsg) { + print "no (No connection on $host port $port)"; + exit 0; + } else { + my $version = ""; + my $line = ""; + $conn->print("version ?"); + $conn->print("exit"); + while (($line = $conn->getline) and ($line !~ /exit/)) { + $version = $line if $line =~ /version/; + } + if ($version =~ /^version/) { + print "yes"; + exit 0; + } else { + print "no (socket responded but the server didn't respond as expected)"; + exit 0; + } + } + } elsif ($ARGV[0] eq "suggest") { + print "I am a multigraph plugin, and suggest is not required\n"; + exit 0; + } elsif ($ARGV[0] eq "update") { + # For scheduled inventory rescan, add this plugin to a cron job + # with the argument "update" Adjust the interval to your own tempo + # for adding/deleting music. This equals a "Look for new and + # changed media files" rescan from the webUI. + # + # example: 5 * * * * /usr/share/munin/plugins/squeezebox update + + my $conn = new Net::Telnet (Telnetmode => 0); + $conn->open (Host => $host, + Port => $port, + Errmode => "return"); + if ($conn->errmsg) { + print $conn->errmsg, "\n";; + exit 1; + } else { + $conn->print("rescan"); + $conn->print("exit"); + exit 0; + } + } elsif ($ARGV[0] eq "config") { + # Sets $config value for using in the main execution cycle + $config = 1; + } +} + +# We're keeping the socket open for all checks +my $conn = new Net::Telnet (Telnetmode => 0); +$conn->open (Host => $host, + Port => $port); + +use URI::Escape; +# use Encode qw (from_to); +use Text::Iconv; +my $converter = Text::Iconv->new("UTF-8", "LATIN1"); +# $converted = $converter->convert("Text to convert"); + +# First all the simple readings +foreach my $attr qw (albums artists genres songs) { + $conn->print ("info total ${attr} ?"); + my $line = uri_unescape($conn->getline); + if ($line =~ /^info total ${attr} (\d+)$/) { + my $number = $1; + print "multigraph squeezebox_${attr}\n"; + if ($config) { + print "graph_title Number of ${attr}\n"; + print "graph_scale no\n"; + print "graph_category Squeezebox\n"; + print "${attr}.label ${attr}\n"; + } else { + print "${attr}.value $number\n"; + } + } +} + +# years +$conn->print ("years"); +if (uri_unescape($conn->getline) =~ /^years\s+count:(\d+)/) { + my $no_of_years = $1; + $conn->print ("years 0 $no_of_years"); + my @years = split (" ", uri_unescape($conn->getline)); + print "multigraph squeezebox_years\n"; + + if ($config) { + # config run + print "graph_title Albums per year\n"; + print "graph_category Squeezebox\n"; + print "graph_args --base 1000 -l 0\n"; + foreach my $year (@years) { + if ($year =~ /year\:(\d+)/) { + print "y" . $1 . ".label $1\n"; + print "y" . $1 . ".draw AREASTACK\n"; + } + } + } else { + # regular run + foreach my $year (@years) { + if ($year =~ /(year\:\d+)/) { + $conn->print ("albums 0 0 $1"); + # albums 0 0 year:2007 count:13 + my $line = uri_unescape ($conn->getline); + if ($line =~ /^.*year\:(\d+) count\:(\d+)$/) { + print "y${1}.value ${2}\n"; + } + + } + } + } +} + +# mixer volume and signalstrength +foreach my $attr ("signalstrength", "mixer volume") { + # The plugin reports as squeezebox_volume while the command is + # "mixer volume". + (my $attr_print = $attr) =~ s/mixer //g; + print "multigraph squeezebox_${attr_print}\n"; + if ($config) { + print "graph_title " . ucfirst ($attr) . "\n"; + print "graph_category Squeezebox\n"; + } + $conn->print ("player count ?"); + (my $no_of_players = uri_unescape ($conn->getline)) =~ s/player count\s+//; + chomp $no_of_players; + my $id; + for ($id = 0; $id < $no_of_players; $id++) { + $conn->print ("player id ${id} ?"); + (my $mac = uri_unescape ($conn->getline)) =~ s/player id \d+ //g; + chomp ($mac); + (my $mac_print = 'm' . $mac) =~ s/\://g; + if ($config) { + $conn->print ("player name ${mac} ?"); + (my $name = uri_unescape ($conn->getline)) =~ s/player name ${mac} //g; + chomp $name; + print "${mac_print}.label ", $converter->convert($name), "\n"; + } else { + $conn->print ("${mac} ${attr} ?"); + (my $value = uri_unescape ($conn->getline)) =~ s/^.* //g; + chomp $value; + print "${mac_print}.value $value\n"; + } + } +} + From 66012ed0be3f6f501c6d87c1805869d175b0ed55 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Wed, 8 Feb 2012 17:40:34 +0100 Subject: [PATCH 22/76] Typos (thx ssm) --- plugins/other/shoutcast2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/other/shoutcast2 b/plugins/other/shoutcast2 index 5e0ed963..250c7ebb 100755 --- a/plugins/other/shoutcast2 +++ b/plugins/other/shoutcast2 @@ -104,7 +104,7 @@ else // this is for munin's configuration tool // could do something more complicated here -if(count($argv) == 2 && $arv[1] == 'authconf') { +if(count($argv) == 2 && $argv[1] == 'autoconf') { exit('yes'); } From 051c28211154f274e0f14c8d6fa674c9639aae77 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 9 Feb 2012 11:30:37 +0100 Subject: [PATCH 23/76] Added some infos on the way the contrib repo works --- README.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 960c5caa..9907bc0f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,27 @@ This is the repository for all user contributed stuff -* contrib/tools/ is for 3rd-party tools. It usually serves as an incubator of trunk/contrib. -* contrib/plugins/ is for 3rd-party plugins. It will serve as the backend of exchange.munin-monitoring.org when it is operational again. -* contrib/templates/ is for 3rd-party templates. Feel free to update templates, or even to create new ones. Bonus points for mobile-friendly ones :) +# contrib/plugins/ - 3rd-party plugins + +**This is usually where you want to begin your journey.** + +Here you'll find all the plugins coming from http://exchange.munin-monitoring.org/. +It as evolved since then, but + +# contrib/templates/ - 3rd-party templates + +Feel free to update templates here, or even to create new ones. + +Bonus points for mobile-friendly ones :) + +Note that the one named `official` is a loose-synced copy of the one in SVN trunk. +It should serves as a base for small editions that can be resynced in SVN trunk, so for that : + +* don't copy the whole template +* directly edit files in this directory + +# contrib/tools/ - 3rd-party tools + +Here, you can put just any kind of tool. Please use this directory instead of a random place on the internet. +It makes things way more easy to search for others. + +And, it serves as an incubator of SVN `trunk/contrib` :-) From a2dd3b1b703ad6fb44f72ab1a2c470c4e7cd1d93 Mon Sep 17 00:00:00 2001 From: Matt West Date: Thu, 9 Feb 2012 03:45:43 -0800 Subject: [PATCH 24/76] Adding shoutcast2_multi plugin written in perl, should function on both 32bit and 64bit machines --- plugins/other/shoutcast2_multi | 331 +++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100755 plugins/other/shoutcast2_multi diff --git a/plugins/other/shoutcast2_multi b/plugins/other/shoutcast2_multi new file mode 100755 index 00000000..e1202ad8 --- /dev/null +++ b/plugins/other/shoutcast2_multi @@ -0,0 +1,331 @@ +#!/usr/bin/perl +# +=head1 Shoutcast 2.0.x Plugin + + A Plugin for monitoring a Shoutcast 2.0.x Server (Multigraph) + +=head1 Munin Configuration + + [shoutcast2_multi] + env.host 127.0.0.1 *default* + env.port 8000 *default* + env.pass changeme *default* + +=head2 Munin Configuration Explanation + + host = host we are attempting to connection to, can be ip, or hostname + port = port we need to connect to in order to get to admin.cgi + pass = password to use to authenticate as admin user + +=head1 License + + GPLv2 + +=head1 Magic Markers + +#%# family=auto +#%# capabilities=autoconf + +=cut + +use strict; +use warnings; +use LWP::UserAgent; +use XML::Simple; +use Munin::Plugin; + +need_multigraph(); + +=head1 Variable Declarations + + This section is mainly for importing / declaring our environment variables. + This is were we will import the data from our plugin-conf.d file so we can + override the default settings which will only work for Shoutcast test configs. + +=cut + +my $host = $ENV{host} || '127.0.0.1'; +my $port = $ENV{port} || 8000; +my $pass = $ENV{pass} || 'changeme'; + +# Initialize hashref for storing results information... +my $dataRef; + +# Create a hashref for our graph information that we will call up later... +my $graphsRef; + +my $ua = LWP::UserAgent->new(); +$ua->agent('Munin Shoutcast Plugin/0.1'); +$ua->timeout(5); +$ua->credentials($host.':'.$port, 'Shoutcast Server', 'admin'=>$pass); + +=head1 Graphs Declarations + + The following section of code contains our graph information. This is the data + provided to Munin, so that it may properly draw our graphs based on the values + the plugin returns. + + While you are free to change colors or labels changing the type, min, or max + could cause unfortunate problems with your graphs. + +=cut + +$graphsRef->{active} = { + config => { + args => '--base 1000 --lower-limit 0', + vlabel => 'Is a DJ Actively Connected?', + category => 'shoutcast2', + title => 'Active States', + info => 'This graph shows us the active state or not, depending on if a DJ is connected', + }, + datasrc => [ + { name => 'active', draw => 'AREA', min => '0', max => '1', label => 'On or Off', type => 'GAUGE' }, + ], +}; + +$graphsRef->{listeners} = { + config => { + args => '--base 1000 --lower-limit 0', + vlabel => 'Listener Count', + category => 'shoutcast2', + title => 'Listeners', + info => 'This graph shows us the various counts for listener states we are tracking', + }, + datasrc => [ + { name => 'maxlisteners', draw => 'STACK', min => '0', label => 'Max Listeners', type => 'GAUGE' }, + { name => 'currlisteners', draw => 'AREA', min => '0', label => 'Current Listeners', type => 'GAUGE' }, + ], +}; + +$graphsRef->{sid_active} = { + config => { + args => '--base 1000 --lower-limit 0', + vlabel => 'Is a DJ Actively Connected?', + title => 'Active State', + info => 'This graph shows us the active state or not, depending on if a DJ is connected', + }, + datasrc => [ + { name => 'active', draw => 'AREA', min => '0', max => '1', label => 'On or Off', type => 'GAUGE', xmlkey => 'STREAMSTATUS' }, + ], +}; + +$graphsRef->{sid_listeners} = { + config => { + args => '--base 1000 --lower-limit 0', + vlabel => 'Listener Count', + title => 'Listeners', + info => 'This graph shows us the various counts for listener states we are tracking', + }, + datasrc => [ + { name => 'maxlisteners', draw => 'STACK', min => '0', label => 'Max Listeners', type => 'GAUGE', xmlkey => 'MAXLISTENERS' }, + { name => 'currlisteners', draw => 'AREA', min => '0', label => 'Current Listeners', type => 'GAUGE', xmlkey => 'CURRENTLISTENERS' }, + { name => 'peaklisteners', draw => 'LINE2', min => '0', label => 'Peak Listeners', type => 'GAUGE', xmlkey => 'PEAKLISTENERS' }, + { name => 'uniqlisteners', draw => 'LINE2', min => '0', label => 'Unique Listeners', type => 'GAUGE', xmlkey => 'UNIQUELISTENERS' }, + ], +}; + +if (defined($ARGV[0]) && ($ARGV[0] eq 'config')) { + config(); + exit; +} + +if (defined($ARGV[0]) && ($ARGV[0] eq 'autoconf')) { + check_autoconf(); + exit; +} + +# I guess we are collecting stats to return, execute main subroutine. +main(); + +exit; + +sub main { + my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port); + if ($returnBit == 0) { + exit; + } + my $streamConfigRef = $adminRef->{STREAMCONFIGS}->{STREAMCONFIG}; + my $sidDataRef; + foreach my $sid (keys %{$streamConfigRef}) { + my ($return,$tmpSidRef) = fetch_sid_data($sid); + if ($return == 0) { + next; + } + $sidDataRef->{$sid} = $tmpSidRef; + } + print_active_data($sidDataRef); + print_listener_data($adminRef->{STREAMCONFIGS}->{SERVERMAXLISTENERS}, $sidDataRef); + return; +} + +sub print_active_data { + my ($sidDataRef) = (@_); + my $globalActive = 0; + foreach my $sid (sort keys %{$sidDataRef}) { + print "multigraph shoutcast2_active.active_sid_$sid\n"; + foreach my $dsrc (@{$graphsRef->{sid_active}->{datasrc}}) { + print "$dsrc->{name}.value $sidDataRef->{$sid}->{$dsrc->{xmlkey}}\n"; + if ($sidDataRef->{$sid}->{$dsrc->{xmlkey}} == 1) { + $globalActive = 1; + } + } + } + print "multigraph shoutcast2_active\n"; + foreach my $dsrc (@{$graphsRef->{active}->{datasrc}}) { + print "$dsrc->{name}.value $globalActive\n"; + } + return; +} + +sub print_listener_data { + my ($maxListeners,$sidDataRef) = (@_); + my $globalListeners = 0; + foreach my $sid (sort keys %{$sidDataRef}) { + print "multigraph shoutcast2_listeners.listeners_sid_$sid\n"; + foreach my $dsrc (@{$graphsRef->{sid_listeners}->{datasrc}}) { + print "$dsrc->{name}.value $sidDataRef->{$sid}->{$dsrc->{xmlkey}}\n"; + if ($dsrc->{name} eq 'currlisteners') { + $globalListeners += $sidDataRef->{$sid}->{$dsrc->{xmlkey}}; + } + } + } + print "multigraph shoutcast2_active\n"; + foreach my $dsrc (@{$graphsRef->{listeners}->{datasrc}}) { + if ($dsrc->{name} eq 'maxlisteners') { + print "$dsrc->{name}.value $maxListeners\n"; + } else { + print "$dsrc->{name}.value $globalListeners\n"; + } + } + return; +} + +sub config { + my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port); + if ($returnBit == 0) { + # $adminRef returned a string, we'll just print it out. + print "no (error response: $adminRef)\n"; + exit; + } + my $streamConfigRef = $adminRef->{STREAMCONFIGS}->{STREAMCONFIG}; + my $sidDataRef; + foreach my $sid (keys %{$streamConfigRef}) { + my ($return,$tmpSidRef) = fetch_sid_data($sid); + if ($return == 0) { + next; + } + $sidDataRef->{$sid} = $tmpSidRef; + } + print_active_config($sidDataRef); + print_listener_config($sidDataRef); + return; +} + +sub print_active_config { + my ($sidDataRef) = (@_); + foreach my $sid (sort keys %{$sidDataRef}) { + # Print the Config Info First + print "multigraph shoutcast2_active.active\_sid\_$sid\n"; + print "graph_title ".$graphsRef->{sid_active}->{config}->{title}." for StreamID: $sid\n"; + print "graph_args ".$graphsRef->{sid_active}->{config}->{args}."\n"; + print "graph_vlabel ".$graphsRef->{sid_active}->{config}->{vlabel}."\n"; + print "graph_category streamid_$sid\n"; + print "graph_info ".$graphsRef->{sid_active}->{config}->{info}."\n"; + # Print the Data Value Info + foreach my $dsrc (@{$graphsRef->{sid_active}->{datasrc}}) { + while ( my ($key, $value) = each (%{$dsrc})) { + next if ($key eq 'name'); + next if ($key eq 'xmlkey'); + print "$dsrc->{name}.$key $value\n"; + } + } + } + print "multigraph shoutcast2_active\n"; + print "graph_title ".$graphsRef->{active}->{config}->{title}."\n"; + print "graph_args ".$graphsRef->{active}->{config}->{args}."\n"; + print "graph_vlabel ".$graphsRef->{active}->{config}->{vlabel}."\n"; + print "graph_category".$graphsRef->{active}->{config}->{category}."\n"; + print "graph_info ".$graphsRef->{active}->{config}->{info}."\n"; + # Print the Data Value Info + foreach my $dsrc (@{$graphsRef->{active}->{datasrc}}) { + while ( my ($key, $value) = each (%{$dsrc})) { + next if ($key eq 'name'); + print "$dsrc->{name}.$key $value\n"; + } + } + return; +} + +sub print_listener_config { + my ($sidDataRef) = (@_); + foreach my $sid (sort keys %{$sidDataRef}) { + # Print the Config Info First + print "multigraph shoutcast2_listeners.listeners\_sid\_$sid\n"; + print "graph_title ".$graphsRef->{sid_listeners}->{config}->{title}." for StreamID: $sid\n"; + print "graph_args ".$graphsRef->{sid_listeners}->{config}->{args}."\n"; + print "graph_vlabel ".$graphsRef->{sid_listeners}->{config}->{vlabel}."\n"; + print "graph_category streamid_$sid\n"; + print "graph_info ".$graphsRef->{sid_listeners}->{config}->{info}."\n"; + # Print the Data Value Info + foreach my $dsrc (@{$graphsRef->{sid_listeners}->{datasrc}}) { + while ( my ($key, $value) = each (%{$dsrc})) { + next if ($key eq 'name'); + next if ($key eq 'xmlkey'); + print "$dsrc->{name}.$key $value\n"; + } + } + } + print "multigraph shoutcast2_listeners\n"; + print "graph_title ".$graphsRef->{listeners}->{config}->{title}."\n"; + print "graph_args ".$graphsRef->{listeners}->{config}->{args}."\n"; + print "graph_vlabel ".$graphsRef->{listeners}->{config}->{vlabel}."\n"; + print "graph_category".$graphsRef->{listeners}->{config}->{category}."\n"; + print "graph_info ".$graphsRef->{listeners}->{config}->{info}."\n"; + # Print the Data Value Info + foreach my $dsrc (@{$graphsRef->{listeners}->{datasrc}}) { + while ( my ($key, $value) = each (%{$dsrc})) { + next if ($key eq 'name'); + print "$dsrc->{name}.$key $value\n"; + } + } + return; +} + +sub check_autoconf { + my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port); + if ($returnBit == 0) { + # $adminRef returned a string, we'll just print it out. + print "no (error response: $adminRef)\n"; + } else { + print "yes\n"; + } + return; +} + +sub fetch_sid_data { + my ($sid) = (@_); + my $url = 'http://'.$host.':'.$port.'/stats?sid='.$sid; + my $response = $ua->get($url); + if ($response->is_success) { + my $returnRef = XMLin($response->decoded_content); + return (1, $returnRef); + } else { + return (0, $response->status_line); + } +} + +sub fetch_admin_data { + my $url = 'http://'.$host.':'.$port.'/admin.cgi?sid=1&mode=viewxml&page=6'; + my $response = $ua->get($url); + if ($response->is_success) { + my $returnRef = XMLin($response->decoded_content); + if (($returnRef->{STREAMCONFIGS}->{TOTALCONFIGS} > 0) && (defined($returnRef->{STREAMCONFIGS}->{STREAMCONFIG}))) { + return (1, $returnRef); + } else { + return (0, 'Unable to Detect any Stream Configurations'); + } + } else { + return (0, $response->status_line); + } +} + From 352a9baf9429ac320613b927e7205f5b747566b4 Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Thu, 9 Feb 2012 14:47:17 +0100 Subject: [PATCH 25/76] Add UTF8 plugins --- .../munin-node-from-hell/muninnode-from-hell | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tools/munin-node-from-hell/muninnode-from-hell b/tools/munin-node-from-hell/muninnode-from-hell index 06f0ef60..fabab78b 100755 --- a/tools/munin-node-from-hell/muninnode-from-hell +++ b/tools/munin-node-from-hell/muninnode-from-hell @@ -1,4 +1,5 @@ #!/usr/bin/python +# .- coding: utf-8 -. # # Artificial munin node that behaves in all the ways you would like # ordinary nodes _not_ to behave. @@ -135,6 +136,40 @@ locked.info The number of processes that have pages locked into memory (for real """ modules["graph_area"] = graph_area() +class utf8_graphcat(MuninPlugin): + "A plugin with a graph category which has UTF-8 in it" + def fetch(self, conf): + load = open("/proc/loadavg", "r").read() + load, rest = load.split(" ", 1) + load = float(load) + return "apples.value %.2f" % load + + def config(self, conf): + return """graph_title Example UTF-8 graph +graph_vlabel apples +graph_category foo™ +apples.label apples +graph_info Apples eaten +apples.info Apples eaten""" +modules["utf8_graphcat"] = utf8_graphcat() + +class utf8_graphname(MuninPlugin): + "A plugin with a UTF-8 name" + def fetch(self, conf): + load = open("/proc/loadavg", "r").read() + load, rest = load.split(" ", 1) + load = float(load) + return "apples.value %.2f" % load + + def config(self, conf): + return """graph_title Example UTF-8 graph +graph_vlabel apples +graph_category system +apples.label apples +graph_info Apples eaten +apples.info Apples eaten""" +modules["utf8_™graphname"] = utf8_graphname() + class ArgumentTCPserver(SocketServer.ThreadingTCPServer): def __init__(self, server_address, RequestHandlerClass, args): From f110d3ddb1d146595dd4f7b1622b22c9b8ef1405 Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Thu, 9 Feb 2012 14:47:30 +0100 Subject: [PATCH 26/76] verbose mode as runtime flag --- tools/munin-node-from-hell/muninnode-from-hell | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/munin-node-from-hell/muninnode-from-hell b/tools/munin-node-from-hell/muninnode-from-hell index fabab78b..2256dbf6 100755 --- a/tools/munin-node-from-hell/muninnode-from-hell +++ b/tools/munin-node-from-hell/muninnode-from-hell @@ -188,7 +188,7 @@ class MuninHandler(SocketServer.StreamRequestHandler): """ def handle(self): - print "%s: Connection from %s:%s. server args is %s" \ + if self.server.args.get("verbose"): print "%s: Connection from %s:%s. server args is %s" \ % (self.server.args["name"], self.client_address[0], self.client_address[1], self.server.args) # slow path hostname = self.server.args["name"] @@ -264,7 +264,7 @@ def start_servers(instances): def usage(): - print "Usage: %s [--run] [--muninconf] " % sys.argv[0] + print "Usage: %s [--run] [--verbose] [--muninconf] " % sys.argv[0] def main(): if len(sys.argv) <= 2: @@ -326,6 +326,8 @@ def main(): instanceconfig[k] = v instanceconfig["plugins"] = plugins + if "--verbose" in sys.argv: + instanceconfig["verbose"] = True instanceconfig["name"] = "%s-%s" % (instancename, portinstance) instanceconfig["expanded_port"] = portinstance From 0442899e04cea0d35710a54444809f0a76f6cd0b Mon Sep 17 00:00:00 2001 From: Lasse Karstensen Date: Thu, 9 Feb 2012 15:42:42 +0100 Subject: [PATCH 27/76] last arg is the config file --- tools/munin-node-from-hell/muninnode-from-hell | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/munin-node-from-hell/muninnode-from-hell b/tools/munin-node-from-hell/muninnode-from-hell index 2256dbf6..30b05473 100755 --- a/tools/munin-node-from-hell/muninnode-from-hell +++ b/tools/munin-node-from-hell/muninnode-from-hell @@ -271,8 +271,12 @@ def main(): usage() sys.exit(1) + verbose = False + if "--verbose" in sys.argv: + verbose = True + config = ConfigParser.RawConfigParser() - config.read(sys.argv[2]) + config.read(sys.argv[-1]) instancekeys = [ key for key in config.sections() if key.startswith("instance:") ] servers = {} @@ -343,6 +347,7 @@ def main(): if "--run" in sys.argv: + if verbose: print "Starting up.." servers = start_servers(instances) try: From 957d093144dbe5d1950655a01d3a20126315c35c Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 9 Feb 2012 18:30:37 +0800 Subject: [PATCH 28/76] Added some infos on the way the contrib repo works --- README.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 960c5caa..9907bc0f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,27 @@ This is the repository for all user contributed stuff -* contrib/tools/ is for 3rd-party tools. It usually serves as an incubator of trunk/contrib. -* contrib/plugins/ is for 3rd-party plugins. It will serve as the backend of exchange.munin-monitoring.org when it is operational again. -* contrib/templates/ is for 3rd-party templates. Feel free to update templates, or even to create new ones. Bonus points for mobile-friendly ones :) +# contrib/plugins/ - 3rd-party plugins + +**This is usually where you want to begin your journey.** + +Here you'll find all the plugins coming from http://exchange.munin-monitoring.org/. +It as evolved since then, but + +# contrib/templates/ - 3rd-party templates + +Feel free to update templates here, or even to create new ones. + +Bonus points for mobile-friendly ones :) + +Note that the one named `official` is a loose-synced copy of the one in SVN trunk. +It should serves as a base for small editions that can be resynced in SVN trunk, so for that : + +* don't copy the whole template +* directly edit files in this directory + +# contrib/tools/ - 3rd-party tools + +Here, you can put just any kind of tool. Please use this directory instead of a random place on the internet. +It makes things way more easy to search for others. + +And, it serves as an incubator of SVN `trunk/contrib` :-) From a247c870d75e66be3a0f8264f2253f0ad4862fec Mon Sep 17 00:00:00 2001 From: Paul Saunders Date: Mon, 16 Jan 2012 21:33:32 +0800 Subject: [PATCH 29/76] ejabberd_: Remove $MUNIN_DEBUG Of course, in bash the local $MUNIN_DEBUG is the same as the environment's $MUNIN_DEBUG. --- plugins/other/ejabberd_ | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/other/ejabberd_ b/plugins/other/ejabberd_ index 0fee887e..b7757d42 100755 --- a/plugins/other/ejabberd_ +++ b/plugins/other/ejabberd_ @@ -43,7 +43,6 @@ shopt -s extglob EJCTL=$(which ejabberdctl) EJVER=$($EJCTL status | awk '/^ejabberd / {print $2}') -MUNIN_DEBUG=${MUNIN_DEBUG:-0} if [ "$1" == "autoconf" ]; then if [ -x $EJCTL > /dev/null ]; then From b75bbfea929d05e2405cc9408f3895ea221ed9b4 Mon Sep 17 00:00:00 2001 From: Fyodor Yarochkin Date: Mon, 16 Jan 2012 23:53:32 +0800 Subject: [PATCH 30/76] typo in the doc :) --- plugins/other/riak_memory | 2 +- plugins/other/riak_node | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/other/riak_memory b/plugins/other/riak_memory index 25fe4764..c1bf08b5 100755 --- a/plugins/other/riak_memory +++ b/plugins/other/riak_memory @@ -5,7 +5,7 @@ # sample config in /etc/munin/plugin-conf.d/riak # # [riak_*] -# RIAK_URL=http://127.0.0.1:8091/stats +# env.RIAK_URL http://127.0.0.1:8091/stats # any questions to fygrave at o0o dot nu # # This plugin monitors memory allocation on each node. diff --git a/plugins/other/riak_node b/plugins/other/riak_node index 0ac851f8..1d3dcc89 100755 --- a/plugins/other/riak_node +++ b/plugins/other/riak_node @@ -4,7 +4,7 @@ # sample config in /etc/munin/plugin-conf.d/riak # # [riak_*] -# RIAK_URL=http://127.0.0.1:8091/stats +# env.RIAK_URL http://127.0.0.1:8091/stats # any questions to fygrave at o0o dot nu # # This plugin monitors put/get rate at each node. From 208bfbedb3e8a1aedf73e08ed62b6c8ac14a6464 Mon Sep 17 00:00:00 2001 From: Matt West Date: Thu, 9 Feb 2012 10:03:20 -0800 Subject: [PATCH 31/76] Updating Memcached Multigraph plugin to latest version --- ...{memcached-multigraph => memcached_multi_} | 468 +++++++++++------- 1 file changed, 289 insertions(+), 179 deletions(-) rename plugins/other/{memcached-multigraph => memcached_multi_} (67%) diff --git a/plugins/other/memcached-multigraph b/plugins/other/memcached_multi_ similarity index 67% rename from plugins/other/memcached-multigraph rename to plugins/other/memcached_multi_ index eac6a90c..e574861f 100755 --- a/plugins/other/memcached-multigraph +++ b/plugins/other/memcached_multi_ @@ -1,6 +1,6 @@ #!/usr/bin/perl # -=head1 NAME +=head1 MEMCACHED Memcached - A Plugin to monitor Memcached Servers (Multigraph) @@ -36,9 +36,6 @@ items => I This graphs the current items and total items in the memc memory => I This graphs the current and max memory allocation B -The following example holds true for all graphing options in this plugin. - Example: ln -s /usr/share/munin/plugins/memcached_multi_ /etc/munin/plugins/memcached_multi_bytes - =head1 ADDITIONAL INFORMATION You will find that some of the graphs have LEI on them. This was done in order to save room @@ -52,13 +49,11 @@ The B variable formats certain graphs based on the following guidelin =head1 ACKNOWLEDGEMENTS -The core of this plugin is based on the mysql_ plugin maintained by Kjell-Magne Ãierud - -Thanks to dormando as well for putting up with me ;) +Thanks to dormando for putting up with me ;) =head1 AUTHOR -Matt West < https://code.google.com/p/memcached-munin-plugin/ > +Matt West < https://github.com/mhwest13/Memcached-Munin-Plugin > =head1 LICENSE @@ -72,54 +67,77 @@ GPLv2 =cut use strict; +use warnings; use IO::Socket; use Munin::Plugin; +use File::Basename; +if (basename($0) !~ /^memcached_multi_/) { + print "This script needs to be named memcached_multi_ and have symlinks which start the same.\n"; + exit 1; +} + +# tell munin about our multigraph capabilities need_multigraph(); +=head1 Variable Declarations + + This section of code is to declare the variables used throughout the plugin + Some of them are imported as environment variables from munin plugin conf.d + file, others are hashes used for storing information that comes from the + stats commands issued to memcached. + +=cut + +# lets import environment variables for the plugin or use the default my $host = $ENV{host} || "127.0.0.1"; my $port = $ENV{port} || 11211; -my %stats; -# This hash contains the information contained in two memcache commands -# stats and stats settings. - -my %items; -# This gives us eviction rates and other hit stats per slab -# We track this so we can see if something was evicted earlier than necessary - -my %chnks; -# This gives us the memory size and usage per slab -# We track this so we can see what slab is being used the most and has no free chunks -# so we can re-tune memcached to allocate more pages for the specified chunk size - -my $timescale = $ENV{timescale} || 3; # This gives us the ability to control the timescale our graphs are displaying. # The default it set to divide by hours, if you want to get seconds set it to 1. # Options: 1 = seconds, 2 = minutes, 3 = hours, 4 = days +my $timescale = $ENV{timescale} || 3; + +# This hash contains the information contained in two memcache commands +# stats and stats settings. +my %stats; + +# This gives us eviction rates and other hit stats per slab +# We track this so we can see if something was evicted earlier than necessary +my %items; + +# This gives us the memory size and usage per slab +# We track this so we can see what slab is being used the most and has no free chunks +# so we can re-tune memcached to allocate more pages for the specified chunk size +my %chnks; + +=head2 Graph Declarations + + This block of code builds up all of the graph info for all root / sub graphs. + + %graphs: is a container for all of the graph definition information. In here is where you'll + find the configuration information for munin's graphing procedure. + Format: + + $graph{graph_name} => { + config => { + You'll find the main graph config stored here + { key => value }, + { ... }, + }, + datasrc => [ + Name: name given to data value + Attr: Attribute and value, attribute must be valid plugin argument + { name => 'Name', info => 'info about graph', ... }, + { ... }, + ], + } + +=cut -# So I was trying to figure out how to build this up, and looking at some good examples -# I decided to use the format, or for the most part, the format from the mysql_ munin plugin -# for Innodb by Kjell-Magne Ãierud, it just spoke ease of flexibility especially with multigraphs -# thanks btw ;) -# -# %graphs is a container for all of the graph definition information. In here is where you'll -# find the configuration information for munin's graphing procedure. -# Format: -# -# $graph{graph_name} => { -# config => { -# # You'll find keys and values stored here for graph manipulation -# }, -# datasrc => [ -# # Name: name given to data value -# # Attr: Attribute for given value -# { name => 'Name', (Attr) }, -# { ... }, -# ], -# } my %graphs; +# main graph for memcached item count $graphs{items} = { config => { args => '--base 1000 --lower-limit 0', @@ -133,7 +151,7 @@ $graphs{items} = { { name => 'total_items', label => 'New Items', min => '0', type => 'DERIVE' }, ], }; - +# main graph for memcached memory usage $graphs{memory} = { config => { args => '--base 1024 --lower-limit 0', @@ -147,7 +165,7 @@ $graphs{memory} = { { name => 'bytes', draw => 'AREA', label => 'Current Bytes Used', min => '0' }, ], }; - +# main graph for memcached network usage $graphs{bytes} = { config => { args => '--base 1000', @@ -162,7 +180,7 @@ $graphs{bytes} = { { name => 'bytes_written', type => 'DERIVE', label => 'Traffic in (-) / out (+)', negative => 'bytes_read', cdef => 'bytes_written,8,*', min => '0' }, ], }; - +# graph for memcached connections $graphs{conns} = { config => { args => '--base 1000 --lower-limit 0', @@ -178,7 +196,7 @@ $graphs{conns} = { { name => 'avg_conns' , label => 'Avg Connections', min => '0' }, ], }; - +# main graph for memcached commands issued $graphs{commands} = { config => { args => '--base 1000 --lower-limit 0', @@ -200,7 +218,7 @@ $graphs{commands} = { { name => 'decr_misses', type => 'DERIVE', label => 'Decrement Misses', info => 'Number of unsuccessful decrement requests', min => '0' }, ], }; - +# main graph for memcached eviction rates $graphs{evictions} = { config => { args => '--base 1000 --lower-limit 0', @@ -215,7 +233,7 @@ $graphs{evictions} = { { name => 'reclaimed', label => 'Reclaimed Items', info => 'Cumulative Reclaimed Item Entries Across All Slabs', type => 'DERIVE', min => '0' }, ], }; - +# sub graph for breaking memory info down by slab ( sub graph of memory ) $graphs{slabchnks} = { config => { args => '--base 1000 --lower-limit 0', @@ -230,7 +248,7 @@ $graphs{slabchnks} = { { name => 'free_chunks', label => 'Total Chunks Not in Use (Free)', min => '0' }, ], }; - +# sub graph for breaking commands down by slab ( sub graph of commands ) $graphs{slabhits} = { config => { args => '--base 1000 --lower-limit 0', @@ -247,7 +265,7 @@ $graphs{slabhits} = { { name => 'decr_hits', label => 'Decrement Requests', type => 'DERIVE', min => '0' }, ], }; - +# sub graph for breaking evictions down by slab ( sub graph of evictions ) $graphs{slabevics} = { config => { args => '--base 1000 --lower-limit 0', @@ -262,7 +280,7 @@ $graphs{slabevics} = { { name => 'reclaimed', label => 'Reclaimed Expired Items', info => 'This is number of times items were stored in expired entry memory space', type => 'DERIVE', min => '0' }, ], }; - +# sub graph for showing the time between an item was last evicted and requested ( sub graph of evictions ) $graphs{slabevictime} = { config => { args => '--base 1000 --lower-limit 0', @@ -275,7 +293,7 @@ $graphs{slabevictime} = { { name => 'evicted_time', label => 'Eviction Time (LEI)', info => 'Time Since Request for Last Evicted Item', min => '0' }, ], }; - +# sub graph for breaking items down by slab ( sub graph of items ) $graphs{slabitems} = { config => { args => '--base 1000 --lower-limit 0', @@ -288,7 +306,7 @@ $graphs{slabitems} = { { name => 'number', label => 'Items', info => 'This is the amount of items stored in this slab', min => '0' }, ], }; - +# sub graph for showing the age of the eldest item stored in a slab ( sub graph of items ) $graphs{slabitemtime} = { config => { args => '--base 1000 --lower-limit 0', @@ -302,37 +320,47 @@ $graphs{slabitemtime} = { ], }; -## -#### Config Check #### -## +=head1 Munin Checks + + These checks look for config / autoconf / suggest params + +=head2 Config Check + + This block of code looks at the argument that is possibly supplied, + should it be config, it then checks to make sure the plugin + specified exists, assuming it does, it will run the do_config + subroutine for the plugin specified, otherwise it dies complaining + about an unknown plugin. + +=cut if (defined $ARGV[0] && $ARGV[0] eq 'config') { - + # Lets get our plugin from the symlink being called up, we'll also verify its a valid + # plugin that we have graph information for $0 =~ /memcached_multi_(.+)*/; my $plugin = $1; - die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin}; - # We need to fetch the stats before we do any config, cause its needed for multigraph + # subgraphs which use slab information for title / info per slab fetch_stats(); - # Now lets go ahead and print out our config. do_config($plugin); exit 0; } -## -#### Autoconf Check #### -## +=head2 Autoconf Check + + This block of code looks at the argument that is possibly supplied, + should it be autoconf, we will attempt to connect to the memcached + service specified on the host:port, upon successful connection it + prints yes, otherwise it prints no. + +=cut if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') { - - my $s = IO::Socket::INET->new( - Proto => "tcp", - PeerAddr => $host, - PeerPort => $port, - ); - + # Lets attempt to connect to memcached + my $s = get_conn(); + # Lets verify that we did connect to memcached if (defined($s)) { print "yes\n"; exit 0; @@ -342,18 +370,21 @@ if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') { } } -## -#### Suggest Check #### -## +=head2 Suggest Check + + This block of code looks at the argument that is possibly supplied, + should it be suggest, we are going to print the possible plugins + which can be specified. Note we only specify the root graphs for the + multigraphs, since the rest of the subgraphs will appear "behind" the + root graphs. It also attempts to connect to the memcached service to + verify it is infact running. + +=cut if (defined $ARGV[0] && $ARGV[0] eq 'suggest') { - - my $s = IO::Socket::INET->new( - Proto => "tcp", - PeerAddr => $host, - PeerPort => $port, - ); - + # Lets attempt to connect to memcached + my $s = get_conn(); + # Lets check that we did connect to memcached if (defined($s)) { my @rootplugins = ('bytes','conns','commands','evictions','items','memory'); foreach my $plugin (@rootplugins) { @@ -366,30 +397,29 @@ if (defined $ARGV[0] && $ARGV[0] eq 'suggest') { } } -## -#### Well We aren't running (auto)config/suggest so lets print some stats #### -## +=head1 Output Subroutines + Output Subroutine calls to output data values + +=head2 fetch_output + + This subroutine is the main call for printing data for the plugin. + No parameters are taken as this is the default call if no arguments + are supplied from the command line. + +=cut + +# Well, no arguments were supplied that we know about, so lets print some data fetch_output(); -## -#### Subroutines for printing info gathered from memcached #### -## - -## -#### This subroutine performs the bulk processing for printing statistics. -## - sub fetch_output { - + # Lets get our plugin from the symlink being called up, we'll also verify its a valid + # plugin that we have graph information for $0 =~ /memcached_multi_(.+)*/; my $plugin = $1; - die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin}; - # Well we need to actually fetch the stats before we do anything to them. fetch_stats(); - # Now lets go ahead and print out our output. my @subgraphs; if ($plugin eq 'memory') { @@ -423,17 +453,24 @@ sub fetch_output { return; } -## -#### This subroutine is for the root non-multigraph graphs which render on the main node page #### -## +=head2 print_root_output + + This block of code prints out the return values for our root graphs. It takes + one parameter $plugin. Returns when completed, this is the non multigraph + output subroutine. + + $plugin; graph we are calling up to print data values for + + Example: print_root_output($plugin); + +=cut sub print_root_output { + # Lets get our plugin, set our graph reference and print out info for Munin my ($plugin) = (@_); - my $graph = $graphs{$plugin}; - print "graph memcached_$plugin\n"; - + # The conns plugin has some specific needs, looking for plugin type if ($plugin ne 'conns') { foreach my $dsrc (@{$graph->{datasrc}}) { my %datasrc = %$dsrc; @@ -461,26 +498,33 @@ sub print_root_output { } } } - return; } -## -#### This subroutine is for the root multigraph graphs which render on the main node page #### -## +=head2 print_rootmulti_output + + This block of code prints out the return values for our root graphs. It takes + one parameter $plugin. Returns when completed, this is the multigraph + output subroutine + + $plugin; main(root) graph we are calling up to print data values for + + Example: print_rootmulti_output($plugin); + +=cut sub print_rootmulti_output { + # Lets get our plugin, set our graph reference and print out info for Munin my ($plugin) = (@_); - my $graph = $graphs{$plugin}; - print "multigraph memcached_$plugin\n"; - + # Lets print our data values with their appropriate name foreach my $dsrc (@{$graph->{datasrc}}) { my $output = 0; my %datasrc = %$dsrc; while ( my ($key, $value) = each(%datasrc)) { next if ($key ne 'name'); + next if (($plugin eq 'evictions') && ($value eq 'reclaimed') && ($stats{version} =~ /1\.4\.[0-2]/)); if (($plugin eq 'evictions') && ($value eq 'evicted_nonzero')) { foreach my $slabid (sort{$a <=> $b} keys %items) { $output += $items{$slabid}->{evicted_nonzero}; @@ -491,24 +535,33 @@ sub print_rootmulti_output { print "$dsrc->{name}.value $output\n"; } } - return; } -## -#### This subroutine is for the sub multigraph graphs created via the multigraph plugin #### -## +=head2 print_submulti_output + + This block of code prints out the return values for our root graphs. It takes + three parameters $slabid, $plugin and @subgraphs. Returns when completed, this + is the multigraph output subroutine for our subgraphs + + $slabid; slab id that we will use to grab info from and print out + $plugin; main(root) being called, used for multigraph output and slab id + @subgraphs; graphs we are actually trying to print data values for + + Example: print_submulti_output($slabid,$plugin,@subgraphs); + +=cut sub print_submulti_output { + # Lets get our slabid, plugin, and subgraphs my ($slabid,$plugin,@subgraphs) = (@_); my $currslab = undef; - + # Time to loop over our subgraphs array foreach my $sgraph (@subgraphs) { - + # Lets set our graph reference for quick calling, and print some info for munin my $graph = $graphs{$sgraph}; - print "multigraph memcached_$plugin.$sgraph\_$slabid\n"; - + # Lets figure out what slab info we are trying to call up if ($plugin eq 'evictions') { $currslab = $items{$slabid}; } elsif ($plugin eq 'memory') { @@ -520,11 +573,12 @@ sub print_submulti_output { } else { return; } - + # Lets print our data values with their appropriate name foreach my $dsrc (@{$graph->{datasrc}}) { my %datasrc = %$dsrc; while ( my ($key, $value) = each(%datasrc)) { next if ($key ne 'name'); + next if (($sgraph eq 'slabevics') && ($value eq 'reclaimed') && ($stats{version} =~ /1\.4\.[0-2]/)); my $output = $currslab->{$value}; if (($sgraph eq 'slabevictime') || ($sgraph eq 'slabitemtime')) { $output = time_scale('data',$output); ; @@ -533,17 +587,23 @@ sub print_submulti_output { } } } - return; } -## -#### Subroutines for printing out config information for graphs #### -## +=head1 Config Subroutines -## -#### This subroutine does the bulk printing the config info per graph #### -## + These subroutines handle the config portion of munin calls. + +=head2 do_config + + This is the main call issued assuming we call up config and plugin specified exists + The subroutine takes one parameter $plugin, and returns when completed. + + $plugin; main(root) graph being called + + Example: do_config($plugin); + +=cut sub do_config { my ($plugin) = (@_); @@ -579,22 +639,59 @@ sub do_config { return; } -## -#### This subroutine is for the config info for sub multigraph graphs created via the multigraph plugin #### -## +=head2 get_conn + + This subroutine returns a socket connection + +=cut + +sub get_conn { + my $s = undef; + + # check if we want to use sockets instead of tcp + my ($sock) = ($host =~ /unix:\/\/(.+)*$/); + + if ($sock) { + $s = IO::Socket::UNIX->new( + Peer => $sock + ); + } else { + $s = IO::Socket::INET->new( + Proto => "tcp", + PeerAddr => $host, + PeerPort => $port, + Timeout => 10, + ); + } + + return $s; +} + +=head2 print_submulti_config + + This subroutine prints out the config information for all of the subgraphs. + It takes three parameters, $slabid, $plugin and @subgraphs, returns when + completed, this is the mutligraph config output for our subgraphs + + $slabid; slab id that we will use to grab info from and print out + $plugin; main(root) being called, used for multigraph output and slab id + @subgraphs; graphs we are actually trying to print data values for + + Example: print_submulti_config($slabid,$plugin,@subgraphs); + +=cut sub print_submulti_config { + # Lets get our slabid, plugin, and subgraphs my ($slabid,$plugin,@subgraphs) = (@_); my ($slabitems,$slabchnks) = undef; - + # Time to loop over our subgraphs array foreach my $sgraph (@subgraphs) { - + # Lets set our graph reference, and main graph config for easy handling my $graph = $graphs{$sgraph}; - my %graphconf = %{$graph->{config}}; - + # Lets tell munin which graph we are graphing, and what our main graph config info is print "multigraph memcached_$plugin.$sgraph\_$slabid\n"; - while ( my ($key, $value) = each(%graphconf)) { if ($key eq 'title') { print "graph_$key $value" . "$slabid" . " ($chnks{$slabid}->{chunk_size} Bytes)\n"; @@ -605,7 +702,7 @@ sub print_submulti_config { print "graph_$key $value\n"; } } - + # Lets tell munin about our data values and how to treat them foreach my $dsrc (@{$graph->{datasrc}}) { my %datasrc = %$dsrc; while ( my ($key, $value) = each(%datasrc)) { @@ -618,25 +715,28 @@ sub print_submulti_config { return; } -## -#### This subroutine is for the config info for root multigraph graphs which render on the main node page #### -## +=head2 print_rootmulti_config + + This subroutine prints out the config information for all of the main(root) graphs. + It takes one parameter, $plugin, returns when completed. + + $plugin; main(root) graph used for multigraph call + + Example: print_rootmulti_config($plugin); + +=cut sub print_rootmulti_config { + # Lets get out plugin, set our graph reference and our graph config info my ($plugin) = (@_); - - die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin}; - my $graph = $graphs{$plugin}; - my %graphconf = %{$graph->{config}}; - + # Lets tell munin about the graph we are referencing and print the main config print "multigraph memcached_$plugin\n"; - while ( my ($key, $value) = each(%graphconf)) { print "graph_$key $value\n"; } - + # Lets tell munin about our data values and how to treat them foreach my $dsrc (@{$graph->{datasrc}}) { my %datasrc = %$dsrc; while ( my ($key, $value) = each(%datasrc)) { @@ -644,29 +744,31 @@ sub print_rootmulti_config { print "$dsrc->{name}.$key $value\n"; } } - return; } -## -#### This subroutine is for the config info for non multigraph graphs which render on the main node page #### -## +=head2 print_root_config + + This subroutine prints out the config information for all of the main(root) graphs. + It takes one parameter, $plugin, returns when completed. + + $plugin; main(root) graph used for multigraph call + + Example: print_root_config($plugin); + +=cut sub print_root_config { + # Lets get our plugin, set our graph reference and our graph config info my ($plugin) = (@_); - - die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin}; - my $graph = $graphs{$plugin}; - my %graphconf = %{$graph->{config}}; - + # Lets tell munin about the graph we are referencing and print the main config print "graph memcached_$plugin\n"; - while ( my ($key, $value) = each(%graphconf)) { print "graph_$key $value\n"; } - + # Lets tell munin about our data values and how to treat them foreach my $dsrc (@{$graph->{datasrc}}) { my %datasrc = %$dsrc; while ( my ($key, $value) = each(%datasrc)) { @@ -674,46 +776,46 @@ sub print_root_config { print "$dsrc->{name}.$key $value\n"; } } - return; } -## -#### This subroutine actually performs the data fetch for us #### -#### These commands do not lock up Memcache at all #### -## +=head1 Misc Subroutines + + These subroutines are misc ones, and are referenced inside of the code. They + should never be called up by Munin. + +=head2 fetch_stats + + This subroutine fetches the information from memcached and stores it into our + hashes for later referencing throughout the graph. Returns when completed + +=cut sub fetch_stats { - my $s = IO::Socket::INET->new( - Proto => "tcp", - PeerAddr => $host, - PeerPort => $port, - ); - + # Lets try and connect to memcached + my $s = get_conn(); + # Die if we can't establish a connection to memcached die "Error: Unable to Connect to $host\[:$port\]\n" unless $s; - + # Lets print the stats command and store the info from the output print $s "stats\r\n"; - while (my $line = <$s>) { - if ($line =~ /STAT\s(.+?)\s(\d+)/) { + if ($line =~ /STAT\s(.+?)\s(.*)/) { my ($skey,$svalue) = ($1,$2); $stats{$skey} = $svalue; } last if $line =~ /^END/; } - + # Lets print the stats settings command and store the info from the output print $s "stats settings\r\n"; - while (my $line = <$s>) { - if ($line =~ /STAT\s(.+?)\s(\d+)/) { + if ($line =~ /STAT\s(.+?)\s(.*)/) { my ($skey,$svalue) = ($1,$2); $stats{$skey} = $svalue; } last if $line =~ /^END/; } - + # Lets print the stats slabs command and store the info from the output print $s "stats slabs\r\n"; - while (my $line = <$s>) { if ($line =~ /STAT\s(\d+):(.+)\s(\d+)/) { my ($slabid,$slabkey,$slabvalue) = ($1,$2,$3); @@ -721,9 +823,8 @@ sub fetch_stats { } last if $line =~ /^END/; } - + # Lets print the stats items command and store the info from the output print $s "stats items\r\n"; - while (my $line = <$s>) { if ($line =~ /STAT\sitems:(\d+):(.+?)\s(\d+)/) { my ($itemid,$itemkey,$itemvalue) = ($1,$2,$3); @@ -733,14 +834,23 @@ sub fetch_stats { } } -## -#### This subroutine is to help manage the time_scale settings for the graph -## +=head2 time_scale + + This subroutine is here for me to adjust the timescale of the time graphs + for last evicted item and age of eldest item in cache. + + Please note, after long usage I have noticed these counters may not + be accurate, I believe the developers are aware and have submitted + a patch upstream. + +=cut sub time_scale { + # Lets get our config option and value to adjust my ($configopt,$origvalue) = (@_); my $value; - + # If config is defined, it returns the config info for time scale + # If data is defined, it returns the original value after its been adjusted if ($configopt eq 'config') { if ($timescale == 1) { $value = "Seconds" . $origvalue; From 8be793e8224a5495bc02a7d04b1ecdef4266a905 Mon Sep 17 00:00:00 2001 From: Matt West Date: Thu, 9 Feb 2012 15:05:03 -0800 Subject: [PATCH 32/76] Fixing shoutcast2_multi plugin --- plugins/other/shoutcast2_multi | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/plugins/other/shoutcast2_multi b/plugins/other/shoutcast2_multi index e1202ad8..e862fffc 100755 --- a/plugins/other/shoutcast2_multi +++ b/plugins/other/shoutcast2_multi @@ -32,6 +32,7 @@ use strict; use warnings; use LWP::UserAgent; use XML::Simple; +use Data::Dumper; use Munin::Plugin; need_multigraph(); @@ -146,12 +147,22 @@ sub main { } my $streamConfigRef = $adminRef->{STREAMCONFIGS}->{STREAMCONFIG}; my $sidDataRef; - foreach my $sid (keys %{$streamConfigRef}) { + if ($adminRef->{STREAMCONFIGS}->{TOTALCONFIGS} == 1) { + my $sid = $streamConfigRef->{id}; my ($return,$tmpSidRef) = fetch_sid_data($sid); if ($return == 0) { - next; + # Only one stream, and we didn't get a good response. + exit; } $sidDataRef->{$sid} = $tmpSidRef; + } else { + foreach my $sid (keys %{$streamConfigRef}) { + my ($return,$tmpSidRef) = fetch_sid_data($sid); + if ($return == 0) { + next; + } + $sidDataRef->{$sid} = $tmpSidRef; + } } print_active_data($sidDataRef); print_listener_data($adminRef->{STREAMCONFIGS}->{SERVERMAXLISTENERS}, $sidDataRef); @@ -209,12 +220,22 @@ sub config { } my $streamConfigRef = $adminRef->{STREAMCONFIGS}->{STREAMCONFIG}; my $sidDataRef; - foreach my $sid (keys %{$streamConfigRef}) { + if ($adminRef->{STREAMCONFIGS}->{TOTALCONFIGS} == 1) { + my $sid = $streamConfigRef->{id}; my ($return,$tmpSidRef) = fetch_sid_data($sid); if ($return == 0) { - next; + # Only one stream, and we didn't get a good response. + exit; } $sidDataRef->{$sid} = $tmpSidRef; + } else { + foreach my $sid (keys %{$streamConfigRef}) { + my ($return,$tmpSidRef) = fetch_sid_data($sid); + if ($return == 0) { + next; + } + $sidDataRef->{$sid} = $tmpSidRef; + } } print_active_config($sidDataRef); print_listener_config($sidDataRef); @@ -244,7 +265,7 @@ sub print_active_config { print "graph_title ".$graphsRef->{active}->{config}->{title}."\n"; print "graph_args ".$graphsRef->{active}->{config}->{args}."\n"; print "graph_vlabel ".$graphsRef->{active}->{config}->{vlabel}."\n"; - print "graph_category".$graphsRef->{active}->{config}->{category}."\n"; + print "graph_category ".$graphsRef->{active}->{config}->{category}."\n"; print "graph_info ".$graphsRef->{active}->{config}->{info}."\n"; # Print the Data Value Info foreach my $dsrc (@{$graphsRef->{active}->{datasrc}}) { @@ -279,7 +300,7 @@ sub print_listener_config { print "graph_title ".$graphsRef->{listeners}->{config}->{title}."\n"; print "graph_args ".$graphsRef->{listeners}->{config}->{args}."\n"; print "graph_vlabel ".$graphsRef->{listeners}->{config}->{vlabel}."\n"; - print "graph_category".$graphsRef->{listeners}->{config}->{category}."\n"; + print "graph_category ".$graphsRef->{listeners}->{config}->{category}."\n"; print "graph_info ".$graphsRef->{listeners}->{config}->{info}."\n"; # Print the Data Value Info foreach my $dsrc (@{$graphsRef->{listeners}->{datasrc}}) { From ee4bc102b9b497674e2762e5d9ab651c6f099095 Mon Sep 17 00:00:00 2001 From: Matt West Date: Thu, 9 Feb 2012 15:05:58 -0800 Subject: [PATCH 33/76] Removing unneeded data dumper module --- plugins/other/shoutcast2_multi | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/other/shoutcast2_multi b/plugins/other/shoutcast2_multi index e862fffc..4ff57589 100755 --- a/plugins/other/shoutcast2_multi +++ b/plugins/other/shoutcast2_multi @@ -32,7 +32,6 @@ use strict; use warnings; use LWP::UserAgent; use XML::Simple; -use Data::Dumper; use Munin::Plugin; need_multigraph(); From 8ffcf3ff69f6f7564cecddbd2189b771f9efc0e6 Mon Sep 17 00:00:00 2001 From: Matt West Date: Thu, 9 Feb 2012 15:24:34 -0800 Subject: [PATCH 34/76] Added perldoc info, tidied up a bit --- plugins/other/shoutcast2_multi | 97 ++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 3 deletions(-) diff --git a/plugins/other/shoutcast2_multi b/plugins/other/shoutcast2_multi index 4ff57589..9eca6500 100755 --- a/plugins/other/shoutcast2_multi +++ b/plugins/other/shoutcast2_multi @@ -17,6 +17,10 @@ port = port we need to connect to in order to get to admin.cgi pass = password to use to authenticate as admin user +=head1 AUTHOR + + Matt West < https://github.com/mhwest13 > + =head1 License GPLv2 @@ -139,8 +143,20 @@ main(); exit; +=head1 Subroutines + + The following is a description of what each subroutine is for and does + +=head2 main + + This subroutine is our main routine should we not be calling up autoconf + or config. Ultimately this routine will print out the values for each graph + and graph data point we are tracking. + +=cut + sub main { - my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port); + my ($returnBit,$adminRef) = fetch_admin_data(); if ($returnBit == 0) { exit; } @@ -168,6 +184,16 @@ sub main { return; } +=head2 print_active_data + + Thie subroutine prints out the active graph values for each stream and ultimately for + the entire shoutcast service. Should 1 Stream be active, but 5 streams available, + the global graph should show the state as active for the service, but clicking into + that graph, should give you a stream level view of which stream was in use during + what time periods. + +=cut + sub print_active_data { my ($sidDataRef) = (@_); my $globalActive = 0; @@ -187,6 +213,15 @@ sub print_active_data { return; } +=head2 print_listener_data + + This subroutine prints out the listener graph values for each stream and ultimately + adds all of the current users together to show that against the maxserver count in + the global graph. Clicking on the global graph will reveal a bit more information + about the users on a stream by stream basis. + +=cut + sub print_listener_data { my ($maxListeners,$sidDataRef) = (@_); my $globalListeners = 0; @@ -210,8 +245,18 @@ sub print_listener_data { return; } +=head2 config + + The config subroutine can be seen as the main config routine, which + will call up to your shoutcast server to figure out how many streams + you have running, and then print out the appropriate multigraph info. + Ultimately this subroutine will call two more routines to print out + the graph args / configuration information. + +=cut + sub config { - my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port); + my ($returnBit,$adminRef) = fetch_admin_data(); if ($returnBit == 0) { # $adminRef returned a string, we'll just print it out. print "no (error response: $adminRef)\n"; @@ -241,6 +286,15 @@ sub config { return; } +=head2 print_active_config + + This subroutine prints out the graph information for our active graphs. + It prints the sub-multigraphs first based on stream id, and finally the + root active graph. Its not suggested that you mess with this routine + unless you fully understand what its doing and how munin graph_args work. + +=cut + sub print_active_config { my ($sidDataRef) = (@_); foreach my $sid (sort keys %{$sidDataRef}) { @@ -276,6 +330,15 @@ sub print_active_config { return; } +=head2 print_listener_config + + This subroutine prints out the graph information for our listeners graphs. + It prints the sub-multigraphs first based on stream id, and finally the + root listeners graph. Its not suggested that you mess with this routine + unless you fully understand what its doing and how munin graph_args work. + +=cut + sub print_listener_config { my ($sidDataRef) = (@_); foreach my $sid (sort keys %{$sidDataRef}) { @@ -311,8 +374,17 @@ sub print_listener_config { return; } +=head2 check_autoconf + + This subroutine is called up when we intercept autoconf specified in ARGV[0] + If we are able to connect to the shoutcast service as admin and fetch the main + admin stats page, we will return ok, otherwise we will return no and the error + response we got from LWP::UserAgent. + +=cut + sub check_autoconf { - my ($returnBit,$adminRef) = fetch_admin_data($ua,$host,$port); + my ($returnBit,$adminRef) = fetch_admin_data(); if ($returnBit == 0) { # $adminRef returned a string, we'll just print it out. print "no (error response: $adminRef)\n"; @@ -322,6 +394,15 @@ sub check_autoconf { return; } +=head2 fetch_sid_data + + This subroutine is called up to fetch information on a per stream mentality. + If we are able to connect to the shoutcast service and get the stats we will + return 1 and a hashref of the de-coded xml information, otherwise we return 0 + so that we know that we have failed and can handle it gracefully. + +=cut + sub fetch_sid_data { my ($sid) = (@_); my $url = 'http://'.$host.':'.$port.'/stats?sid='.$sid; @@ -334,6 +415,16 @@ sub fetch_sid_data { } } +=head2 fetch_admin_data + + This subroutine is called up to fetch information from the admin page to get stream ids. + This subroutine is also used to test that we can connect to the shoutcast service + and if not we can fail gracefully. If we are able to connect to the shoutcast service + and get the stats we will return 1 and a hashref of the de-coded xml information, + otherwise we return 0 so that we know that we have failed and can handle it gracefully. + +=cut + sub fetch_admin_data { my $url = 'http://'.$host.':'.$port.'/admin.cgi?sid=1&mode=viewxml&page=6'; my $response = $ua->get($url); From d1b9cbbb909591746893e7b90a1d89beda7d560f Mon Sep 17 00:00:00 2001 From: Manuel Schneider Date: Fri, 20 Jan 2012 02:06:58 +0800 Subject: [PATCH 35/76] pretty simple plugin to monitor pending freebsd-updates requires 'portversion' --- plugins/other/freebsd-upgrades | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 plugins/other/freebsd-upgrades diff --git a/plugins/other/freebsd-upgrades b/plugins/other/freebsd-upgrades new file mode 100755 index 00000000..e9b0b5a5 --- /dev/null +++ b/plugins/other/freebsd-upgrades @@ -0,0 +1,38 @@ +#!/usr/local/bin/bash + +if [ "$1" = "config" ]; then + echo "graph_title Available Updates" + echo "graph_args --base 1000 -l 0" + echo "graph_vlabel upgradeable packages/ports " + echo "pkg.label binary packages" + echo "ports.label ports" + exit 0 +fi + +if [ "$1" = "autoconf" ]; then + echo "yes" + exit 0 +fi + +updates="$(freebsd-update fetch | \ +grep -v 'Looking up update.FreeBSD.org mirrors' | \ +grep -v 'Fetching metadata signature' | \ +grep -v 'Fetching metadata index' | \ +grep -v 'Inspecting system' | \ +grep -v 'Preparing to download files' | \ +grep -v -e '^$' | \ +grep -v 'The following files will be added' | \ +grep -v 'No updates needed' | \ +grep -v 'The following files will be updated' | wc -l | sed -e 's/ //g' )" + +updates="$(echo -n "${updates}")" + +echo "pkg.value $updates" + + +updates="$(portversion | grep '<' | wc -l | sed -e 's/ //g')" +updates="$(echo -n "${updates}")" + +echo "ports.value $updates" + +exit 0 From f7fcd35f64e1b8b9cc5042f518c1010062a2b375 Mon Sep 17 00:00:00 2001 From: Sean Whitney Date: Sat, 28 Jan 2012 00:53:51 +0800 Subject: [PATCH 36/76] Converted script to perl. It now handles: * 32 to 64 bit counters * reboots without resetting graph values * a rolling 30 days with preliminary prediction * autodiscover a public IPv4 address on a linux firewall/router --- plugins/other/{network-usage => bandwidth_} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename plugins/other/{network-usage => bandwidth_} (100%) diff --git a/plugins/other/network-usage b/plugins/other/bandwidth_ similarity index 100% rename from plugins/other/network-usage rename to plugins/other/bandwidth_ From 138de37d29b929465390799ba22b2481c9f19fb4 Mon Sep 17 00:00:00 2001 From: Sean Whitney Date: Sat, 28 Jan 2012 00:57:58 +0800 Subject: [PATCH 37/76] perl version not committed?!? --- plugins/other/bandwidth_ | 296 ++++++++++++++++++++++++++++----------- 1 file changed, 218 insertions(+), 78 deletions(-) diff --git a/plugins/other/bandwidth_ b/plugins/other/bandwidth_ index 6d73fdbf..99a4fc39 100755 --- a/plugins/other/bandwidth_ +++ b/plugins/other/bandwidth_ @@ -1,12 +1,10 @@ -#!/bin/bash +#!/usr/bin/perl +# -*- perl -*- -# Now updated to support 32-bit operating systems -# Requires bash - -: << =cut +=head1 NAME bandwidth_ - Wildcard-plugin to monitor total network traffic and -predict 30 day bandwidth usage + predict 30 day bandwidth usage =head1 CONFIGURATION @@ -20,16 +18,21 @@ bandwidth_ to this file. E.g. Most likely usage is to monitor an interface connected to your ISP. +The suggest option will try and determine if you have any interfaces with a +public IP and if so it will suggest monitoring those interfaces. If all +IP addresses are private the setup will have to be done manually. Suggest +does not handle IPv6 addresses. + =head1 USAGE Any device found in /proc/net/dev can be monitored. Examples include ipsec*, eth*, irda* and lo. -Please not that aliases cannot be monitored with this plugin. +Please note that aliases cannot be monitored with this plugin. =head1 VERSION -$Id: bandwidth_,v 1.2 2011/09/16 17:54:50 root Exp $ +$Id: bandwidth_,v 1.35 2012/01/23 20:04:33 root Exp $ =head1 AUTHOR @@ -53,92 +56,229 @@ to be interested in expressing peaks in bytes.... =cut -# Change to show your outside interface -INTERFACE=${0##*bandwidth_} -HISTORY="/var/lib/munin/plugin-state/bandwidth_$INTERFACE.state" +use strict; +use Storable qw(store retrieve); +use Switch; -TOTALUPTIME=0 -TOTALINPUT=0 -TOTALOUTPUT=0 -OLDUPTIME=0 -OLDINPUT=0 -OLDOUTPUT=0 +my $interface; +my $history; +my $counter_input; +my $counter_output; +my $input; +my $output; +my $uptime; +my $oldest_ts; +my $input_30days; +my $output_30days; +my $perf_ref = {}; +my $count30 = 2592000; # The number of seconds in 30 days +my $unix_ts = time; +my $rollover = 4294967295; -test -f $HISTORY || touch $HISTORY -BC=$(which bc) -test ${#BC} || (echo "bc not found, please install bc" && exit 1) +eval { init(); }; -case $1 in +sub autoconf { + $0 =~ /bandwidth_(.+)*$/; + $interface = $1; + exit 2 unless defined $interface; + $history = "/var/lib/munin/plugin-state/bandwidth_$interface.state"; +} -# I know that "bandwidth is bits and base10 as opposed to bytes and base2. -# However the purpose of this plugin it to monitor your monthly bandwidth -# consumption to make sure you don't go over your ISP's peak. ISP's seem -# to be interested in expressing peaks in bytes.... +sub bit32or64 { + if ( $input > $rollover || $output > $rollover ) { + $rollover = 18446744073709551615; + } +} - config) - cat <<'EOM' +sub retrieve_history { + return (undef) unless ( -r $history ); + my $store = retrieve($history); + while ( my ( $key, $value ) = each(%$store) ) { + if ( $unix_ts - $key < $count30 ) { + $perf_ref->{$key} = $value; + } + if ( $key =~ /last/ ) { + $perf_ref->{$key} = $value; + } + + } +} + +sub suggest { + + # This only works if one of your interfaces has a public IP, + # Otherwise it will fail and you will have to set it manually + # Multiple public IP addresses can be detected. It won't + # Detect IPv6 addresses. + my $locate = readpipe("locate -b '\\ifconfig'"); + my @ifconfig = readpipe($locate); + my @old; + my $net = "/proc/net/dev"; + my @interfaces; + -f $net || die "Unable to read $net: $!"; + open( DEV, "<", $net ) || die "Unable to read $net: $!"; + + while () { + chomp; + split; + /Inter|face/ and next; + split /:/; + push( @interfaces, $_[0] ); + } + close(DEV); + + foreach (@ifconfig) { + if (/inet addr:([\d.]+)/) { + $1 + =~ /^(127\.\d+|10\.\d+|172\.(1[6-9]|2\d|3[0-1])|192\.168)(\.\d+){2}$/ + and next; + exists $interfaces[ $old[0] ] and print "$old[0]\n"; + } + @old = split; + chomp @old; + } + exit 0; +} + +sub store_history { + + # Store the current values to the new old times + $perf_ref->{$unix_ts} = { + input => $input, + output => $output, + }; + $perf_ref->{last} = { + counter_input => $counter_input, + counter_output => $counter_output, + uptime => $uptime, + }; + store( $perf_ref, $history ) || die "Unable to store $history: $!"; +} + +sub arg { + defined( $ARGV[0] ) or return; + switch ( $ARGV[0] ) { + case 'autoconf' { print "yes\n"; exit 0; } + case 'config' { print_config(); } + case 'suggest' { suggest(); } + } +} + +sub print_config { + print <; + chomp $counter_input; + close($rx); + open(my $tx , "<", "/sys/class/net/$interface/statistics/tx_bytes" ) + || die "Unable to read: $!"; + $counter_output = <$tx>; + chomp $counter_output; + close(DEV); +} -INPUT=$(ifconfig $INTERFACE|grep bytes|awk '{print $2}'|sed s/bytes://g) -OUTPUT=$(ifconfig $INTERFACE|grep bytes|awk '{print $6}'|sed s/bytes://g) +sub uptime { + my $puptime = "/proc/uptime"; + open( TIME, "<", $puptime ) || die "Unable to read $puptime: $!"; + while (