From 623bed7581db3729c9bcd1367a4bf21737ec993a Mon Sep 17 00:00:00 2001 From: Matthias Schmitz Date: Mon, 26 Jul 2010 21:31:27 +0000 Subject: [PATCH 001/109] Add some svg files with logos for t-shirts --- .../logo-horizontal-tshirt-black-modified.svg | 75 ++++++++ .../t-shirts/logo-horizontal-tshirt-black.svg | 172 ++++++++++++++++++ images/t-shirts/logo-shirt-black.svg | 57 ++++++ plugins/sensor/sequoia_websens | 10 +- 4 files changed, 309 insertions(+), 5 deletions(-) create mode 100644 images/t-shirts/logo-horizontal-tshirt-black-modified.svg create mode 100644 images/t-shirts/logo-horizontal-tshirt-black.svg create mode 100644 images/t-shirts/logo-shirt-black.svg diff --git a/images/t-shirts/logo-horizontal-tshirt-black-modified.svg b/images/t-shirts/logo-horizontal-tshirt-black-modified.svg new file mode 100644 index 00000000..f0e0c683 --- /dev/null +++ b/images/t-shirts/logo-horizontal-tshirt-black-modified.svg @@ -0,0 +1,75 @@ + + + + + + + www.munin-monitoring.org + + + + + + + + + + + + + + + + diff --git a/images/t-shirts/logo-horizontal-tshirt-black.svg b/images/t-shirts/logo-horizontal-tshirt-black.svg new file mode 100644 index 00000000..3ce5c0e6 --- /dev/null +++ b/images/t-shirts/logo-horizontal-tshirt-black.svg @@ -0,0 +1,172 @@ + + + + + + + + + + + + + image/svg+xml + + + + + + + www.munin-monitoring.org + + + + + + + + + + + + + + + + diff --git a/images/t-shirts/logo-shirt-black.svg b/images/t-shirts/logo-shirt-black.svg new file mode 100644 index 00000000..6b2d8289 --- /dev/null +++ b/images/t-shirts/logo-shirt-black.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + diff --git a/plugins/sensor/sequoia_websens b/plugins/sensor/sequoia_websens index 6607215c..4bab4c43 100755 --- a/plugins/sensor/sequoia_websens +++ b/plugins/sensor/sequoia_websens @@ -15,14 +15,14 @@ # # If your environment has a average temperature which differs from the default # waring and critical value than feel free to configure the warning and critical value -# +# # # Author # Mohammad Ali # # Version 1.0 # March 19, 2010 -# 01:17:14 PM +# 01:17:14 PM # #%# family=auto #%# capabilities=autoconf @@ -39,7 +39,7 @@ if [ "$1" = "config" ]; then echo "graph_category sensor" echo "graph_args -l 0 -u 100 -r" echo "graph.scale no" - echo "graph_vlabel % and C°" + echo "graph_vlabel % and C°" echo "tempsens.label Temperature" echo "humsens.label Humidity" echo "tempsens.warning 19:24" @@ -47,7 +47,7 @@ if [ "$1" = "config" ]; then echo "tempsens.critical 18:25" echo "humsens.critical :60" exit 0 -fi +fi # HTTP GET REQUEST to retrieve the data from the WebSensor WEBSENS_DATA_FULL=$(printf "GET $host/index.html?em345678 HTTP/1.0 \n\n" | nc $host $port ) @@ -61,4 +61,4 @@ WEBSENS_HUM=$(echo "$WEBSENS_DATA" | cut -d ' ' -f11 | cut -d ':' -f2 | cut -d ' # Sending custom formatted data to munin to create the graphs echo "tempsens.value $WEBSENS_TEMP" -echo "humsens.value $WEBSENS_HUM" \ No newline at end of file +echo "humsens.value $WEBSENS_HUM" From b618e762aea46afd1a1f2d008005afe1d536073c Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 25 Jun 2012 11:13:49 +0200 Subject: [PATCH 002/109] adding some doc to t-shirt --- images/README.md | 2 ++ images/t-shirts/README.md | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 images/t-shirts/README.md diff --git a/images/README.md b/images/README.md index fedf12ba..9216f9b0 100644 --- a/images/README.md +++ b/images/README.md @@ -1,2 +1,4 @@ Please **don't** put screenshots of your plugins here. Put them right next to your plugins. + +The `t-shirt/` subdir contains a t-shirt vector gfx. diff --git a/images/t-shirts/README.md b/images/t-shirts/README.md new file mode 100644 index 00000000..ae8aa3a4 --- /dev/null +++ b/images/t-shirts/README.md @@ -0,0 +1,7 @@ +# T-Shirt subproject + +Some t-shirts + +![logo-horizontal-tshirt-black-modified.svg](logo-horizontal-tshirt-black-modified.svg "logo-horizontal-tshirt-black-modified.svg") +![logo-shirt-black.svg](logo-shirt-black.svg "logo-shirt-black.svg") +![logo-horizontal-tshirt-black.svg](logo-horizontal-tshirt-black.svg "logo-horizontal-tshirt-black.svg") From 1c0440a798a2e9964ee1f18c9a382c9457194259 Mon Sep 17 00:00:00 2001 From: Robert Kilian Date: Thu, 9 Aug 2012 15:26:21 -0700 Subject: [PATCH 003/109] Initial commit of Xastir plugin --- plugins/xastir/README | 5 ++ plugins/xastir/xastir | 111 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 plugins/xastir/README create mode 100755 plugins/xastir/xastir diff --git a/plugins/xastir/README b/plugins/xastir/README new file mode 100644 index 00000000..720841ae --- /dev/null +++ b/plugins/xastir/README @@ -0,0 +1,5 @@ +Be sure to correctly edit the STATION_CALL, XASTIRDIR, and LOGDIR variables + +STATION_CALL: The callsign used by Xastir (include suffix if one is in use) +XASTIRDIR: The directory where Xastir's data, config, etc files are found. Typically ~/.xastir +LOGDIR: Logs are typically stored in ~/.xastir/logs. Ensure that permissions are set appropriately to allow the munin user to read these logs diff --git a/plugins/xastir/xastir b/plugins/xastir/xastir new file mode 100755 index 00000000..ffe082fa --- /dev/null +++ b/plugins/xastir/xastir @@ -0,0 +1,111 @@ +#!/bin/bash + +## Copyright (C) 2012 Robert Kilian +## +## This file is part of the Xastir plugin for Munin. +## +## Xastir-Munin 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; +## either version 3 of the License, or (at your option) any +## later version. +## +## Xastir-Munin is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied +## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +## PURPOSE. See the GNU General Public License for more +## details. +## +## You should have received a copy of the GNU General Public +## License along with Xastir-Munin; see the file COPYING. If not, +## see . +## +## Version 0.1 -- 07.26.12 +## + +# Location of active instance of Xastir +XASTIRDIR="/home/USERNAME/.xastir" + +# Grab the station's callsign from Xastir config +# this currently does not derive the station call correctly when called by the server, but works using munin-run... +#STATION_CALL=`grep ^STATION_CALLSIGN:.* $XASTIRDIR/config/xastir.cnf | awk -F":" '{print $2}'` +STATION_CALL="" + +# Location of Xastir's logs (this can be a symlink to where Xastir actually writes the logs) +LOGDIR="/var/log/xastir/logs" + + +case $1 in + config) + cat <<'EOM' + +graph_title Xastir Packet Stats +graph_vlabel Packets +graph_category ham_radio +graph_scale no +graph_printf %.0lf + +igatetonet.label IGate - RF to Net +igatetonet.type COUNTER +igatetonet.min 0 +igatetonet.max 500 +igatetonet.LINE1 + +message.label Message RX +message.type COUNTER +message.min 0 +message.max 500 +message.draw LINE1 + +messagetx.label Message TX +messagetx.type COUNTER +messagetx.min 0 +messagetx.max 500 +messagetx.draw LINE1 + +net.label Net RX +net.type COUNTER +net.min 0 +net.max 500 +net.draw LINE1 + +nettx.label Net TX +nettx.type COUNTER +nettx.min 0 +nettx.max 500 +nettx.draw LINE1 + +tnc.label TNC RX +tnc.type COUNTER +tnc.min 0 +tnc.max 500 +tnc.draw LINE1 + +tnctx.label TNC TX +tnctx.type COUNTER +tnctx.min 0 +tnctx.max 500 +tnctx.draw LINE1 + +EOM + exit 0;; +esac + +# Parse logs for various values +IGATETONET=`cat $LOGDIR/igate.log | grep -e '^IGATE RF' | wc -l` +MESSAGE=`cat $LOGDIR/message.log | grep -v '^\#' | grep -v ^$STATION_CALL | wc -l` +MESSAGETX=`cat $LOGDIR/message.log | grep -v '^\#' | grep ^$STATION_CALL | wc -l` +NET=`cat $LOGDIR/net.log | grep -v '^\#' | grep -v ^$STATION_CALL | wc -l` +NETTX=`cat $LOGDIR/net.log | grep -v '^\#' | grep ^$STATION_CALL | wc -l` +TNC=`cat $LOGDIR/tnc.log | grep -v '^\#' | grep -v ^$STATION_CALL | wc -l` +TNCTX=`cat $LOGDIR/tnc.log | grep -v '^\#' | grep ^$STATION_CALL | wc -l` + +# Display values +echo "igatetonet.value $IGATETONET" +echo "message.value $MESSAGE" +echo "messagetx.value $MESSAGETX" +echo "net.value $NET" +echo "nettx.value $NETTX" +echo "tnc.value $TNC" +echo "tnctx.value $TNCTX" + From fdd3eaf440327c387600095e679965ecb6104afa Mon Sep 17 00:00:00 2001 From: Robert Kilian Date: Tue, 21 Aug 2012 15:09:05 -0700 Subject: [PATCH 004/109] Moved contents of README into plugin as comments --- plugins/xastir/README | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 plugins/xastir/README diff --git a/plugins/xastir/README b/plugins/xastir/README deleted file mode 100644 index 720841ae..00000000 --- a/plugins/xastir/README +++ /dev/null @@ -1,5 +0,0 @@ -Be sure to correctly edit the STATION_CALL, XASTIRDIR, and LOGDIR variables - -STATION_CALL: The callsign used by Xastir (include suffix if one is in use) -XASTIRDIR: The directory where Xastir's data, config, etc files are found. Typically ~/.xastir -LOGDIR: Logs are typically stored in ~/.xastir/logs. Ensure that permissions are set appropriately to allow the munin user to read these logs From a0975cecfd2bc64dec00778c0fff35e3c41de333 Mon Sep 17 00:00:00 2001 From: Robert Kilian Date: Tue, 21 Aug 2012 15:11:04 -0700 Subject: [PATCH 005/109] Moved contents of README into plugin as comments --- plugins/xastir/xastir | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plugins/xastir/xastir b/plugins/xastir/xastir index ffe082fa..c8944d6b 100755 --- a/plugins/xastir/xastir +++ b/plugins/xastir/xastir @@ -23,6 +23,12 @@ ## Version 0.1 -- 07.26.12 ## +## Be sure to correctly edit the STATION_CALL, XASTIRDIR, and LOGDIR variables +## +## STATION_CALL: The callsign used by Xastir (include suffix if one is in use) +## XASTIRDIR: The directory where Xastir's data, config, etc files are found. Typically ~/.xastir +## LOGDIR: Logs are typically stored in ~/.xastir/logs. Ensure that permissions are set appropriately to allow the munin user to read these logs + # Location of active instance of Xastir XASTIRDIR="/home/USERNAME/.xastir" From e62ea879a23d19347d6c3bab965f6a521a1200cc Mon Sep 17 00:00:00 2001 From: thiago Date: Sun, 28 Oct 2012 08:30:28 +1100 Subject: [PATCH 006/109] Add plugins for Sick-Beard * Number of shows (sample: http://imgur.com/5Uxih) * Number of Episodes (sample: http://imgur.com/3fG8M) --- plugins/sickbeard/sickbeard_episodes | 69 ++++++++++++++++++++++++++++ plugins/sickbeard/sickbeard_shows | 69 ++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100755 plugins/sickbeard/sickbeard_episodes create mode 100755 plugins/sickbeard/sickbeard_shows diff --git a/plugins/sickbeard/sickbeard_episodes b/plugins/sickbeard/sickbeard_episodes new file mode 100755 index 00000000..2a6eb7d5 --- /dev/null +++ b/plugins/sickbeard/sickbeard_episodes @@ -0,0 +1,69 @@ +#!/usr/bin/perl +# +# Munin plugins for Sick-Beard +# +# Copyright (C) 2012 - Blauwbek +# Copyright (C) 2012 - Thiago +# +# Sick-Beard : http://sickbeard.com/ +# +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Requires: JSON::Any +# LWP::UserAgent +# +# Configuration example +# [sickbeard*] +# env.host http://host:port/ +# env.api apikey +# + +use strict; +use JSON::Any; +use LWP::UserAgent; + +#defines +my $HOST = exists $ENV{'host'} ? $ENV{'host'} : "http://localhost:8081/"; +my $API = exists $ENV{'api'} ? $ENV{'api'} : ""; +my $URL = $HOST."/api/".$API."/?cmd=shows.stats"; +my $sURL = sprintf $URL; + +#config output +if(defined $ARGV[0] && $ARGV[0] eq 'config') +{ + print <new; +my $req = $get->get($sURL); +my $json = JSON::Any->jsonToObj($req->content()); + +if ($json->{result} eq 'success') { + print "down.value $json->{data}->{ep_downloaded}\n"; + print "total.value $json->{data}->{ep_total}\n"; + exit 0; +} else { + print "$json->{message}\n"; + exit 1; +} + diff --git a/plugins/sickbeard/sickbeard_shows b/plugins/sickbeard/sickbeard_shows new file mode 100755 index 00000000..a81c6bd8 --- /dev/null +++ b/plugins/sickbeard/sickbeard_shows @@ -0,0 +1,69 @@ +#!/usr/bin/perl +# +# Munin plugins for Sick-Beard +# +# Copyright (C) 2012 - Blauwbek +# Copyright (C) 2012 - Thiago +# +# Sick-Beard : http://sickbeard.com/ +# +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Requires: JSON::Any +# LWP::UserAgent +# +# Configuration example +# [sickbeard*] +# env.host http://host:port/ +# env.api apikey +# + +use strict; +use JSON::Any; +use LWP::UserAgent; + +#defines +my $HOST = exists $ENV{'host'} ? $ENV{'host'} : "http://localhost:8081/"; +my $API = exists $ENV{'api'} ? $ENV{'api'} : ""; +my $URL = $HOST."/api/".$API."/?cmd=shows.stats"; +my $sURL = sprintf $URL; + +#config output +if(defined $ARGV[0] && $ARGV[0] eq 'config') +{ + print <new; +my $req = $get->get($sURL); +my $json = JSON::Any->jsonToObj($req->content()); + +if ($json->{result} eq 'success') { + print "active.value $json->{data}->{shows_active}\n"; + print "total.value $json->{data}->{shows_total}\n"; + exit 0; +} else { + print "$json->{message}\n"; + exit 1; +} + From 8b1e467b7cd5ce035a7c163d6fbc2b8faa954fd8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 1 Nov 2012 08:52:06 +0000 Subject: [PATCH 007/109] Improve the HTTP plugin by allowing configuring a proxy and friendly name per URL. Note that the configuration file syntax has changed. You need one "url" variable per URL now, numbered starting with 1, e.g. url1, url2, url3. Each one can be configured by suffixing its variable, e.g. url1_proxy, url2_proxy, etc. --- plugins/http/http_request_time | 82 +++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/plugins/http/http_request_time b/plugins/http/http_request_time index 509db0d8..a5852a16 100755 --- a/plugins/http/http_request_time +++ b/plugins/http/http_request_time @@ -10,7 +10,12 @@ =head1 CONFIGURATION [http_request_time] - env.url http://127.0.0.1/1 http://127.0.0.1/2 http://127.0.0.1/3 + env.url http://127.0.0.1/1 + env.url2 http://127.0.0.1/2 + env.url3 http://www.example.com + env.url3_name some_munin_internal_name + env.url3_label Some random page on our website + env.url3_proxy http://firewall:3128 =head1 MAGIC MARKERS @@ -41,7 +46,6 @@ sub clean { return $surl; }; - if (! eval "require LWP::UserAgent;") { $ret = "LWP::UserAgent not found"; @@ -50,12 +54,19 @@ if (! eval "require LWP::UserAgent;") } } -my $URL = $ENV{'url'}?$ENV{'url'}:"http://127.0.0.1/"; my %URLS; -foreach $_ (split(/ /,$URL)){ - $URLS{$_}={ - url=>$_, - surl=>clean($_), + +for (my $i = 1; $ENV{"url$i"}; $i++) +{ + my $url = $ENV{"url$i"}; + my $proxy = $ENV{"url${i}_proxy"}; + my $name = $ENV{"url${i}_name"} || clean($url); + my $label = $ENV{"url${i}_label"} || $url; + + $URLS{$name}={ + url=>$url, + proxy=>$proxy, + label=>$label, time=>'U' }; } @@ -94,50 +105,67 @@ if ( defined $ARGV[0] and $ARGV[0] eq "config" ) print "graph_category other\n"; my @go; - foreach my $url (values %URLS) { - print "$$url{'surl'}.label $$url{'url'}\n"; - print "$$url{'surl'}.info The response time of a single request\n"; - print "$$url{'surl'}.min 0\n"; - print "$$url{'surl'}.draw LINE1\n"; - push(@go,$$url{'surl'}); + foreach my $name (keys %URLS) { + my $url = $URLS{$name}; + print "$name.label $$url{'label'}\n"; + print "$name.info The response time of a single request\n"; + print "$name.min 0\n"; + print "$name.draw LINE1\n"; + push(@go, $name); } # multigraphs - foreach my $url (values %URLS) { - print "\nmultigraph http_request_time.$$url{'surl'}\n"; + foreach my $name (keys %URLS) { + my $url = $URLS{$name}; + print "\nmultigraph http_request_time.$name\n"; print "graph_title $$url{'url'}\n"; print "graph_args --base 1000\n"; print "graph_vlabel response time in ms\n"; print "graph_category other\n"; - print "$$url{'surl'}.label $$url{'url'}\n"; - print "$$url{'surl'}.info The response time of a single request\n"; - print "$$url{'surl'}.min 0\n"; - print "$$url{'surl'}.draw LINE1\n"; + print "$name.label $$url{'label'}\n"; + print "$name.info The response time of a single request\n"; + print "$name.min 0\n"; + print "$name.draw LINE1\n"; } exit 0; } my $ua = LWP::UserAgent->new(timeout => 15); +foreach my $name (keys %URLS) { + my $url = $URLS{$name}; -foreach my $url (values %URLS) { - my $t1=[gettimeofday]; + if ($url->{proxy}) { + $ua->proxy(['http', 'ftp'], $url->{proxy}); + } + else { + $ua->proxy(['http', 'ftp'], undef); + } + + # warm up my $response = $ua->request(HTTP::Request->new('GET',$$url{'url'})); + + # timed run + my $t1=[gettimeofday]; + $response = $ua->request(HTTP::Request->new('GET',$$url{'url'})); my $t2=[gettimeofday]; + if ($response->is_success) { $$url{'time'}=sprintf("%d",tv_interval($t1,$t2)*1000); }; }; print("multigraph http_request_time\n"); -foreach my $url (values %URLS) { - print("$$url{'surl'}.value $$url{'time'}\n"); -} -foreach my $url (values %URLS) { - print("\nmultigraph http_request_time.$$url{'surl'}\n"); - print("$$url{'surl'}.value $$url{'time'}\n"); +foreach my $name (keys %URLS) { + my $url = $URLS{$name}; + print("$name.value $$url{'time'}\n"); } +foreach my $name (keys %URLS) { + my $url = $URLS{$name}; + print("\nmultigraph http_request_time.$name\n"); + print("$name.value $$url{'time'}\n"); +} # vim:syntax=perl From 55aa46a3a03ef47dbe6bd106ce656f53e2d33f84 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 1 Nov 2012 09:31:37 +0000 Subject: [PATCH 008/109] Add our "all processes" monitoring plugin, cleaned up, and a page fault plugin. --- plugins/system/cpu_by_process | 106 +++++++++++++++++++++++++++ plugins/system/pagefaults_by_process | 105 ++++++++++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100755 plugins/system/cpu_by_process create mode 100755 plugins/system/pagefaults_by_process diff --git a/plugins/system/cpu_by_process b/plugins/system/cpu_by_process new file mode 100755 index 00000000..f299a087 --- /dev/null +++ b/plugins/system/cpu_by_process @@ -0,0 +1,106 @@ +#!/usr/bin/perl +# +# Copyright 2012 Chris Wilson +# Copyright 2006 Holger Levsen +# +# This plugin monitors ALL processes on a system. No exceptions. It can +# produce very big graphs! But if you want to know where your CPU time +# is going without knowing what to monitor in advance, this can help; +# or in addition to one of the more specific CPU plugins to monitor +# just Apache or MySQL, for example. +# +# It's not obvious what the graph heights actually mean, even to me. +# Each counter is a DERIVE (difference since the last counter reading) +# of the CPU time usage (in seconds) accounted to each process, summed +# by the process name, so all Apache and all MySQL processes are grouped +# together. Processes with no CPU usage at all are ignored. Processes +# that die may not appear on the graph, and anyway their last chunk of +# CPU usage before they died is lost. You could modify this plugin to +# read SAR/psacct records if you care about that. +# +# 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. + +#scriptname=`basename $0` +#vsname=`echo $scriptname | perl -ne '/^vserver_proc_VM_(.*)/ and print $1'` + +#if [ "$1" = "suggest" ]; then +# ls -1 /etc/vservers +# exit 0 +#elif [ -z "$vsname" ]; then +# echo "Must be used with a vserver name; try '$0 suggest'" >&2 +# exit 2 +#fi + +use strict; +use warnings; + +my $cmd = "ps -eo time,comm h"; +open PS, "$cmd|" or die "Failed to run ps command: $cmd: $!"; + +# my $header_line = ; +my %total_cpu_by_process; + +while () +{ + my @fields = split; + my $cputime = $fields[0]; + my $process = $fields[1]; + + # remove any / and everything after it from the process name, + # e.g. kworker/0:2 -> kworker + $process =~ s|/.*||; + + # remove any . at the end of the name (why does this appear?) + # $process =~ s|\.$||; + + # change any symbol that's not allowed in a munin variable name to _ + $process =~ tr|a-zA-Z0-9|_|c; + + my @times = split /:/, $cputime; + $cputime = (($times[0] * 60) + $times[1]) * 60 + $times[2]; + $total_cpu_by_process{$process} += $cputime; +} + +foreach my $process (keys %total_cpu_by_process) +{ + # remove all processes with 0 cpu time + if (not $total_cpu_by_process{$process}) + { + delete $total_cpu_by_process{$process}; + } +} + +close(PS); + +if (@ARGV and $ARGV[1] == "config") +{ + print <&2 +# exit 2 +#fi + +use strict; +use warnings; + +my $cmd = "ps -eo maj_flt,comm h"; +open PS, "$cmd|" or die "Failed to run ps command: $cmd: $!"; + +# my $header_line = ; +my %total_by_process; + +while () +{ + my @fields = split; + my $value = $fields[0]; + my $process = $fields[1]; + + # remove any / and everything after it from the process name, + # e.g. kworker/0:2 -> kworker + $process =~ s|/.*||; + + # remove any . at the end of the name (why does this appear?) + # $process =~ s|\.$||; + + # change any symbol that's not allowed in a munin variable name to _ + $process =~ tr|a-zA-Z0-9|_|c; + + $total_by_process{$process} += $value; +} + +foreach my $process (keys %total_by_process) +{ + # remove all processes with 0 faults + if (not $total_by_process{$process}) + { + delete $total_by_process{$process}; + } +} + +close(PS); + +if (@ARGV and $ARGV[1] == "config") +{ + print < Date: Thu, 1 Nov 2012 09:32:21 +0000 Subject: [PATCH 009/109] These plugins should be executable. --- plugins/system/membyuser | 0 plugins/system/memory_by_process | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 plugins/system/membyuser mode change 100644 => 100755 plugins/system/memory_by_process diff --git a/plugins/system/membyuser b/plugins/system/membyuser old mode 100644 new mode 100755 diff --git a/plugins/system/memory_by_process b/plugins/system/memory_by_process old mode 100644 new mode 100755 From c00710c083e6c3b4b5264c8bf1d207c9805f28db Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 1 Nov 2012 09:55:47 +0000 Subject: [PATCH 010/109] Fix process labels. --- plugins/system/cpu_by_process | 2 +- plugins/system/pagefaults_by_process | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/system/cpu_by_process b/plugins/system/cpu_by_process index f299a087..f452aa6f 100755 --- a/plugins/system/cpu_by_process +++ b/plugins/system/cpu_by_process @@ -89,7 +89,7 @@ END sub draw() { return $stack++ ? "STACK" : "AREA" } print map { - "$_.label $total_cpu_by_process{$_}\n" . + "$_.label $_\n" . "$_.min 0\n" . "$_.type DERIVE\n" . "$_.draw " . draw() . "\n" diff --git a/plugins/system/pagefaults_by_process b/plugins/system/pagefaults_by_process index 89ad2b79..a1f7f10e 100755 --- a/plugins/system/pagefaults_by_process +++ b/plugins/system/pagefaults_by_process @@ -88,7 +88,7 @@ END sub draw() { return $stack++ ? "STACK" : "AREA" } print map { - "$_.label $total_by_process{$_}\n" . + "$_.label $_\n" . "$_.min 0\n" . "$_.type DERIVE\n" . "$_.draw " . draw() . "\n" From fcbc8edbf8b36b0675e19b705f7a58e34fe95143 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 1 Nov 2012 10:29:10 +0000 Subject: [PATCH 011/109] Fix string comparison. --- plugins/system/cpu_by_process | 2 +- plugins/system/pagefaults_by_process | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/system/cpu_by_process b/plugins/system/cpu_by_process index f452aa6f..504ff309 100755 --- a/plugins/system/cpu_by_process +++ b/plugins/system/cpu_by_process @@ -75,7 +75,7 @@ foreach my $process (keys %total_cpu_by_process) close(PS); -if (@ARGV and $ARGV[1] == "config") +if (@ARGV and $ARGV[1] eq "config") { print < Date: Wed, 7 Nov 2012 15:31:10 +0000 Subject: [PATCH 012/109] Add a plugin for adding up any number column output by ps. --- plugins/system/total_by_process_ | 118 +++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100755 plugins/system/total_by_process_ diff --git a/plugins/system/total_by_process_ b/plugins/system/total_by_process_ new file mode 100755 index 00000000..5e3b1a1c --- /dev/null +++ b/plugins/system/total_by_process_ @@ -0,0 +1,118 @@ +#!/usr/bin/perl +# +# Copyright 2012 Chris Wilson +# Copyright 2006 Holger Levsen +# +# This plugin monitors ALL processes on a system. No exceptions. It can +# produce very big graphs! But if you want to know which processes are +# killing your system by page faulting, without knowing what to monitor +# in advance, this can help; or in addition to one of the more specific +# plugins to monitor just Apache or MySQL, for example. +# +# Each counter is a DERIVE (difference since the last counter reading) +# of the number of major page faults, usually 4k each, read in by a +# process. Memory mapped files probably contribute to this. The process +# cannot continue until the page fault is served, so this is a +# high-priority read that usually indicates memory starvation. +# Processes with no page faults at all are ignored. Processes +# that die may not appear on the graph, and anyway their last chunk of +# CPU usage before they died is lost. You could modify this plugin to +# read SAR/psacct records if you care about that. +# +# 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. + +use strict; +use warnings; + +my $scriptname = $0; +$scriptname =~ s|.*/||; +my $fieldname = ($scriptname =~ /^total_by_process_(.*)_(.*)/) ? $1 : undef; +my $fieldtype = ($scriptname =~ /^total_by_process_(.*)_(.*)/) ? $2 : undef; + +if (@ARGV and $ARGV[1] eq "suggest") +{ + system("ps L | cut -d' ' -f1"); + exit(0); +} + +if (!$fieldname) +{ + print STDERR "Must be used with a PS format specifier name; try '$0 suggest'"; + exit(2); +} + +unless ($fieldtype =~ /^(GAUGE|DERIVE)$/) +{ + print STDERR "Unknown field type $fieldtype: should be GAUGE or DERIVE"; + exit(2); +} + +my $cmd = "ps -eo $fieldname,comm h"; +open PS, "$cmd|" or die "Failed to run ps command: $cmd: $!"; + +# my $header_line = ; +my %total_by_process; + +while () +{ + my @fields = split; + my $value = $fields[0]; + my $process = $fields[1]; + + # remove any / and everything after it from the process name, + # e.g. kworker/0:2 -> kworker + $process =~ s|/.*||; + + # remove any . at the end of the name (why does this appear?) + # $process =~ s|\.$||; + + # change any symbol that's not allowed in a munin variable name to _ + $process =~ tr|a-zA-Z0-9|_|c; + + $total_by_process{$process} += $value; +} + +foreach my $process (keys %total_by_process) +{ + # remove all processes with 0 faults + if (not $total_by_process{$process}) + { + delete $total_by_process{$process}; + } +} + +close(PS); + +if (@ARGV and $ARGV[1] == "config") +{ + print < Date: Wed, 7 Nov 2012 15:33:11 +0000 Subject: [PATCH 013/109] Improve the left-side label of the graph. --- plugins/system/total_by_process_ | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/system/total_by_process_ b/plugins/system/total_by_process_ index 5e3b1a1c..a2da8fc0 100755 --- a/plugins/system/total_by_process_ +++ b/plugins/system/total_by_process_ @@ -92,6 +92,7 @@ if (@ARGV and $ARGV[1] == "config") graph_title $fieldname by Process graph_category system graph_info Shows total of $fieldname (reported by ps) for each process name +graph_vlabel $fieldname (from ps) END # graph_args --base 1000 From 7a96e905713a15bee7b6a3eab5f2c6d10154a873 Mon Sep 17 00:00:00 2001 From: Jimmy Jones Date: Fri, 7 Dec 2012 13:18:19 -0800 Subject: [PATCH 014/109] Add Munin scripts for Apache Qpid monitoring --- plugins/qpid/qpid_bytedepth | 44 ++++++++++++++++++++++++++++++++++ plugins/qpid/qpid_discardsring | 44 ++++++++++++++++++++++++++++++++++ plugins/qpid/qpid_enqueuebytes | 44 ++++++++++++++++++++++++++++++++++ plugins/qpid/qpid_enqueuecount | 44 ++++++++++++++++++++++++++++++++++ plugins/qpid/qpid_msgdepth | 44 ++++++++++++++++++++++++++++++++++ 5 files changed, 220 insertions(+) create mode 100755 plugins/qpid/qpid_bytedepth create mode 100755 plugins/qpid/qpid_discardsring create mode 100755 plugins/qpid/qpid_enqueuebytes create mode 100755 plugins/qpid/qpid_enqueuecount create mode 100755 plugins/qpid/qpid_msgdepth diff --git a/plugins/qpid/qpid_bytedepth b/plugins/qpid/qpid_bytedepth new file mode 100755 index 00000000..e89d506f --- /dev/null +++ b/plugins/qpid/qpid_bytedepth @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# Plugin to monitor Apache Qpid +# +# Parameters understood: +# +# queues (required) - space separated list of queues to display (regex allowed) +# +# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) + +import re +import sys +import os +from qmf.console import Session + +if not "queues" in os.environ: + print >> sys.stderr, "Missing env.queues in config" + sys.exit(-1) + +output_queue = [] +sess = Session() +broker = sess.addBroker() +queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker") +for q in queues: + for match in os.environ["queues"].split(" "): + if re.match(match, q.name): + output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name)) + +if len(sys.argv) > 1 and sys.argv[1] == "config": + print "graph_category Qpid"; + print "graph_title Queue byte depth"; + print "graph_vlabel bytes" + for queue in output_queue: + print "%s.label %s" % (queue, queue) + print "%s.min 0" % queue + print "%s.type GAUGE" % queue +else: + for q in queues: + qname = re.sub('[^a-zA-Z0-9_]', '_', q.name) + if qname in output_queue: + print "%s.value %u" % (qname, q.byteDepth) + +sess.delBroker(broker) + diff --git a/plugins/qpid/qpid_discardsring b/plugins/qpid/qpid_discardsring new file mode 100755 index 00000000..f2a12e5d --- /dev/null +++ b/plugins/qpid/qpid_discardsring @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# Plugin to monitor Apache Qpid +# +# Parameters understood: +# +# queues (required) - space separated list of queues to display (regex allowed) +# +# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) + +import re +import sys +import os +from qmf.console import Session + +if not "queues" in os.environ: + print >> sys.stderr, "Missing env.queues in config" + sys.exit(-1) + +output_queue = [] +sess = Session() +broker = sess.addBroker() +queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker") +for q in queues: + for match in os.environ["queues"].split(" "): + if re.match(match, q.name): + output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name)) + +if len(sys.argv) > 1 and sys.argv[1] == "config": + print "graph_category Qpid"; + print "graph_title Ring queue discard rate"; + print "graph_vlabel messages/second"; + for queue in output_queue: + print "%s.label %s" % (queue, queue) + print "%s.min 0" % queue + print "%s.type COUNTER" % queue +else: + for q in queues: + qname = re.sub('[^a-zA-Z0-9_]', '_', q.name) + if qname in output_queue: + print "%s.value %u" % (qname, q.discardsRing) + +sess.delBroker(broker) + diff --git a/plugins/qpid/qpid_enqueuebytes b/plugins/qpid/qpid_enqueuebytes new file mode 100755 index 00000000..c2713a01 --- /dev/null +++ b/plugins/qpid/qpid_enqueuebytes @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# Plugin to monitor Apache Qpid +# +# Parameters understood: +# +# queues (required) - space separated list of queues to display (regex allowed) +# +# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) + +import re +import sys +import os +from qmf.console import Session + +if not "queues" in os.environ: + print >> sys.stderr, "Missing env.queues in config" + sys.exit(-1) + +output_queue = [] +sess = Session() +broker = sess.addBroker() +queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker") +for q in queues: + for match in os.environ["queues"].split(" "): + if re.match(match, q.name): + output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name)) + +if len(sys.argv) > 1 and sys.argv[1] == "config": + print "graph_category Qpid"; + print "graph_title Enqueue data rate"; + print "graph_vlabel bytes/second" + for queue in output_queue: + print "%s.label %s" % (queue, queue) + print "%s.min 0" % queue + print "%s.type COUNTER" % queue +else: + for q in queues: + qname = re.sub('[^a-zA-Z0-9_]', '_', q.name) + if qname in output_queue: + print "%s.value %u" % (qname, q.byteTotalEnqueues) + +sess.delBroker(broker) + diff --git a/plugins/qpid/qpid_enqueuecount b/plugins/qpid/qpid_enqueuecount new file mode 100755 index 00000000..38c34381 --- /dev/null +++ b/plugins/qpid/qpid_enqueuecount @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# Plugin to monitor Apache Qpid +# +# Parameters understood: +# +# queues (required) - space separated list of queues to display (regex allowed) +# +# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) + +import re +import sys +import os +from qmf.console import Session + +if not "queues" in os.environ: + print >> sys.stderr, "Missing env.queues in config" + sys.exit(-1) + +output_queue = [] +sess = Session() +broker = sess.addBroker() +queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker") +for q in queues: + for match in os.environ["queues"].split(" "): + if re.match(match, q.name): + output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name)) + +if len(sys.argv) > 1 and sys.argv[1] == "config": + print "graph_category Qpid"; + print "graph_title Enqueue message rate"; + print "graph_vlabel messages/second" + for queue in output_queue: + print "%s.label %s" % (queue, queue) + print "%s.min 0" % queue + print "%s.type COUNTER" % queue +else: + for q in queues: + qname = re.sub('[^a-zA-Z0-9_]', '_', q.name) + if qname in output_queue: + print "%s.value %u" % (qname, q.msgTotalEnqueues) + +sess.delBroker(broker) + diff --git a/plugins/qpid/qpid_msgdepth b/plugins/qpid/qpid_msgdepth new file mode 100755 index 00000000..c68616b8 --- /dev/null +++ b/plugins/qpid/qpid_msgdepth @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# Plugin to monitor Apache Qpid +# +# Parameters understood: +# +# queues (required) - space separated list of queues to display (regex allowed) +# +# Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) + +import re +import sys +import os +from qmf.console import Session + +if not "queues" in os.environ: + print >> sys.stderr, "Missing env.queues in config" + sys.exit(-1) + +output_queue = [] +sess = Session() +broker = sess.addBroker() +queues = sess.getObjects(_class="queue", _package="org.apache.qpid.broker") +for q in queues: + for match in os.environ["queues"].split(" "): + if re.match(match, q.name): + output_queue.append(re.sub('[^a-zA-Z0-9_]', '_', q.name)) + +if len(sys.argv) > 1 and sys.argv[1] == "config": + print "graph_category Qpid"; + print "graph_title Queue message depth"; + print "graph_vlabel messages" + for queue in output_queue: + print "%s.label %s" % (queue, queue) + print "%s.min 0" % queue + print "%s.type GAUGE" % queue +else: + for q in queues: + qname = re.sub('[^a-zA-Z0-9_]', '_', q.name) + if qname in output_queue: + print "%s.value %u" % (qname, q.msgDepth) + +sess.delBroker(broker) + From 516f91a416f58429e93dc6e94afde325ad853352 Mon Sep 17 00:00:00 2001 From: freewil Date: Tue, 11 Dec 2012 01:50:00 -0500 Subject: [PATCH 015/109] add difficulty to bitcoind_ --- plugins/other/bitcoind_ | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/other/bitcoind_ b/plugins/other/bitcoind_ index bf75a589..a62cb7a2 100755 --- a/plugins/other/bitcoind_ +++ b/plugins/other/bitcoind_ @@ -56,6 +56,7 @@ def main(): 'transactions': ("Transactions", "Transactions", ('confirmed', 'waiting')), 'block_age': ("Last Block Age", "Seconds"), + 'difficulty': ("Difficulty", ""), } labels = request_labels[request_var] if len(labels) < 3: From c26049e8d272a94190972677a81bc0a29c83aa00 Mon Sep 17 00:00:00 2001 From: Claudius Herder Date: Wed, 19 Dec 2012 18:37:51 +0100 Subject: [PATCH 016/109] Update plugins/zfs/zfs_stats_ Don't divide by zero if there is no l2arc Error output from zfs_stats_cachehitlist: dc: divide by zero --- plugins/zfs/zfs_stats_ | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/zfs/zfs_stats_ b/plugins/zfs/zfs_stats_ index 40a4072b..7252dfe0 100755 --- a/plugins/zfs/zfs_stats_ +++ b/plugins/zfs/zfs_stats_ @@ -109,8 +109,10 @@ else fi L2_ACCESSES_TOTAL=`echo "$L2_HITS+$L2_MISSES" | $BC` -L2_HIT_RATIO_PERC=`echo "scale=2 ; (100*$L2_HITS/$L2_ACCESSES_TOTAL)" | $BC` -L2_MISS_RATIO_PERC=`echo "scale=2 ; (100*$L2_MISSES/$L2_ACCESSES_TOTAL)" | $BC` +if [ $L2_ACCESSES_TOTAL -gt 0 ]; then + L2_HIT_RATIO_PERC=`echo "scale=2 ; (100*$L2_HITS/$L2_ACCESSES_TOTAL)" | $BC` + L2_MISS_RATIO_PERC=`echo "scale=2 ; (100*$L2_MISSES/$L2_ACCESSES_TOTAL)" | $BC` +fi efficiency() { if [ "$1" = "config" ]; then From feef65dba9402db36a778310f663dcabda5f3a80 Mon Sep 17 00:00:00 2001 From: deveth0 Date: Thu, 20 Dec 2012 13:42:05 +0100 Subject: [PATCH 017/109] Update plugins/system/zones_mem Increase number of displayed zones. --- plugins/system/zones_mem | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/system/zones_mem b/plugins/system/zones_mem index c39464e1..1e6c62aa 100755 --- a/plugins/system/zones_mem +++ b/plugins/system/zones_mem @@ -4,7 +4,7 @@ #%# capabilities=autoconf PRSTAT=/usr/bin/prstat -PRSTAT_OPTS="-Z 1 1" +PRSTAT_OPTS="-Z -n 1,99 1 1" if [ "$1" = 'autoconf' ]; then if [ -f $PRSTAT ]; then From 05710b1f9b15b29ff1922c8f92bd60395bbb609b Mon Sep 17 00:00:00 2001 From: Claudius Date: Thu, 20 Dec 2012 16:21:13 +0100 Subject: [PATCH 018/109] initial checkin --- plugins/zfs/zfs_usage_ | 286 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100755 plugins/zfs/zfs_usage_ diff --git a/plugins/zfs/zfs_usage_ b/plugins/zfs/zfs_usage_ new file mode 100755 index 00000000..5117e18e --- /dev/null +++ b/plugins/zfs/zfs_usage_ @@ -0,0 +1,286 @@ +#!/usr/local/bin/perl +# -*- perl + +=pod + +=head1 NAME + +zfs_usage_ - Script to monitor zfs pool usage + +=head1 CONFIGURATION + +Create one symlink per zpool for exampe zfs_usage_system + +=head1 BUGS + +=head1 AUTHOR + +2012, Claudius Herder + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf suggest + +=cut + +use strict; +use warnings; +use Munin::Plugin; +need_multigraph(); + +my $filesystems; +my $zpool; +my $zpoolexec="/sbin/zpool"; +my $zfsexec="/sbin/zfs"; + +my $properties = { + available => "Read-only property that identifies the amount of disk" + ." space available to a file system and all its children," + ." assuming no other activity in the pool. Because disk" + ." space is shared within a pool, available space can be" + ." limited by various factors including physical pool size," + ." quotas, reservations, and other datasets within the" + ." pool.", + + quota => "Limits the amount of disk space a file system and its" + ." descendents can consume. This property enforces a" + ." hard limit on the amount of disk space used, including" + ." all space consumed by descendents, such as file systems" + ." and snapshots. Setting a quota on a descendent of a file" + ." system that already has a quota does not override the" + ." ancestor's quota, but rather imposes an additional" + ." limit. Quotas cannot be set on volumes, as the volsize" + ." property acts as an implicit quota.", + + referenced => "Read-only property that identifies the amount of data" + ." accessible by a dataset, which might or might not be" + ." shared with other datasets in the pool." + ." When a snapshot or clone is created, it initially" + ." references the same amount of disk space as the file" + ." system or snapshot it was created from, because its" + ." contents are identical.", + + refquota => "Sets the amount of disk space that a dataset can" + ." consume. This property enforces a hard limit on the" + ." amount of space used. This hard limit does not include" + ." disk space used by descendents, such as snapshots and" + ." clones.", + + refreservation => "Sets the minimum amount of disk space that is" + ." guaranteed to a dataset, not including descendents," + ." such as snapshots and clones. When the amount of disk" + ." space used is below this value, the dataset is treated as if" + ." it were taking up the amount of space specified by" + ." refreservation. The refreservation reservation is" + ." accounted for in the parent dataset's disk space used," + ." and counts against the parent dataset's quotas and" + ." reservations." + ." If refreservation is set, a snapshot is only allowed if" + ." enough free pool space is available outside of this" + ." reservation to accommodate the current number of" + ." referenced bytes in the dataset.", + + reservation => "Sets the minimum amount of disk space guaranteed to" + ." a file system and its descendents. When the amount of" + ." disk space used is below this value, the file system is" + ." treated as if it were using the amount of space specified" + ." by its reservation. Reservations are accounted for in the" + ." parent file system's disk space used, and count against" + ." the parent file system's quotas and reservations.", + + type => "Read-only property that identifies the dataset type as" + ." filesystem (file system or clone), volume, or" + ." snapshot.", + + used => "Read-only property that identifies the amount of disk" + ." space consumed by a dataset and all its descendents.", + + usedbychildren => "Read-only property that identifies the amount of disk" + ." space that is used by children of this dataset, which" + ." would be freed if all the dataset's children were" + ." destroyed. The property abbreviation is usedchild.", + + usedbydataset => "Read-only property that identifies the amount of disk" + ." space that is used by a dataset itself, which would be" + ." freed if the dataset was destroyed, after first destroying" + ." any snapshots and removing any refreservation" + ." reservations. The property abbreviation is usedds.", + + usedbyrefreservation=> "Read-only property that identifies the amount of disk" + ." space that is used by a refreservation set on a dataset," + ." which would be freed if the refreservation was" + ." removed.", + + usedbysnapshots => "Read-only property that identifies the amount of disk" + ." space that is consumed by snapshots of a dataset. In" + ." particular, it is the amount of disk space that would be" + ." freed if all of this dataset's snapshots were destroyed." + ." Note that this value is not simply the sum of the" + ." snapshots' used properties, because space can be" + ." shared by multiple snapshots.", + volsize => "For volumes, specifies the logical size of the volume.", +}; + +my @order = ( +"usedbydataset", +"usedbysnapshots", +"usedbyrefreservation", +"usedbychildren", +"available", +"quota", +"refquota", +"referenced", +"reservation", +"refreservation", +"used", +"volsize", +); + +sub do_collect { + + my $fslist=(`$zfsexec list -H -r -o name $zpool`); + + my @params = join(',',( keys %{$properties} )); + + my $fsget="$zfsexec get -H -p @params"; + + foreach my $fsname (split(/\n/,$fslist)) { + foreach my $line (split(/\n/, `$fsget $fsname` )) { + my ($name, $key, $value, undef ) = (split(/\t/,$line)); + ($name =~ s/\//_/g); + $filesystems->{$name}->{$key}=$value; + } + } +} + + +sub do_config_fs { + my ($fs) = @_; + my $fs_slash = ($fs); + ($fs_slash =~ s/_/\//g); + + if ( $fs ne $zpool ) { + print "multigraph zfs_usage_$zpool.$fs\n"; + print "graph_title ZFS usage for $filesystems->{$fs}->{type} $fs_slash\n"; + print "graph_info This graph shows used bytes of $filesystems->{$fs}->{type} $fs_slash\n"; + } else { + print "multigraph zfs_usage_$zpool\n"; + print "graph_title ZFS usage for zpool $zpool\n"; + print "graph_info This graph shows used bytes of zpool $zpool\n"; + } + print "graph_args --base 1024 --lower-limit 0 --rigid\n"; + print "graph_vlabel bytes \n"; + print "graph_category zfs\n"; + print "graph_order @order\n"; + + foreach my $key ( keys %{$filesystems->{$fs}}) { + if ( $key ne "type" ) { + if ( $filesystems->{$fs}->{type} eq "volume" && $key =~ /quota/ ) { + } + elsif ($filesystems->{$fs}->{type} eq "filesystem" && $key eq "volsize") { + } + else { + print "$key.label $key\n"; + print "$key.min 0\n"; + print "$key.type GAUGE\n"; + print "$key.info $properties->{$key}\n"; + if ( $key =~ /quota|referenced|^(ref)*reservation|^used$|volsize/ ) { + print "$key.draw LINE3\n"; + } + else { + print "$key.draw AREASTACK\n"; + } + } + } + } +} + + +sub do_fetch_fs { + my ($fs) = @_; + + if ( $fs ne $zpool ) { + print "multigraph zfs_usage_$zpool.$fs\n"; + } else { + print "multigraph zfs_usage_$zpool\n"; + } + + foreach my $key ( keys %{$filesystems->{$fs}}) { + if ( $key ne "type" ) { + if ( $filesystems->{$fs}->{type} eq "volume" && $key =~ /quota/ ) { + } + elsif ($filesystems->{$fs}->{type} eq "filesystem" && $key eq "volsize") { + } + else { + print "$key.value $filesystems->{$fs}->{$key}\n"; + } + } + } +} + +sub do_config { + + foreach my $fs ( sort keys %{$filesystems}) { + do_config_fs($fs); + } +} + +sub do_autoconf { + + if (`which $zpoolexec 2>/dev/null` =~ m{^/}) { + print "yes\n"; + } else { + print "no ($zpoolexec could not be found)\n"; + } + exit 0; +} + + +sub do_suggest { + my $poollist=(`zpool list -H -o name`); + print "$poollist"; +} + +sub do_fetch { + + foreach my $fs ( sort keys %{$filesystems}) { + do_fetch_fs($fs); + } +} + +sub do_setpool { + if ( $0 =~ /zfs_usage_$/) { + die ("Can't run without a symlinked name\n") + } + elsif ($0 =~ /zfs_usage_(.+)*$/) { + $zpool = $1; + } + +} + +if ($ARGV[0]) { + if ($ARGV[0] eq "config") { + do_setpool(); + do_collect(); + do_config(); + exit 0; + } + elsif ($ARGV[0] eq "autoconf") { + do_autoconf(); + exit 0; + } + elsif ($ARGV[0] eq "suggest") { + do_suggest(); + exit 0; + } +} +else { + do_setpool(); + do_collect(); + do_fetch(); +} + +exit 0; + +__END__ From a129a67998110cda8cafcc4dbcb09882d39156fe Mon Sep 17 00:00:00 2001 From: Claudius Date: Thu, 20 Dec 2012 17:11:29 +0100 Subject: [PATCH 019/109] add license --- plugins/zfs/zfs_usage_ | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/zfs/zfs_usage_ b/plugins/zfs/zfs_usage_ index 5117e18e..4aeb17e9 100755 --- a/plugins/zfs/zfs_usage_ +++ b/plugins/zfs/zfs_usage_ @@ -22,6 +22,10 @@ Create one symlink per zpool for exampe zfs_usage_system #%# family=auto #%# capabilities=autoconf suggest +=head1 LICENSE + +GPLv2 + =cut use strict; From 5ebdabf44a4819b834f633d8e2978a3aa79d591d Mon Sep 17 00:00:00 2001 From: Kenyon Ralph Date: Sun, 23 Dec 2012 20:49:42 -0800 Subject: [PATCH 020/109] whitespace cleanup --- plugins/zfs/zfs_usage_ | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/plugins/zfs/zfs_usage_ b/plugins/zfs/zfs_usage_ index 4aeb17e9..d3700a6f 100755 --- a/plugins/zfs/zfs_usage_ +++ b/plugins/zfs/zfs_usage_ @@ -15,7 +15,7 @@ Create one symlink per zpool for exampe zfs_usage_system =head1 AUTHOR -2012, Claudius Herder +2012, Claudius Herder =head1 MAGIC MARKERS @@ -95,7 +95,7 @@ my $properties = { type => "Read-only property that identifies the dataset type as" ." filesystem (file system or clone), volume, or" - ." snapshot.", + ." snapshot.", used => "Read-only property that identifies the amount of disk" ." space consumed by a dataset and all its descendents.", @@ -142,7 +142,6 @@ my @order = ( ); sub do_collect { - my $fslist=(`$zfsexec list -H -r -o name $zpool`); my @params = join(',',( keys %{$properties} )); @@ -150,8 +149,8 @@ sub do_collect { my $fsget="$zfsexec get -H -p @params"; foreach my $fsname (split(/\n/,$fslist)) { - foreach my $line (split(/\n/, `$fsget $fsname` )) { - my ($name, $key, $value, undef ) = (split(/\t/,$line)); + foreach my $line (split(/\n/, `$fsget $fsname` )) { + my ($name, $key, $value, undef ) = (split(/\t/,$line)); ($name =~ s/\//_/g); $filesystems->{$name}->{$key}=$value; } @@ -173,11 +172,11 @@ sub do_config_fs { print "graph_title ZFS usage for zpool $zpool\n"; print "graph_info This graph shows used bytes of zpool $zpool\n"; } - print "graph_args --base 1024 --lower-limit 0 --rigid\n"; + print "graph_args --base 1024 --lower-limit 0 --rigid\n"; print "graph_vlabel bytes \n"; print "graph_category zfs\n"; print "graph_order @order\n"; - + foreach my $key ( keys %{$filesystems->{$fs}}) { if ( $key ne "type" ) { if ( $filesystems->{$fs}->{type} eq "volume" && $key =~ /quota/ ) { @@ -224,20 +223,18 @@ sub do_fetch_fs { } sub do_config { - foreach my $fs ( sort keys %{$filesystems}) { do_config_fs($fs); } } sub do_autoconf { - - if (`which $zpoolexec 2>/dev/null` =~ m{^/}) { - print "yes\n"; - } else { - print "no ($zpoolexec could not be found)\n"; - } - exit 0; + if (`which $zpoolexec 2>/dev/null` =~ m{^/}) { + print "yes\n"; + } else { + print "no ($zpoolexec could not be found)\n"; + } + exit 0; } @@ -247,7 +244,6 @@ sub do_suggest { } sub do_fetch { - foreach my $fs ( sort keys %{$filesystems}) { do_fetch_fs($fs); } @@ -260,15 +256,14 @@ sub do_setpool { elsif ($0 =~ /zfs_usage_(.+)*$/) { $zpool = $1; } - } if ($ARGV[0]) { if ($ARGV[0] eq "config") { - do_setpool(); - do_collect(); - do_config(); - exit 0; + do_setpool(); + do_collect(); + do_config(); + exit 0; } elsif ($ARGV[0] eq "autoconf") { do_autoconf(); @@ -278,11 +273,11 @@ if ($ARGV[0]) { do_suggest(); exit 0; } -} +} else { - do_setpool(); - do_collect(); - do_fetch(); + do_setpool(); + do_collect(); + do_fetch(); } exit 0; From b7e0cab72e38133f7f834ea9085d2bf270da5e62 Mon Sep 17 00:00:00 2001 From: Kenyon Ralph Date: Mon, 24 Dec 2012 18:28:38 -0800 Subject: [PATCH 021/109] add some description --- plugins/system/zones_mem | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/system/zones_mem b/plugins/system/zones_mem index 1e6c62aa..d32566d4 100755 --- a/plugins/system/zones_mem +++ b/plugins/system/zones_mem @@ -1,5 +1,7 @@ #!/bin/sh +# This plugin shows Solaris zone memory usage. + #%# family=auto #%# capabilities=autoconf From 94c0585a593aa357058ab192563470010d174091 Mon Sep 17 00:00:00 2001 From: Kenyon Ralph Date: Mon, 24 Dec 2012 18:29:12 -0800 Subject: [PATCH 022/109] whitespace cleanup --- plugins/system/zones_mem | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/plugins/system/zones_mem b/plugins/system/zones_mem index d32566d4..9d216065 100755 --- a/plugins/system/zones_mem +++ b/plugins/system/zones_mem @@ -10,12 +10,12 @@ PRSTAT_OPTS="-Z -n 1,99 1 1" if [ "$1" = 'autoconf' ]; then if [ -f $PRSTAT ]; then - zones=`/usr/sbin/zoneadm list | wc -l` - if [ $zones -gt 1 ]; then - echo yes - else - echo yes - fi + zones=`/usr/sbin/zoneadm list | wc -l` + if [ $zones -gt 1 ]; then + echo yes + else + echo yes + fi exit 0 else echo no @@ -26,18 +26,18 @@ fi if [ "$1" = 'config' ]; then echo 'graph_title zone memory usage' echo 'graph_args --upper-limit 100' - echo 'graph_category system' - stack=AREA + echo 'graph_category system' + stack=AREA $PRSTAT $PRSTAT_OPTS | sed '1,/^ZONEID/d' | grep -v '^Total' | while read i; do - oIFS="$IFS" - IFS=' + oIFS="$IFS" + IFS=' ' - set -$- $i - name=$1 - label=$8 + set -$- $i + name=$1 + label=$8 printf "$name.label $label\n$name.draw $stack\n$name.warn 95\n" - IFS="$oIFS" - stack=STACK + IFS="$oIFS" + stack=STACK done exit 0 fi @@ -50,12 +50,12 @@ fi # Total: 207 processes, 709 lwps, load averages: 0.05, 0.06, 0.11$ $PRSTAT $PRSTAT_OPTS | sed '1,/^ZONEID/d' | grep -v '^Total' | while read i; do - oIFS="$IFS" - IFS='% + oIFS="$IFS" + IFS='% ' - set -$- $i - name=$1 - value=$5 - printf "$name.value $value\n" - IFS="$oIFS" + set -$- $i + name=$1 + value=$5 + printf "$name.value $value\n" + IFS="$oIFS" done From 548a2b626eb6a794ccd194d943bcc956e14908c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sun, 30 Dec 2012 09:23:18 -0800 Subject: [PATCH 023/109] freeipmi: implement suggestions from Bart ten Brinke for FreeIPMI 1.1.x. This adds support for versions of FreeIPMI before 1.2 (without the threshold information), and explicits the dependency information. It also works with older Munin nodes where dirtyconfig is not supported. --- plugins/sensors/freeipmi | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/plugins/sensors/freeipmi b/plugins/sensors/freeipmi index 0d34fb06..6016eb26 100755 --- a/plugins/sensors/freeipmi +++ b/plugins/sensors/freeipmi @@ -17,10 +17,29 @@ When used for the local host, the plugin should be linked as non-wildcard plugin, i.e., 'freeipmi', whereas when used to monitor a foreign host it should be, e.g., 'freeipmi_192.168.0.253'. +=head1 DEPENDENCIES + +The plugin requires FreeIPMI 1.1.5 or later to fetch the information. +Limits set on thresholds are available when using FreeIPMI 1.2.0 or +later. + =head1 AUTHOR Diego Elio Pettenò . +With help and suggestions of: + +Bart ten Brinke + +=head1 LICENSE + +GPLv2 + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf + =head1 LICENSE GPLv2 @@ -42,12 +61,15 @@ my $IPMISENSORS = $ENV{'ipmisensors'} || 'ipmi-sensors'; $0 =~ /freeipmi(?:_(.+))$/; my $hostname = $1; -$IPMISENSORS .= " --quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors --sensor-types=Temperature,Fan,Current,Voltage --output-sensor-thresholds"; +my $help_output = `$IPMISENSORS --help`; + +$IPMISENSORS .= " --output-sensor-thresholds" if $help_output =~ /--output-sensor-thresholds/; +$IPMISENSORS .= " --quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors --sensor-types=Temperature,Fan,Current,Voltage"; $IPMISENSORS .= " --hostname=$hostname" if defined($hostname); $IPMISENSORS .= " --username=$ENV{IPMI_USERNAME}" if defined($ENV{IPMI_USERNAME}); $IPMISENSORS .= " --password=$ENV{IPMI_PASSWORD}" if defined($ENV{IPMI_PASSWORD}); -my $output=`$IPMISENSORS --output-sensor-thresholds 2>/dev/null`; +my $output=`$IPMISENSORS 2>/dev/null`; my $retval=$?; if ( defined $ARGV[0] and $ARGV[0] eq 'autoconf' ) { @@ -158,7 +180,7 @@ END } } - unless ( $ENV{MUNIN_CAP_DIRTYCONFIG} == 1 ) { + unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) { exit 0; } } From 5b22647d681bfacc282723c215d5230f0eee67c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sun, 30 Dec 2012 09:27:05 -0800 Subject: [PATCH 024/109] hwmon: support non-dirtyconfig capable nodes. --- plugins/sensors/hwmon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/sensors/hwmon b/plugins/sensors/hwmon index 5e755436..66e44801 100755 --- a/plugins/sensors/hwmon +++ b/plugins/sensors/hwmon @@ -173,7 +173,7 @@ END } } - unless ( $ENV{MUNIN_CAP_DIRTYCONFIG} == 1 ) { + unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) { exit 0; } } From fce750234234d3dc3d74584cd3746e6f1b968e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sun, 30 Dec 2012 12:22:52 -0800 Subject: [PATCH 025/109] asterisk: first part of the new Asterisk plugin. This plugin is targeting to enter main distribution in 2.1 to remove the multiple Asterisk plugins present in 2.0. It features full autoconfiguration support, multigraph capabilities, and less error-prone code. For the moment, it only implements a replacement for asterisk_channels. --- plugins/asterisk/asterisk | 141 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100755 plugins/asterisk/asterisk diff --git a/plugins/asterisk/asterisk b/plugins/asterisk/asterisk new file mode 100755 index 00000000..2e023ddd --- /dev/null +++ b/plugins/asterisk/asterisk @@ -0,0 +1,141 @@ +#!/usr/bin/perl -w +# -*- cperl -*- + +=head1 NAME + +asterisk - Multigraph-capable plugin to monitor Asterisk + +=head1 CONFIGURATION + +The following configuration parameters are used by this plugin + + [asterisk] + env.host - hostname to connect to + env.port - port number to connect to + env.username - username used for authentication + env.secret - secret used for authentication + +The "username" and "secret" parameters are mandatory, and have no +defaults. + +=head2 DEFAULT CONFIGURATION + + [asterisk] + env.host 127.0.0.1 + env.port 5038 + +=head2 WILDCARD CONFIGURATION + +It's possible to use the plugin in a virtual-node capacity, in which +case the host configuration will default to the hostname following the +underscore: + + [asterisk_someserver] + env.host someserver + env.port 5038 + +=head1 AUTHOR + +Copyright (C) 2005 Rodolphe Quiedeville +Copyright (C) 2012 Diego Elio Pettenò + +=head1 LICENSE + +GPLv2 + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf + +=cut + +use strict; +use Munin::Plugin; +use IO::Socket; + +sub readreply { + my $socket = shift; + my $line; + my $return; + + while ( $line = $socket->getline and $line ne "\r\n" ) { + $return .= $line; + } + + return $return; +} + +$0 =~ /asterisk(?:_(.+))$/; +my $hostname = $1; + +my $peeraddr = $ENV{'host'} || $hostname || '127.0.0.1'; +my $peerport = $ENV{'port'} || '5038'; + +my $username = $ENV{'username'}; +my $secret = $ENV{'secret'}; + +my $line, my $error; +my $socket = new IO::Socket::INET(PeerAddr => $peeraddr, + PeerPort => $peerport, + Proto => 'tcp') + or $error = "Could not create socket: $!"; + +if ( $socket ) { + # This will consume the "Asterisk Call Manager" welcome line. + $socket->getline; + + $socket->print("Action: login\nUsername: $username\nSecret: $secret\nEvents: off\n\n"); + my $auth_status = readreply $socket; + + if ( $auth_status !~ /^Response: Success/ ) { + $auth_status =~ s/.*\nMessage: (.*)\r\n/$1/; + $error = "Asterisk authentication error: " . $auth_status; + $socket->close(); + $socket = undef; + } +} + +if ( $ARGV[0] and $ARGV[0] eq 'autoconf' ) { + if ( $error ) { + print "no ($error)\n"; + } else { + print "yes\n"; + } + + exit 0; +} elsif ( $ARGV[0] and $ARGV[0] eq 'config' ) { + print "host_name $hostname" if $hostname; + + print <print("Action: command\nCommand: core show channels\n\n"); +my $shown_channels = readreply $socket; + +my $channels = 'U'; +$channels = $1 if $shown_channels =~ /\n([0-9]+) active channels/; + +print <close(); From f5064c93983c8d89510c5333e5b6f571ab6403d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sun, 30 Dec 2012 12:44:29 -0800 Subject: [PATCH 026/109] asterisk: add support for showing the per-type breakdown of channels. This makes it possible for a single graph to replace the two apache_channels and apache_channeltypes plugins. --- plugins/asterisk/asterisk | 44 +++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/plugins/asterisk/asterisk b/plugins/asterisk/asterisk index 2e023ddd..2cf93cd9 100755 --- a/plugins/asterisk/asterisk +++ b/plugins/asterisk/asterisk @@ -5,6 +5,14 @@ asterisk - Multigraph-capable plugin to monitor Asterisk +=head1 NOTES + +This plugin will produce multiple graphs showing: + + - total number of active channels (replaces asterisk_channels), + together with breakdown of specific channel types (replaces + asterisk_channelstypes). + =head1 CONFIGURATION The following configuration parameters are used by this plugin @@ -14,6 +22,7 @@ The following configuration parameters are used by this plugin env.port - port number to connect to env.username - username used for authentication env.secret - secret used for authentication + env.channels - The channel types to look for The "username" and "secret" parameters are mandatory, and have no defaults. @@ -23,6 +32,7 @@ defaults. [asterisk] env.host 127.0.0.1 env.port 5038 + env.channels Zap IAX2 SIP =head2 WILDCARD CONFIGURATION @@ -75,6 +85,8 @@ my $peerport = $ENV{'port'} || '5038'; my $username = $ENV{'username'}; my $secret = $ENV{'secret'}; +my @CHANNELS = exists $ENV{'channels'} ? split ' ',$ENV{'channels'} : qw(Zap IAX2 SIP); + my $line, my $error; my $socket = new IO::Socket::INET(PeerAddr => $peeraddr, PeerPort => $peerport, @@ -114,10 +126,16 @@ graph_title Asterisk active channels graph_args --base 1000 -l 0 graph_vlabel channels graph_category asterisk -channels.draw AREA -channels.label channels +total.label channels END + foreach my $channel (@CHANNELS) { + print <print("Action: command\nCommand: core show channels\n\n"); +#Response: Follows +#Channel Location State Application(Data) +#Zap/pseudo-198641660 s@frompstn:1 Rsrvd (None) +#Zap/1-1 4@frompstn:1 Up MeetMe(5500) +#2 active channels +#1 active call +#--END COMMAND-- my $shown_channels = readreply $socket; -my $channels = 'U'; -$channels = $1 if $shown_channels =~ /\n([0-9]+) active channels/; +$socket->close(); + +my $active_channels = 'U'; +$active_channels = $1 if $shown_channels =~ /\n([0-9]+) active channels/; print <close(); +my @channels_list = split(/\r\n/, $shown_channels); +foreach my $channel (@CHANNELS) { + print "$channel.value " . + scalar(grep(/^$channel\//, @channels_list)) + . "\n"; +} From 9f56a03d058b152cad46938ab7eb25dd5ccaa8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sun, 30 Dec 2012 13:04:25 -0800 Subject: [PATCH 027/109] asterisk: add asterisk_voicemail replacement code as well. This is a bit trickier, since the voicemail might not be enabled anywhere. Unfortunately it's not easy to set this up during autoconfig, as voicemails can be added on the fly. --- plugins/asterisk/asterisk | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/plugins/asterisk/asterisk b/plugins/asterisk/asterisk index 2cf93cd9..fe507b97 100755 --- a/plugins/asterisk/asterisk +++ b/plugins/asterisk/asterisk @@ -11,7 +11,10 @@ This plugin will produce multiple graphs showing: - total number of active channels (replaces asterisk_channels), together with breakdown of specific channel types (replaces - asterisk_channelstypes). + asterisk_channelstypes); + + - the number of messages in all voicemail boxes (replaces + asterisk_voicemail). =head1 CONFIGURATION @@ -136,6 +139,16 @@ $channel.label $channel channels END } +print <print("Action: command\nCommand: core show channels\n\n"); #--END COMMAND-- my $shown_channels = readreply $socket; +$socket->print("Action: command\nCommand: voicemail show users\n\n"); +#Response: Follows +#Context Mbox User Zone NewMsg +#default 1234 Example Mailbox 1 +#other 1234 Company2 User 0 +#2 voicemail users configured. +#--END COMMAND-- +my $voicemail_response = readreply $socket; +$voicemail_response = undef if $voicemail_response =~ /Response: Error/; + $socket->close(); my $active_channels = 'U'; @@ -171,3 +194,16 @@ foreach my $channel (@CHANNELS) { scalar(grep(/^$channel\//, @channels_list)) . "\n"; } + +print "\nmultigraph asterisk_voicemail\n"; +if ( !$voicemail_response or $voicemail_response =~ /no voicemail users/ ) { + print "total.value U\n"; +} else { + my $messages = 0; + foreach my $line (split(/\r\n/, $voicemail_response)) { + next unless $line =~ / ([0-9]+)$/; + $messages += $1; + } + + print "total.value $messages\n"; +} From b77eef4a62898157bfcc8ca38169c413754aab6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sun, 30 Dec 2012 13:07:24 -0800 Subject: [PATCH 028/109] asterisk: handle more gracefully errors on the asterisk_channels path. --- plugins/asterisk/asterisk | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/asterisk/asterisk b/plugins/asterisk/asterisk index fe507b97..b6d6bd14 100755 --- a/plugins/asterisk/asterisk +++ b/plugins/asterisk/asterisk @@ -165,7 +165,8 @@ $socket->print("Action: command\nCommand: core show channels\n\n"); #2 active channels #1 active call #--END COMMAND-- -my $shown_channels = readreply $socket; +my $channels_response = readreply $socket; +$channels_response = undef if $channels_response =~ /Response: Error/; $socket->print("Action: command\nCommand: voicemail show users\n\n"); #Response: Follows @@ -180,7 +181,7 @@ $voicemail_response = undef if $voicemail_response =~ /Response: Error/; $socket->close(); my $active_channels = 'U'; -$active_channels = $1 if $shown_channels =~ /\n([0-9]+) active channels/; +$active_channels = $1 if $channels_response =~ /\n([0-9]+) active channels/; print < Date: Sun, 30 Dec 2012 13:36:36 -0800 Subject: [PATCH 029/109] asterisk: refactor command/response handling. Instead of having a dumb readreply, already drop some of the unneeded lines of the command when sending the request, and handle errors in place. This simplifies the code a little, even though it requires a few more "discard loops" in the code (to avoid garbage in Asterisk's logs). --- plugins/asterisk/asterisk | 56 ++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/plugins/asterisk/asterisk b/plugins/asterisk/asterisk index b6d6bd14..5f310ae2 100755 --- a/plugins/asterisk/asterisk +++ b/plugins/asterisk/asterisk @@ -67,16 +67,31 @@ use strict; use Munin::Plugin; use IO::Socket; -sub readreply { - my $socket = shift; - my $line; - my $return; +sub asterisk_command { + my ($socket, $command) = @_; + my $line, my $reply; - while ( $line = $socket->getline and $line ne "\r\n" ) { - $return .= $line; + $socket->print("Action: command\nCommand: $command\n\n"); + + # Response: (Error|Follows|???) + $line = $socket->getline; + if ($line ne "Response: Follows\r\n") { + while ( $line = $socket->getline and $line ne "\r\n" ) {} + return undef; } - return $return; + # Privilege: Command + $line = $socket->getline; + + # Until we get the --END COMMAND-- marker, it's the command's output. + while ( $line = $socket->getline and $line ne "--END COMMAND--\r\n" ) { + $reply .= $line; + } + + # And then wait for the empty line that says we're done + while ( $line = $socket->getline and $line ne "\r\n" ) {} + + return $reply; } $0 =~ /asterisk(?:_(.+))$/; @@ -101,14 +116,15 @@ if ( $socket ) { $socket->getline; $socket->print("Action: login\nUsername: $username\nSecret: $secret\nEvents: off\n\n"); - my $auth_status = readreply $socket; + my $response_status = $socket->getline; - if ( $auth_status !~ /^Response: Success/ ) { - $auth_status =~ s/.*\nMessage: (.*)\r\n/$1/; - $error = "Asterisk authentication error: " . $auth_status; - $socket->close(); - $socket = undef; + if ( $response_status ne "Response: Success\r\n" ) { + my $response_message = $socket->getline; + $response_message =~ s/Message: (.*)\r\n/$1/; + $error = "Asterisk authentication error: " . $response_message; } + + while ( $line = $socket->getline and $line ne "\r\n" ) {} } if ( $ARGV[0] and $ARGV[0] eq 'autoconf' ) { @@ -155,28 +171,20 @@ END } # if we arrive here and we don't have a socket, it's time to exit. -die $error unless $socket; +die $error if $error; -$socket->print("Action: command\nCommand: core show channels\n\n"); -#Response: Follows +my $channels_response = asterisk_command($socket, "core show channels"); #Channel Location State Application(Data) #Zap/pseudo-198641660 s@frompstn:1 Rsrvd (None) #Zap/1-1 4@frompstn:1 Up MeetMe(5500) #2 active channels #1 active call -#--END COMMAND-- -my $channels_response = readreply $socket; -$channels_response = undef if $channels_response =~ /Response: Error/; -$socket->print("Action: command\nCommand: voicemail show users\n\n"); -#Response: Follows +my $voicemail_response = asterisk_command($socket, "voicemail show users"); #Context Mbox User Zone NewMsg #default 1234 Example Mailbox 1 #other 1234 Company2 User 0 #2 voicemail users configured. -#--END COMMAND-- -my $voicemail_response = readreply $socket; -$voicemail_response = undef if $voicemail_response =~ /Response: Error/; $socket->close(); From 608c1a90ef820e863407949f557ae76918455cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Elio=20Petten=C3=B2?= Date: Sun, 30 Dec 2012 13:38:41 -0800 Subject: [PATCH 030/109] asterisk: add graph to replace asterisk_meetme and asterisk_meetmeusers. --- plugins/asterisk/asterisk | 45 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/plugins/asterisk/asterisk b/plugins/asterisk/asterisk index 5f310ae2..f1949651 100755 --- a/plugins/asterisk/asterisk +++ b/plugins/asterisk/asterisk @@ -14,7 +14,10 @@ This plugin will produce multiple graphs showing: asterisk_channelstypes); - the number of messages in all voicemail boxes (replaces - asterisk_voicemail). + asterisk_voicemail); + + - the number of active MeetMe conferences and users connected to them + (replace asterisk_meetme and asterisk_meetmeusers, respectively). =head1 CONFIGURATION @@ -163,6 +166,16 @@ graph_args --base 1000 -l 0 graph_vlabel messages graph_category asterisk messages.label Total messages +END + +print <close(); my $active_channels = 'U'; @@ -216,3 +236,26 @@ if ( !$voicemail_response or $voicemail_response =~ /no voicemail users/ ) { print "total.value $messages\n"; } + +print "\nmultigraph asterisk_meetme\n"; +if ( !$meetme_response ) { + print < Date: Sun, 30 Dec 2012 14:02:17 -0800 Subject: [PATCH 031/109] asterisk: replace the remaining two Asterisk plugins. The fourth graph (asterisk_codecs) replaces both asterisk_sipchannels and asterisk_codecs, as the latter already included the data from the first. If we want to get more details we could have sub-multigraphs for a breakdown of the codecs per channel type, but right now it feels unneeded. --- plugins/asterisk/asterisk | 121 +++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 2 deletions(-) diff --git a/plugins/asterisk/asterisk b/plugins/asterisk/asterisk index f1949651..7a3c13ce 100755 --- a/plugins/asterisk/asterisk +++ b/plugins/asterisk/asterisk @@ -17,7 +17,10 @@ This plugin will produce multiple graphs showing: asterisk_voicemail); - the number of active MeetMe conferences and users connected to them - (replace asterisk_meetme and asterisk_meetmeusers, respectively). + (replace asterisk_meetme and asterisk_meetmeusers, respectively); + + - the number of active channels for a given codec, for both SIP and + IAX2 channels (replaces asterisk_sipchannels and asterisk_codecs). =head1 CONFIGURATION @@ -29,6 +32,8 @@ The following configuration parameters are used by this plugin env.username - username used for authentication env.secret - secret used for authentication env.channels - The channel types to look for + env.codecsx - List of codec IDs (hexadecimal values) + env.codecs - List of codecs names, matching codecsx order The "username" and "secret" parameters are mandatory, and have no defaults. @@ -39,6 +44,8 @@ defaults. env.host 127.0.0.1 env.port 5038 env.channels Zap IAX2 SIP + env.codecsx 0x2 0x4 0x8 + env.codecs gsm ulaw alaw =head2 WILDCARD CONFIGURATION @@ -52,7 +59,7 @@ underscore: =head1 AUTHOR -Copyright (C) 2005 Rodolphe Quiedeville +Copyright (C) 2005-2006 Rodolphe Quiedeville Copyright (C) 2012 Diego Elio Pettenò =head1 LICENSE @@ -107,6 +114,8 @@ my $username = $ENV{'username'}; my $secret = $ENV{'secret'}; my @CHANNELS = exists $ENV{'channels'} ? split ' ',$ENV{'channels'} : qw(Zap IAX2 SIP); +my @CODECS = exists $ENV{'codecs'} ? split ' ',$ENV{'codecs'} : qw(gsm ulaw alaw); +my @CODECSX = exists $ENV{'codecsx'} ? split ' ',$ENV{'codecsx'} : qw(0x2 0x4 0x8); my $line, my $error; my $socket = new IO::Socket::INET(PeerAddr => $peeraddr, @@ -176,6 +185,29 @@ graph_args --base 1000 -l 0 graph_category asterisk users.label Connected users conferences.label Active conferences +END + +print <close(); @@ -259,3 +301,78 @@ END print "conferences.value " . (scalar(@meetme_list)-1) . "\n"; } } + +print "\nmultigraph asterisk_codecs\n"; +if ( !$sipchannels_response and !$iaxchannels_response ) { + foreach my $codec (@CODECS) { + print "$codec.value U\n"; + } + print < Date: Mon, 31 Dec 2012 09:29:37 +0100 Subject: [PATCH 032/109] Fixed undefined warnings --- plugins/sensors/freeipmi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/sensors/freeipmi b/plugins/sensors/freeipmi index 6016eb26..feb64189 100755 --- a/plugins/sensors/freeipmi +++ b/plugins/sensors/freeipmi @@ -131,11 +131,11 @@ foreach my $line (@data) { value => $dataline[3], label => $dataline[1] ); - $sensor{lwarn} = $dataline[7] ne "N/A" ? $dataline[7] : ''; - $sensor{hwarn} = $dataline[8] ne "N/A" ? $dataline[8] : ''; + $sensor{lwarn} = (defined($dataline[7]) and $dataline[7] ne "N/A") ? $dataline[7] : ''; + $sensor{hwarn} = (defined($dataline[8]) and $dataline[8] ne "N/A") ? $dataline[8] : ''; - $sensor{lcrit} = $dataline[6] ne "N/A" ? $dataline[6] : ''; - $sensor{hcrit} = $dataline[9] ne "N/A" ? $dataline[9] : ''; + $sensor{lcrit} = (defined($dataline[6]) and $dataline[6] ne "N/A") ? $dataline[6] : ''; + $sensor{hcrit} = (defined($dataline[9]) and $dataline[9] ne "N/A") ? $dataline[9] : ''; my $type; if ( $dataline[2] eq "Temperature" ) { From a38bb464b3bd00917ca0415bbe0b6a2053bd8548 Mon Sep 17 00:00:00 2001 From: louis Date: Fri, 4 Jan 2013 18:53:51 +0100 Subject: [PATCH 033/109] set executable bit for netatalk plugin --- plugins/network/netatalk | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 plugins/network/netatalk diff --git a/plugins/network/netatalk b/plugins/network/netatalk old mode 100644 new mode 100755 From 1c60f63b11a526b0bf0c983fbef6230717208448 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 10 Jan 2013 10:27:35 +0100 Subject: [PATCH 034/109] db2_cnx: adding a plugin for monitoring DB2 connections --- plugins/db2/db2_cnx | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 plugins/db2/db2_cnx diff --git a/plugins/db2/db2_cnx b/plugins/db2/db2_cnx new file mode 100644 index 00000000..d6d60ad1 --- /dev/null +++ b/plugins/db2/db2_cnx @@ -0,0 +1,37 @@ +#! /bin/sh +# (c) 2012 - Steve Schnepp - LGPL + +# XXX - coded hastily + +# Source the DB2 profile +. /home/db2inst1/sqllib/db2profile + +echo "graph_title Number of connections" +echo "graph_category DB2" +echo "graph_args -l 0" + +db2 list application | tail +5 | awk ' /^[A-Z]/ { print $1 }' | sort | uniq -c > $HOME/run/$(basename $0).txt + +# Get users list +touch $HOME/run/$(basename $0).users +awk '{ print $2 }' $HOME/run/$(basename $0).txt | cat $HOME/run/$(basename $0).users - | sort -ru > $HOME/run/$(basename $0).users.tmp +mv $HOME/run/$(basename $0).users.tmp $HOME/run/$(basename $0).users + +# Emit config +if [ "$1" = "config" ] +then + awk ' { print $1 ".label " $1 "\n" $1 ".draw AREASTACK" }' $HOME/run/$(basename $0).users +fi + +# Emit values +for i in $( cat $HOME/run/$(basename $0).users ) +do + TMPLINE=$(awk -v i=$i '($2 == i) { print }' $HOME/run/$(basename $0).txt) + if [ -z "$TMPLINE" ] + then + echo "$i.value 0" + else + echo "$TMPLINE" | awk ' { print $2 ".value " $1 }' + + fi +done From 1db419b1ee79d3fffd889ea530adba17fe7f1759 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 10 Jan 2013 10:32:05 +0100 Subject: [PATCH 035/109] db2_cnx: +x --- plugins/db2/db2_cnx | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 plugins/db2/db2_cnx diff --git a/plugins/db2/db2_cnx b/plugins/db2/db2_cnx old mode 100644 new mode 100755 From 6fcde6d8f123e6e116c9c96a820fbacc6ae8ff7c Mon Sep 17 00:00:00 2001 From: Michiel Holtkamp Date: Sun, 13 Jan 2013 15:13:59 +0100 Subject: [PATCH 036/109] Added multigraph so not only volume but also ratio is graphed --- plugins/network/traffic | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/plugins/network/traffic b/plugins/network/traffic index 5df88dc6..6f1de21e 100755 --- a/plugins/network/traffic +++ b/plugins/network/traffic @@ -21,6 +21,7 @@ If trouble reading files, use: =over =item 2012.09.20: Initial version by Arturo Borrero Gonzalez +=item 2013.01.12: Added percentage graphing by Michiel Holtkamp =back @@ -39,6 +40,7 @@ GPLv2 if [ "$1" == "config" ] then cat <<'EOF' +multigraph traffic graph_title Throughput by IP protocol graph_vlabel bits per ${graph_period} graph_category network @@ -55,6 +57,32 @@ total.label Total bps total.min 0 total.type DERIVE total.draw LINE1 +EOF + + # Adapted from http://munin-monitoring.org/wiki/PercentGraphHowto + cat <<'EOF' +multigraph traffic_percent +graph_scale no +graph_title Throughput of IP protocols by percentage +graph_vlabel Percentage +graph_order IPv4=traffic.IPv4 IPv6=traffic.IPv6 total=traffic.total IPv4_percent=traffic.total IPv6_percent=traffic.total total_percent=traffic.total +graph_category network +graph_args --upper-limit 100 -l 0 -r +IPv4.label no +IPv6.label no +total.label no +total_percent.label no +IPv4.graph no +IPv6.graph no +total.graph no +total_percent.graph no +total_percent.cdef total,0.0000001,+ +IPv4_percent.label IPv4 +IPv4_percent.cdef IPv4,total_percent,/,100,* +IPv4_percent.draw AREASTACK +IPv6_percent.label IPv6 +IPv6_percent.cdef IPv6,total_percent,/,100,* +IPv6_percent.draw AREASTACK EOF exit 0 fi From 21fa1d24e3ba7a46e16a22504050c68dd4ce4750 Mon Sep 17 00:00:00 2001 From: Michiel Holtkamp Date: Fri, 18 Jan 2013 22:19:11 +0100 Subject: [PATCH 037/109] Added a line of whitespace between =item's --- plugins/network/traffic | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/network/traffic b/plugins/network/traffic index 6f1de21e..a3f8f09e 100755 --- a/plugins/network/traffic +++ b/plugins/network/traffic @@ -21,6 +21,7 @@ If trouble reading files, use: =over =item 2012.09.20: Initial version by Arturo Borrero Gonzalez + =item 2013.01.12: Added percentage graphing by Michiel Holtkamp =back From 32bee48e0dce3c391a24785295ae0576dd5455a4 Mon Sep 17 00:00:00 2001 From: Stig Sandbeck Mathisen Date: Wed, 23 Jan 2013 10:26:54 +0100 Subject: [PATCH 038/109] Support warning and critical --- plugins/network/ping/ping | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/network/ping/ping b/plugins/network/ping/ping index 010d39ad..1742a91c 100755 --- a/plugins/network/ping/ping +++ b/plugins/network/ping/ping @@ -164,6 +164,10 @@ for (my $host_i = 0; $host_i < @host_addrs; ++$host_i) { my $h_norm_name = clean_fieldname($h_cur_name); if ($config_mode) { print "$h_norm_name.min 0\n$h_norm_name.label $h_cur_name\n$h_norm_name.draw LINE2\n"; + my ( $warning, $critical ) = + get_thresholds($h_norm_name); + printf "%s.warning %s\n", $h_norm_name, $warning; + printf "%s.critical %s\n", $h_norm_name, $critical; } else { my $pid = $fork ? fork() : -1; if ($pid <= 0) { From 81ae39dfc0533508694119e19568906911ca8901 Mon Sep 17 00:00:00 2001 From: Stig Sandbeck Mathisen Date: Wed, 23 Jan 2013 10:31:30 +0100 Subject: [PATCH 039/109] Test for values of $warning and $critical before try emitting them --- plugins/network/ping/ping | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/network/ping/ping b/plugins/network/ping/ping index 1742a91c..858fb6d3 100755 --- a/plugins/network/ping/ping +++ b/plugins/network/ping/ping @@ -166,8 +166,10 @@ for (my $host_i = 0; $host_i < @host_addrs; ++$host_i) { print "$h_norm_name.min 0\n$h_norm_name.label $h_cur_name\n$h_norm_name.draw LINE2\n"; my ( $warning, $critical ) = get_thresholds($h_norm_name); - printf "%s.warning %s\n", $h_norm_name, $warning; - printf "%s.critical %s\n", $h_norm_name, $critical; + printf "%s.warning %s\n", $h_norm_name, $warning + if $warning; + printf "%s.critical %s\n", $h_norm_name, $critical + if $critical; } else { my $pid = $fork ? fork() : -1; if ($pid <= 0) { From c87caf6cd755943b019e07779e15aea91e08edfb Mon Sep 17 00:00:00 2001 From: Jimmy Jones Date: Thu, 24 Jan 2013 12:19:41 -0800 Subject: [PATCH 040/109] Add licence and more description --- plugins/qpid/qpid_bytedepth | 4 ++++ plugins/qpid/qpid_discardsring | 4 ++++ plugins/qpid/qpid_enqueuebytes | 4 ++++ plugins/qpid/qpid_enqueuecount | 4 ++++ plugins/qpid/qpid_msgdepth | 4 ++++ 5 files changed, 20 insertions(+) diff --git a/plugins/qpid/qpid_bytedepth b/plugins/qpid/qpid_bytedepth index e89d506f..43959fe8 100755 --- a/plugins/qpid/qpid_bytedepth +++ b/plugins/qpid/qpid_bytedepth @@ -1,12 +1,16 @@ #!/usr/bin/env python # # Plugin to monitor Apache Qpid +# - graphs the number of outstanding bytes on queue(s) specified in config # # Parameters understood: # # queues (required) - space separated list of queues to display (regex allowed) # # Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) +# +# Licence: GPLv2 +# import re import sys diff --git a/plugins/qpid/qpid_discardsring b/plugins/qpid/qpid_discardsring index f2a12e5d..62d85d1b 100755 --- a/plugins/qpid/qpid_discardsring +++ b/plugins/qpid/qpid_discardsring @@ -1,12 +1,16 @@ #!/usr/bin/env python # # Plugin to monitor Apache Qpid +# - graphs the number of messages discarded from queue(s) specified in config # # Parameters understood: # # queues (required) - space separated list of queues to display (regex allowed) # # Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) +# +# Licence: GPLv2 +# import re import sys diff --git a/plugins/qpid/qpid_enqueuebytes b/plugins/qpid/qpid_enqueuebytes index c2713a01..8afc420f 100755 --- a/plugins/qpid/qpid_enqueuebytes +++ b/plugins/qpid/qpid_enqueuebytes @@ -1,12 +1,16 @@ #!/usr/bin/env python # # Plugin to monitor Apache Qpid +# - graph ingest rate (bytes/sec) of queue(s) specified in config # # Parameters understood: # # queues (required) - space separated list of queues to display (regex allowed) # # Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) +# +# Licence: GPLv2 +# import re import sys diff --git a/plugins/qpid/qpid_enqueuecount b/plugins/qpid/qpid_enqueuecount index 38c34381..45420d89 100755 --- a/plugins/qpid/qpid_enqueuecount +++ b/plugins/qpid/qpid_enqueuecount @@ -1,12 +1,16 @@ #!/usr/bin/env python # # Plugin to monitor Apache Qpid +# - graphs ingest rate (messages/sec) of queue(s) specified in config # # Parameters understood: # # queues (required) - space separated list of queues to display (regex allowed) # # Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) +# +# Licence: GPLv2 +# import re import sys diff --git a/plugins/qpid/qpid_msgdepth b/plugins/qpid/qpid_msgdepth index c68616b8..33143d00 100755 --- a/plugins/qpid/qpid_msgdepth +++ b/plugins/qpid/qpid_msgdepth @@ -1,12 +1,16 @@ #!/usr/bin/env python # # Plugin to monitor Apache Qpid +# - graphs the number of outstanding messages on queue(s) specified in config # # Parameters understood: # # queues (required) - space separated list of queues to display (regex allowed) # # Made by Jimmy Jones (jimmyjones2 AT gmx DOT co DOT uk) +# +# Licence: GPLv2 +# import re import sys From 0595306b2dabda323ee7fbcc505ce55ef69a9a83 Mon Sep 17 00:00:00 2001 From: CWempe Date: Thu, 24 Jan 2013 23:03:51 +0100 Subject: [PATCH 041/109] svdrpsend.pl was renamed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The script "svdrpsend.pl" was renamed to "svdrpsend" in VDR Version 1.7.23. see http://www.vdr-wiki.de/wiki/index.php/SVDRP#svdrpsend --- plugins/vdr/vdr_ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/vdr/vdr_ b/plugins/vdr/vdr_ index e3bdb23b..ea10e593 100755 --- a/plugins/vdr/vdr_ +++ b/plugins/vdr/vdr_ @@ -21,7 +21,7 @@ $0 =~ /vdr_(.+)*$/; my $host = $1 || "localhost";; #print "Name: $0\nHost: $host\n"; -my $SVDRPSENDPL="/usr/bin/svdrpsend.pl -d $host"; +my $SVDRPSENDPL="/usr/bin/svdrpsend -d $host"; sub ermittelnTimer; sub ermittelnAufnahmen; From b9ffe6035e3f514a1e85f20158699e6f4c5fc8b9 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 27 Jan 2013 16:16:17 +0100 Subject: [PATCH 042/109] Add plugin mysql_size_ondisk - reports the on-disk size of MySQL DBs. --- plugins/mysql/mysql_size_ondisk | 80 +++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100755 plugins/mysql/mysql_size_ondisk diff --git a/plugins/mysql/mysql_size_ondisk b/plugins/mysql/mysql_size_ondisk new file mode 100755 index 00000000..c18b9a38 --- /dev/null +++ b/plugins/mysql/mysql_size_ondisk @@ -0,0 +1,80 @@ +#!/bin/bash +# +INFO=\ +"mysql_size_ondisk - Munin plugin that reports the size of the files and + directories in /var/lib/mysql, biggest to smallest. + To correctly count InnoDB tables you should have innodb_file_per_table enabled + in MySQL (good practise anyway), otherwise all InnoDB tables will be counted into + ibdataX. + This plugin must be run as the user mysql, to do that append the following + to your /etc/munin/plugins/plugin-conf.d/munin-node: + + [mysql_size_ondisk] + user mysql + + This plugin gives you similar information as mysql_size_all. A difference + is that mysql_size_ondisk is much faster (0.4 seconds vs 14 seconds, on a server + with 170 databases, 26 GB total). Also note that mysql_size_all gives you the net + data size, mysql_size_ondisk gives you the gross storage space used, which may be + much more than your actual data." +# +# License: GPLv2 or later +# +# v1.0, 27.01.2012 Jakob Unterwurzacher + +#%# family=auto +#%# capabilities=autoconf + +set -eu + +DIR=/var/lib/mysql + +function clean { + # First character must not be a number + a=${1/#[0-9]/_} + # Other characters must be alphanumeric + b=${a//[^a-zA-Z0-9]/_} + echo $b +} + +if [ "${1:-}" = "autoconf" ] +then + if du -sb $DIR &> /dev/null + then + echo "yes" + exit 0 + else + echo "no" + exit 1 + fi +elif [ "${1:-}" = "config" ] +then + echo "graph_title MySQL on-disk database size" + echo "graph_category mysql" + # graph_info cannot have newlines - replace by
which will be rendered to newlines in + # the web interface. + echo "graph_info ${INFO//$'\n'/
}" + echo "graph_args --base 1024 --lower-limit 0" + echo "graph_vlabel Bytes" + cd $DIR + du -sb * | sort -nr | while read s i + do + i=`clean $i` + echo "$i.label $i" + echo "$i.type GAUGE" + echo "$i.draw AREASTACK" + done + exit 0 +elif [ "${1:-}" = "" ] +then + cd $DIR + du -sb * | sort -nr | while read s i + do + i=`clean $i` + echo "$i.value $s" + done + exit 0 +else + echo "Unknown argument" + exit 1 +fi From 36a53f4538ab48abb6bacd86c92e2c8d0f568cca Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 10 Jan 2013 10:27:35 +0100 Subject: [PATCH 043/109] db2_cnx: adding a plugin for monitoring DB2 connections --- plugins/db2/db2_cnx | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 plugins/db2/db2_cnx diff --git a/plugins/db2/db2_cnx b/plugins/db2/db2_cnx new file mode 100644 index 00000000..d6d60ad1 --- /dev/null +++ b/plugins/db2/db2_cnx @@ -0,0 +1,37 @@ +#! /bin/sh +# (c) 2012 - Steve Schnepp - LGPL + +# XXX - coded hastily + +# Source the DB2 profile +. /home/db2inst1/sqllib/db2profile + +echo "graph_title Number of connections" +echo "graph_category DB2" +echo "graph_args -l 0" + +db2 list application | tail +5 | awk ' /^[A-Z]/ { print $1 }' | sort | uniq -c > $HOME/run/$(basename $0).txt + +# Get users list +touch $HOME/run/$(basename $0).users +awk '{ print $2 }' $HOME/run/$(basename $0).txt | cat $HOME/run/$(basename $0).users - | sort -ru > $HOME/run/$(basename $0).users.tmp +mv $HOME/run/$(basename $0).users.tmp $HOME/run/$(basename $0).users + +# Emit config +if [ "$1" = "config" ] +then + awk ' { print $1 ".label " $1 "\n" $1 ".draw AREASTACK" }' $HOME/run/$(basename $0).users +fi + +# Emit values +for i in $( cat $HOME/run/$(basename $0).users ) +do + TMPLINE=$(awk -v i=$i '($2 == i) { print }' $HOME/run/$(basename $0).txt) + if [ -z "$TMPLINE" ] + then + echo "$i.value 0" + else + echo "$TMPLINE" | awk ' { print $2 ".value " $1 }' + + fi +done From 709af409cdc71f9eb9245a381f7f7ff8919136f0 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 10 Jan 2013 10:32:05 +0100 Subject: [PATCH 044/109] db2_cnx: +x --- plugins/db2/db2_cnx | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 plugins/db2/db2_cnx diff --git a/plugins/db2/db2_cnx b/plugins/db2/db2_cnx old mode 100644 new mode 100755 From 5fc0b17b752e6fa5124789bf6c998a6deb63b46d Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 10 Jan 2013 18:00:05 +0100 Subject: [PATCH 045/109] qos_: add ability to use custom update_rate --- plugins/network/qos_ | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/network/qos_ b/plugins/network/qos_ index 6382cfe1..3b9bc6fa 100755 --- a/plugins/network/qos_ +++ b/plugins/network/qos_ @@ -16,6 +16,8 @@ # tc - Override default program # ignore_queue - Queue with handle not be plotted # label_name - Queue with handle as defined label +# update_rate - Custom update_rate, to be used with async +# graph_data_size - Custom graph_data_size, to be used with async & custom update_rate # # Magic markers: #%# family=manual @@ -100,6 +102,8 @@ if ( exists $ARGV[0] and $ARGV[0] eq 'config' ) { print "graph_vlabel bits per \${graph_period}\n"; print "graph_category network\n"; print "graph_info This graph shows the QoS queue of the $IFACE network interface.\n"; + print "update_rate $ENV{update_rate}\n" if $ENV{update_rate}; + print "graph_data_size $ENV{graph_data_size}\n" if $ENV{graph_data_size}; print "graph_order "; foreach my $key (sort by_handle keys %queues) { $haschild = 0; From 209937078bc6934159706dcd73239a850bdfcf7f Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 21 Jun 2008 11:33:06 +0000 Subject: [PATCH 046/109] initial tree --- tools/munin-plugins-busybox/Makefile | 16 +++ tools/munin-plugins-busybox/common.c | 14 ++ tools/munin-plugins-busybox/common.h | 7 + tools/munin-plugins-busybox/cpu.c | 157 ++++++++++++++++++++++ tools/munin-plugins-busybox/entropy.c | 35 +++++ tools/munin-plugins-busybox/forks.c | 44 ++++++ tools/munin-plugins-busybox/fw_packets.c | 60 +++++++++ tools/munin-plugins-busybox/interrupts.c | 47 +++++++ tools/munin-plugins-busybox/load.c | 47 +++++++ tools/munin-plugins-busybox/main.c | 64 +++++++++ tools/munin-plugins-busybox/open_files.c | 52 +++++++ tools/munin-plugins-busybox/open_inodes.c | 42 ++++++ tools/munin-plugins-busybox/processes.c | 42 ++++++ tools/munin-plugins-busybox/swap.c | 78 +++++++++++ tools/munin-plugins-busybox/uptime.c | 32 +++++ 15 files changed, 737 insertions(+) create mode 100644 tools/munin-plugins-busybox/Makefile create mode 100644 tools/munin-plugins-busybox/common.c create mode 100644 tools/munin-plugins-busybox/common.h create mode 100644 tools/munin-plugins-busybox/cpu.c create mode 100644 tools/munin-plugins-busybox/entropy.c create mode 100644 tools/munin-plugins-busybox/forks.c create mode 100644 tools/munin-plugins-busybox/fw_packets.c create mode 100644 tools/munin-plugins-busybox/interrupts.c create mode 100644 tools/munin-plugins-busybox/load.c create mode 100644 tools/munin-plugins-busybox/main.c create mode 100644 tools/munin-plugins-busybox/open_files.c create mode 100644 tools/munin-plugins-busybox/open_inodes.c create mode 100644 tools/munin-plugins-busybox/processes.c create mode 100644 tools/munin-plugins-busybox/swap.c create mode 100644 tools/munin-plugins-busybox/uptime.c diff --git a/tools/munin-plugins-busybox/Makefile b/tools/munin-plugins-busybox/Makefile new file mode 100644 index 00000000..56a56f63 --- /dev/null +++ b/tools/munin-plugins-busybox/Makefile @@ -0,0 +1,16 @@ +CC=gcc +CFLAGS=-W -Wall -pedantic -Wextra -g -O2 +OBJS=main.o common.o cpu.o entropy.o forks.o fw_packets.o interrupts.o load.o \ + open_files.o open_inodes.o processes.o swap.o uptime.o +LINKS=cpu entropy forks fw_packets interrupts load open_files open_inodes \ + processes swap uptime + +%.o:%.c + ${CC} ${CFLAGS} -c $< -o $@ +all:main + for l in ${LINKS}; do test -f $$l || ln -s main $$l; done +main:${OBJS} + ${CC} ${CFLAGS} $^ -o $@ +clean: + rm -f main ${OBJS} ${LINKS} +.PHONY:all clean diff --git a/tools/munin-plugins-busybox/common.c b/tools/munin-plugins-busybox/common.c new file mode 100644 index 00000000..3d78e518 --- /dev/null +++ b/tools/munin-plugins-busybox/common.c @@ -0,0 +1,14 @@ +#include + +int writeyes(void) { + puts("yes"); + return 0; +} + +int writeno(const char *s) { + if(s) + printf("no (%s)\n", s); + else + puts("no"); + return 1; +} diff --git a/tools/munin-plugins-busybox/common.h b/tools/munin-plugins-busybox/common.h new file mode 100644 index 00000000..67a5bebc --- /dev/null +++ b/tools/munin-plugins-busybox/common.h @@ -0,0 +1,7 @@ +#ifndef COMMON_H +#define COMMON_H + +int writeyes(void); +int writeno(const char *); + +#endif diff --git a/tools/munin-plugins-busybox/cpu.c b/tools/munin-plugins-busybox/cpu.c new file mode 100644 index 00000000..171a3d3c --- /dev/null +++ b/tools/munin-plugins-busybox/cpu.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include "common.h" + +#define SYSWARNING 30 +#define SYSCRITICAL 50 +#define USRWARNING 80 + +int cpu(int argc, char **argv) { + FILE *f; + char buff[256], *s; + int ncpu=0, extinfo=0, scaleto100=0; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + s = getenv("scaleto100"); + if(s && !strcmp(s, "yes")) + scaleto100=1; + + if(!(f=fopen("/proc/stat", "r"))) { + fputs("cannot open /proc/stat\n", stderr); + return 1; + } + while(fgets(buff, 256, f)) { + if(!strncmp(buff, "cpu", 3)) { + if(isdigit(buff[3])) + ncpu++; + if(buff[3] == ' ') { + s = strtok(buff+4, " \t"); + for(extinfo=0;strtok(NULL, " \t");extinfo++) + ; + } + } + } + fclose(f); + + if(ncpu < 1 || extinfo < 4) { + fputs("cannot parse /proc/stat\n", stderr); + return 1; + } + + puts("graph_title CPU usage"); + if(extinfo == 7) + puts("graph_order system user nice idle iowait irq softirq"); + else + puts("graph_order system user nice idle"); + if(scaleto100) + puts("graph_args --base 1000 -r --lower-limit 0 --upper-limit 100"); + else + printf("graph_args --base 1000 -r --lower-limit 0 --upper-limit %d\n", 100 * ncpu); + puts("graph_vlabel %\n" + "graph_scale no\n" + "graph_info This graph shows how CPU time is spent.\n" + "graph_category system\n" + "graph_period second\n" + "system.label system\n" + "system.draw AREA"); + printf("system.max %d\n", 100 * ncpu); + puts("system.min 0\n" + "system.type DERIVE"); + printf("system.warning %d\n", SYSWARNING * ncpu); + printf("system.critical %d\n", SYSCRITICAL * ncpu); + puts("system.info CPU time spent by the kernel in system activities\n" + "user.label user\n" + "user.draw STACK\n" + "user.min 0"); + printf("user.max %d\n", 100 * ncpu); + printf("user.warning %d\n", USRWARNING * ncpu); + puts("user.type DERIVE\n" + "user.info CPU time spent by normal programs and daemons\n" + "nice.label nice\n" + "nice.draw STACK\n" + "nice.min 0"); + printf("nice.max %d\n", 100 * ncpu); + puts("nice.type DERIVE\n" + "nice.info CPU time spent by nice(1)d programs\n" + "idle.label idle\n" + "idle.draw STACK\n" + "idle.min 0"); + printf("idle.max %d\n", 100 * ncpu); + puts("idle.type DERIVE\n" + "idle.info Idle CPU time"); + if(scaleto100) + printf("system.cdef system,%d,/\n" + "user.cdef user,%d,/\n" + "nice.cdef nice,%d,/\n" + "idle.cdef idle,%d,/\n", ncpu, ncpu, ncpu, ncpu); + if(extinfo == 7) { + puts("iowait.label iowait\n" + "iowait.draw STACK\n" + "iowait.min 0"); + printf("iowait.max %d\n", 100 * ncpu); + puts("iowait.type DERIVE\n" + "iowait.info CPU time spent waiting for I/O operations to finish\n" + "irq.label irq\n" + "irq.draw STACK\n" + "irq.min 0"); + printf("irq.max %d\n", 100 * ncpu); + puts("irq.type DERIVE\n" + "irq.info CPU time spent handling interrupts\n" + "softirq.label softirq\n" + "softirq.draw STACK\n" + "softirq.min 0"); + printf("softirq.max %d\n", 100 * ncpu); + puts("softirq.type DERIVE\n" + "softirq.info CPU time spent handling \"batched\" interrupts"); + if(scaleto100) + printf("iowait.cdef iowait,%d,/\n" + "irq.cdef irq,%d,/\n" + "softirq.cdef softirq,%d,/\n", ncpu, ncpu, ncpu); + } + return 0; + } + if(!strcmp(argv[1], "autoconf")) { + if(0 == access("/proc/stat", R_OK)) + return writeyes(); + else + return writeno("/proc/stat not readable"); + } + } + if(!(f=fopen("/proc/stat", "r"))) { + fputs("cannot open /proc/stat\n", stderr); + return 1; + } + while(fgets(buff, 256, f)) { + if(!strncmp(buff, "cpu ", 4)) { + fclose(f); + if(!(s = strtok(buff+4, " \t"))) + break; + printf("user.value %s\n", s); + if(!(s = strtok(NULL, " \t"))) + break; + printf("nice.value %s\n", s); + if(!(s = strtok(NULL, " \t"))) + break; + printf("system.value %s\n", s); + if(!(s = strtok(NULL, " \t"))) + break; + printf("idle.value %s\n", s); + if(!(s = strtok(NULL, " \t"))) + return 0; + printf("iowait.value %s\n", s); + if(!(s = strtok(NULL, " \t"))) + return 0; + printf("irq.value %s\n", s); + if(!(s = strtok(NULL, " \t"))) + return 0; + printf("softirq.value %s\n", s); + return 0; + } + } + fclose(f); + fputs("no cpu line found in /proc/stat\n", stderr); + return 1; +} diff --git a/tools/munin-plugins-busybox/entropy.c b/tools/munin-plugins-busybox/entropy.c new file mode 100644 index 00000000..4a5d8468 --- /dev/null +++ b/tools/munin-plugins-busybox/entropy.c @@ -0,0 +1,35 @@ +#include +#include +#include "common.h" + +int entropy(int argc, char **argv) { + FILE *f; + int entropy; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Available entropy\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel entropy (bytes)\n" + "graph_scale no\n" + "graph_category system\n" + "graph_info This graph shows the amount of entropy available in the system.\n" + "entropy.label entropy\n" + "entropy.info The number of random bytes available. This is typically used by cryptographic applications."); + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + if(!(f=fopen("/proc/sys/kernel/random/entropy_avail", "r"))) { + fputs("cannot open /proc/sys/kernel/random/entropy_avail\n", stderr); + return 1; + } + if(1 != fscanf(f, "%d", &entropy)) { + fputs("cannot read from /proc/sys/kernel/random/entropy_avail\n", stderr); + fclose(f); + return 1; + } + fclose(f); + printf("entropy.value %d\n", entropy); + return 0; +} diff --git a/tools/munin-plugins-busybox/forks.c b/tools/munin-plugins-busybox/forks.c new file mode 100644 index 00000000..fa4dadb4 --- /dev/null +++ b/tools/munin-plugins-busybox/forks.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include "common.h" + +int forks(int argc, char **argv) { + FILE *f; + char buff[256]; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Fork rate\n" + "graph_args --base 1000 -l 0 \n" + "graph_vlabel forks / ${graph_period}\n" + "graph_category processes\n" + "graph_info This graph shows the forking rate (new processes started).\n" + "forks.label forks\n" + "forks.type DERIVE\n" + "forks.min 0\n" + "forks.max 100000\n" + "forks.info The number of forks per second."); + return 0; + } + if(!strcmp(argv[1], "autoconf")) { + if(0 == access("/proc/stat", R_OK)) + return writeyes(); + else + return writeno("/proc/stat not readable"); + } + } + if(!(f=fopen("/proc/stat", "r"))) { + fputs("cannot open /proc/stat\n", stderr); + return 1; + } + while(fgets(buff, 256, f)) { + if(!strncmp(buff, "processes ", 10)) { + fclose(f); + printf("forks.value %s", buff+10); + return 0; + } + } + fclose(f); + fputs("no processes line found in /proc/stat\n", stderr); + return 1; +} diff --git a/tools/munin-plugins-busybox/fw_packets.c b/tools/munin-plugins-busybox/fw_packets.c new file mode 100644 index 00000000..06367dde --- /dev/null +++ b/tools/munin-plugins-busybox/fw_packets.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include "common.h" + +int fw_packets(int argc, char **argv) { + FILE *f; + char buff[1024], *s; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Firewall Throughput\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel Packets/${graph_period}\n" + "graph_category network\n" + "received.label Received\n" + "received.draw AREA\n" + "received.type DERIVE\n" + "received.min 0\n" + "forwarded.label Forwarded\n" + "forwarded.draw LINE2\n" + "forwarded.type DERIVE\n" + "forwarded.min 0"); + return 0; + } + if(!strcmp(argv[1], "autoconf")) { + if(0 == access("/proc/net/snmp", R_OK)) + return writeyes(); + else + return writeno("/proc/net/snmp not readable"); + } + } + if(!(f=fopen("/proc/net/snmp", "r"))) { + fputs("cannot open /proc/net/snmp\n", stderr); + return 1; + } + while(fgets(buff, 1024, f)) { + if(!strncmp(buff, "Ip: ", 4) && isdigit(buff[4])) { + fclose(f); + if(!(s = strtok(buff+4, " \t"))) + break; + if(!(s = strtok(NULL, " \t"))) + break; + if(!(s = strtok(NULL, " \t"))) + break; + printf("received.value %s\n", s); + if(!(s = strtok(NULL, " \t"))) + break; + if(!(s = strtok(NULL, " \t"))) + break; + if(!(s = strtok(NULL, " \t"))) + break; + printf("forwarded.value %s\n", s); + return 0; + } + } + fclose(f); + fputs("no ip line found in /proc/net/snmp\n", stderr); + return 1; +} diff --git a/tools/munin-plugins-busybox/interrupts.c b/tools/munin-plugins-busybox/interrupts.c new file mode 100644 index 00000000..2755ccf6 --- /dev/null +++ b/tools/munin-plugins-busybox/interrupts.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include "common.h" + +int interrupts(int argc, char **argv) { + FILE *f; + char buff[256]; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Interrupts & context switches\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel interrupts & ctx switches / ${graph_period}\n" + "graph_category system\n" + "graph_info This graph shows the number of interrupts and context switches on the system. These are typically high on a busy system.\n" + "intr.info Interrupts are events that alter sequence of instructions executed by a processor. They can come from either hardware (exceptions, NMI, IRQ) or software."); + puts("ctx.info A context switch occurs when a multitasking operatings system suspends the currently running process, and starts executing another.\n" + "intr.label interrupts\n" + "ctx.label context switches\n" + "intr.type DERIVE\n" + "ctx.type DERIVE\n" + "intr.max 100000\n" + "ctx.max 100000\n" + "intr.min 0\n" + "ctx.min 0"); + return 0; + } + if(!strcmp(argv[1], "autoconf")) { + if(0 == access("/proc/stat", R_OK)) + return writeyes(); + else + return writeno("/proc/stat not readable"); + } + } + if(!(f=fopen("/proc/stat", "r"))) { + fputs("cannot open /proc/stat\n", stderr); + return 1; + } + while(fgets(buff, 256, f)) { + if(!strncmp(buff, "intr ", 5)) + printf("intr.value %s", buff+5); + else if(!strncmp(buff, "ctxt ", 5)) + printf("ctx.value %s", buff+5); + } + fclose(f); + return 0; +} diff --git a/tools/munin-plugins-busybox/load.c b/tools/munin-plugins-busybox/load.c new file mode 100644 index 00000000..c894f5e2 --- /dev/null +++ b/tools/munin-plugins-busybox/load.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include "common.h" + +int load(int argc, char **argv) { + FILE *f; + int warn, crit; + float val; + char *s; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + s = getenv("load_warn"); + if(s) + warn = atoi(s); + else + warn = 10; + s = getenv("load_crit"); + if(s) + crit = atoi(s); + else + crit = 120; + puts("graph_title Load average\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel load\n" + "graph_scale no\n" + "graph_category system\n" + "load.label load"); + printf("load.warning %d\nload.critical %d\n", warn, crit); + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + if(!(f=fopen("/proc/loadavg", "r"))) { + fputs("cannot open /proc/loadavg\n", stderr); + return 1; + } + if(1 != fscanf(f, "%*f %f", &val)) { + fputs("cannot read from /proc/loadavg\n", stderr); + fclose(f); + return 1; + } + fclose(f); + printf("load.value %.2f\n", val); + return 0; +} diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c new file mode 100644 index 00000000..348b4f65 --- /dev/null +++ b/tools/munin-plugins-busybox/main.c @@ -0,0 +1,64 @@ +#include +#include +#include + +int cpu(int argc, char **argv); +int entropy(int argc, char **argv); +int forks(int argc, char **argv); +int fw_packets(int argc, char **argv); +int interrupts(int argc, char **argv); +int load(int argc, char **argv); +int open_files(int argc, char **argv); +int open_inodes(int argc, char **argv); +int processes(int argc, char **argv); +int swap(int argc, char **argv); +int uptime(int argc, char **argv); + +int main(int argc, char **argv) { + char *progname; + progname = basename(argv[0]); + switch(*progname) { + case 'c': + if(!strcmp(progname+1, "pu")) + return cpu(argc, argv); + break; + case 'e': + if(!strcmp(progname+1, "ntropy")) + return entropy(argc, argv); + break; + case 'f': + if(!strcmp(progname+1, "orks")) + return forks(argc, argv); + if(!strcmp(progname+1, "w_packets")) + return fw_packets(argc, argv); + break; + case 'i': + if(!strcmp(progname+1, "nterrupts")) + return interrupts(argc, argv); + break; + case 'l': + if(!strcmp(progname+1, "oad")) + return load(argc, argv); + break; + case 'o': + if(!strcmp(progname+1, "pen_files")) + return open_files(argc, argv); + if(!strcmp(progname+1, "pen_inodes")) + return open_inodes(argc, argv); + break; + case 'p': + if(!strcmp(progname+1, "rocesses")) + return processes(argc, argv); + break; + case 's': + if(!strcmp(progname+1, "wap")) + return swap(argc, argv); + break; + case 'u': + if(!strcmp(progname+1, "ptime")) + return uptime(argc, argv); + break; + } + fprintf(stderr, "function not specified\n"); + return 1; +} diff --git a/tools/munin-plugins-busybox/open_files.c b/tools/munin-plugins-busybox/open_files.c new file mode 100644 index 00000000..3f82c8b5 --- /dev/null +++ b/tools/munin-plugins-busybox/open_files.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include "common.h" + +int open_files(int argc, char **argv) { + FILE *f; + int alloc, freeh, avail; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + if(!(f=fopen("/proc/sys/fs/file-nr", "r"))) { + fprintf(stderr, "cannot open /proc/sys/fs/file-nr\n"); + return 1; + } + if(1 != fscanf(f, "%*d %*d %d", &avail)) { + fclose(f); + fprintf(stderr, "cannot read from /proc/sys/fs/file-nr\n"); + return 1; + } + fclose(f); + puts("graph_title File table usage\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel number of open files\n" + "graph_category system\n" + "graph_info This graph monitors the Linux open files table.\n" + "used.label open files\n" + "used.info The number of currently open files.\n" + "max.label max open files\n" + "max.info The maximum supported number of open files. Tune by modifying /proc/sys/fs/file-max."); + printf("used.warning %d\nused.critical %d\n", (int)(avail*0.92), (int)(avail*0.98)); + return 0; + } + if(!strcmp(argv[1], "autoconf")) { + if(0 == access("/proc/sys/fs/file-nr", R_OK)) + return writeyes(); + else + return writeno("/proc/sys/fs/file-nr not readable"); + } + } + if(!(f=fopen("/proc/sys/fs/file-nr", "r"))) { + fputs("cannot open /proc/sys/fs/file-nr\n", stderr); + return 1; + } + if(3 != fscanf(f, "%d %d %d", &alloc, &freeh, &avail)) { + fclose(f); + fputs("cannot read from /proc/sys/fs/file-nr\n", stderr); + return 1; + } + fclose(f); + printf("used.value %d\nmax.value %d\n", alloc-freeh, avail); + return 0; +} diff --git a/tools/munin-plugins-busybox/open_inodes.c b/tools/munin-plugins-busybox/open_inodes.c new file mode 100644 index 00000000..bc20cc60 --- /dev/null +++ b/tools/munin-plugins-busybox/open_inodes.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include "common.h" + +int open_inodes(int argc, char **argv) { + FILE *f; + int nr, freen; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Inode table usage\n" + "graph_args --base 1000 -l 0\n" + "graph_vlabel number of open inodes\n" + "graph_category system\n" + "graph_info This graph monitors the Linux open inode table.\n" + "used.label open inodes\n" + "used.info The number of currently open inodes.\n" + "max.label inode table size\n" + "max.info The size of the system inode table. This is dynamically adjusted by the kernel."); + + return 0; + } + if(!strcmp(argv[1], "autoconf")) { + if(0 == access("/proc/sys/fs/inode-nr", R_OK)) + return writeyes(); + else + return writeno("/proc/sys/fs/inode-nr not readable"); + } + } + if(!(f=fopen("/proc/sys/fs/inode-nr", "r"))) { + fputs("cannot open /proc/sys/fs/inode-nr\n", stderr); + return 1; + } + if(2 != fscanf(f, "%d %d", &nr, &freen)) { + fclose(f); + fputs("cannot read from /proc/sys/fs/inode-nr\n", stderr); + return 1; + } + fclose(f); + printf("used.value %d\nmax.value %d\n", nr-freen, nr); + return 0; +} diff --git a/tools/munin-plugins-busybox/processes.c b/tools/munin-plugins-busybox/processes.c new file mode 100644 index 00000000..b5227686 --- /dev/null +++ b/tools/munin-plugins-busybox/processes.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include "common.h" + +int processes(int argc, char **argv) { + DIR *d; + struct dirent *e; + char *s; + int n=0; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Number of Processes\n" + "graph_args --base 1000 -l 0 \n" + "graph_vlabel number of processes\n" + "graph_category processes\n" + "graph_info This graph shows the number of processes in the system.\n" + "processes.label processes\n" + "processes.draw LINE2\n" + "processes.info The current number of processes."); + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + if(!(d = opendir("/proc"))) { + fputs("cannot open /proc\n", stderr); + return 1; + } + while((e = readdir(d))) { + for(s=e->d_name;*s;++s) + if(!isdigit(*s)) + break; + if(!*s) + ++n; + } + closedir(d); + printf("processes.value %d\n", n); + return 0; +} diff --git a/tools/munin-plugins-busybox/swap.c b/tools/munin-plugins-busybox/swap.c new file mode 100644 index 00000000..fef6cc32 --- /dev/null +++ b/tools/munin-plugins-busybox/swap.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include "common.h" + +int swap(int argc, char **argv) { + FILE *f; + char buff[256]; + int in, out; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Swap in/out\n" + "graph_args -l 0 --base 1000\n" + "graph_vlabel pages per ${graph_period} in (-) / out (+)\n" + "graph_category system\n" + "swap_in.label swap\n" + "swap_in.type DERIVE\n" + "swap_in.max 100000\n" + "swap_in.min 0\n" + "swap_in.graph no\n" + "swap_out.label swap\n" + "swap_out.type DERIVE\n" + "swap_out.max 100000\n" + "swap_out.min 0\n" + "swap_out.negative swap_in"); + + return 0; + } + if(!strcmp(argv[1], "autoconf")) { + if(0 == access("/proc/stat", R_OK)) + return writeyes(); + else + return writeno("/proc/stat not readable"); + } + } + if(!access("/proc/vmstat", F_OK)) { + in=out=0; + if(!(f=fopen("/proc/vmstat", "r"))) { + fputs("cannot open /proc/vmstat\n", stderr); + return 1; + } + while(fgets(buff, 256, f)) { + if(!in && !strncmp(buff, "pswpin ", 7)) { + ++in; + printf("swap_in.value %s", buff+7); + } + else if(!out && !strncmp(buff, "pswpout ", 8)) { + ++out; + printf("swap_out.value %s", buff+8); + } + } + fclose(f); + if(!in*out) { + fputs("no usable data on /proc/vmstat\n", stderr); + return 1; + } + return 0; + } else { + if(!(f=fopen("/proc/stat", "r"))) { + fputs("cannot open /proc/stat\n", stderr); + return 1; + } + while(fgets(buff, 256, f)) { + if(!strncmp(buff, "swap ", 5)) { + fclose(f); + if(2 != sscanf(buff+5, "%d %d", &in, &out)) { + fputs("bad data on /proc/stat\n", stderr); + return 1; + } + printf("swap_in.value %d\nswap_out.value %d\n", in, out); + return 0; + } + } + fclose(f); + fputs("no swap line found in /proc/stat\n", stderr); + return 1; + } +} diff --git a/tools/munin-plugins-busybox/uptime.c b/tools/munin-plugins-busybox/uptime.c new file mode 100644 index 00000000..ce6093fa --- /dev/null +++ b/tools/munin-plugins-busybox/uptime.c @@ -0,0 +1,32 @@ +#include +#include +#include "common.h" + +int uptime(int argc, char **argv) { + FILE *f; + float uptime; + if(argc > 1) { + if(!strcmp(argv[1], "config")) { + puts("graph_title Uptime\n" + "graph_args --base 1000 -l 0 \n" + "graph_vlabel uptime in days\n" + "uptime.label uptime\n" + "uptime.draw AREA"); + return 0; + } + if(!strcmp(argv[1], "autoconf")) + return writeyes(); + } + if(!(f=fopen("/proc/uptime", "r"))) { + fputs("cannot open /proc/uptime\n", stderr); + return 1; + } + if(1 != fscanf(f, "%f", &uptime)) { + fputs("cannot read from /proc/uptime\n", stderr); + fclose(f); + return 1; + } + fclose(f); + printf("uptime.value %.2f\n", uptime/86400); + return 0; +} From bede1947b2025035b6d7a4a7c6c54e15d92e6d08 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 21 Jun 2008 11:45:12 +0000 Subject: [PATCH 047/109] change name to munin-plugins-busybox --- tools/munin-plugins-busybox/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/munin-plugins-busybox/Makefile b/tools/munin-plugins-busybox/Makefile index 56a56f63..34d9c491 100644 --- a/tools/munin-plugins-busybox/Makefile +++ b/tools/munin-plugins-busybox/Makefile @@ -7,10 +7,10 @@ LINKS=cpu entropy forks fw_packets interrupts load open_files open_inodes \ %.o:%.c ${CC} ${CFLAGS} -c $< -o $@ -all:main - for l in ${LINKS}; do test -f $$l || ln -s main $$l; done -main:${OBJS} +all:munin-plugins-busybox + for l in ${LINKS}; do test -f $$l || ln -s munin-plugins-busybox $$l; done +munin-plugins-busybox:${OBJS} ${CC} ${CFLAGS} $^ -o $@ clean: - rm -f main ${OBJS} ${LINKS} + rm -f munin-plugins-busybox ${OBJS} ${LINKS} .PHONY:all clean From 2f167d679fb1565a52d90c501983ba4bd710ddf7 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 21 Jun 2008 11:52:14 +0000 Subject: [PATCH 048/109] fix bug in swap.c --- tools/munin-plugins-busybox/swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-plugins-busybox/swap.c b/tools/munin-plugins-busybox/swap.c index fef6cc32..1a270fe8 100644 --- a/tools/munin-plugins-busybox/swap.c +++ b/tools/munin-plugins-busybox/swap.c @@ -50,7 +50,7 @@ int swap(int argc, char **argv) { } } fclose(f); - if(!in*out) { + if(!(in*out)) { fputs("no usable data on /proc/vmstat\n", stderr); return 1; } From 881a6374f5f9e37a65bada9cb5cbe022826522fc Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 21 Jun 2008 11:52:29 +0000 Subject: [PATCH 049/109] strip the binary --- tools/munin-plugins-busybox/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/munin-plugins-busybox/Makefile b/tools/munin-plugins-busybox/Makefile index 34d9c491..dae1b6c7 100644 --- a/tools/munin-plugins-busybox/Makefile +++ b/tools/munin-plugins-busybox/Makefile @@ -8,6 +8,7 @@ LINKS=cpu entropy forks fw_packets interrupts load open_files open_inodes \ %.o:%.c ${CC} ${CFLAGS} -c $< -o $@ all:munin-plugins-busybox + strip -s munin-plugins-busybox for l in ${LINKS}; do test -f $$l || ln -s munin-plugins-busybox $$l; done munin-plugins-busybox:${OBJS} ${CC} ${CFLAGS} $^ -o $@ From ad5c0c537a1a204721cbf3de8122e1d32b1ddd32 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 21 Jun 2008 11:52:41 +0000 Subject: [PATCH 050/109] added a README --- tools/munin-plugins-busybox/README | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tools/munin-plugins-busybox/README diff --git a/tools/munin-plugins-busybox/README b/tools/munin-plugins-busybox/README new file mode 100644 index 00000000..2945e709 --- /dev/null +++ b/tools/munin-plugins-busybox/README @@ -0,0 +1,30 @@ +What is this? +~~~~~~~~~~~~~ +This is a rewrite of commonly used plugins in C as a single binary. The +purpose is reducing resource usage: + * disk space: the binary is smaler than the plugins together + * more diskspace: it has no dependencies on other programs + * less forks: it does not fork internally + * faster startup: it doesn't start perl or shell + * less memory: just a small C program + * less file accesses: one binary for many plugins +This can be useful for machines with restricted resources like embedded +machines. + +What plugins are included? +~~~~~~~~~~~~~~~~~~~~~~~~~~ +cpu entropy forks fw_packets interrupts load open_files open_inodes +processes swap uptime + +How to use? +~~~~~~~~~~~ +After compiling there will be binary munin-plugins-busybox. You can just +replace symlinks in /etc/munin/plugins/ with symlinks to this binary. + +License? +~~~~~~~~ +(C) 2008 Helmut Grohne +GPLv3 applies to *.c *.h and Makefile + +# vim7:spelllang=en +# vim:textwidth=75 From 1adee557369190c0da15183c61a91a8167734107 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 21 Jun 2008 12:18:23 +0000 Subject: [PATCH 051/109] it was not really clear to be about munin --- tools/munin-plugins-busybox/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/munin-plugins-busybox/README b/tools/munin-plugins-busybox/README index 2945e709..4d8df262 100644 --- a/tools/munin-plugins-busybox/README +++ b/tools/munin-plugins-busybox/README @@ -1,7 +1,7 @@ What is this? ~~~~~~~~~~~~~ -This is a rewrite of commonly used plugins in C as a single binary. The -purpose is reducing resource usage: +This is a rewrite of commonly used munin plugins in C as a single binary. +The purpose is reducing resource usage: * disk space: the binary is smaler than the plugins together * more diskspace: it has no dependencies on other programs * less forks: it does not fork internally From a61fdfd103a15f3d747c7fbc94bb8737e037bbd6 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sat, 21 Jun 2008 12:18:50 +0000 Subject: [PATCH 052/109] readme -> disadvantages? --- tools/munin-plugins-busybox/README | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/munin-plugins-busybox/README b/tools/munin-plugins-busybox/README index 4d8df262..3e1457e0 100644 --- a/tools/munin-plugins-busybox/README +++ b/tools/munin-plugins-busybox/README @@ -16,6 +16,12 @@ What plugins are included? cpu entropy forks fw_packets interrupts load open_files open_inodes processes swap uptime +Disadvantages? +~~~~~~~~~~~~~~ +You lose flexibility. You can no longer just edit the plugin and if you try +you have to be very careful not to break it. If you want to deploy this you +have to create one binary for each architecture. + How to use? ~~~~~~~~~~~ After compiling there will be binary munin-plugins-busybox. You can just From bdf2dd257a054848948ea0136db01f79ce97714a Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Thu, 22 Jan 2009 14:30:31 +0000 Subject: [PATCH 053/109] added if_err_ plugin --- tools/munin-plugins-busybox/Makefile | 8 +- tools/munin-plugins-busybox/if_err_.c | 123 ++++++++++++++++++++++++++ tools/munin-plugins-busybox/main.c | 3 + 3 files changed, 130 insertions(+), 4 deletions(-) create mode 100644 tools/munin-plugins-busybox/if_err_.c diff --git a/tools/munin-plugins-busybox/Makefile b/tools/munin-plugins-busybox/Makefile index dae1b6c7..fe465f64 100644 --- a/tools/munin-plugins-busybox/Makefile +++ b/tools/munin-plugins-busybox/Makefile @@ -1,9 +1,9 @@ CC=gcc CFLAGS=-W -Wall -pedantic -Wextra -g -O2 -OBJS=main.o common.o cpu.o entropy.o forks.o fw_packets.o interrupts.o load.o \ - open_files.o open_inodes.o processes.o swap.o uptime.o -LINKS=cpu entropy forks fw_packets interrupts load open_files open_inodes \ - processes swap uptime +OBJS=main.o common.o cpu.o entropy.o forks.o fw_packets.o interrupts.o \ + if_err_.o load.o open_files.o open_inodes.o processes.o swap.o uptime.o +LINKS=cpu entropy forks fw_packets interrupts if_err_eth0 load open_files \ + open_inodes processes swap uptime %.o:%.c ${CC} ${CFLAGS} -c $< -o $@ diff --git a/tools/munin-plugins-busybox/if_err_.c b/tools/munin-plugins-busybox/if_err_.c new file mode 100644 index 00000000..caee6b3a --- /dev/null +++ b/tools/munin-plugins-busybox/if_err_.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include + +#define PROC_NET_DEV "/proc/net/dev" + +int if_err_(int argc, char **argv) { + char *interface; + FILE *f; + char buff[256], *s; + int i; + + interface = basename(argv[0]); + if(strncmp(interface, "if_err_", 7) != 0) { + fputs("if_err_ invoked with invalid basename\n", stderr); + return 1; + } + interface += 7; + + if(argc > 1) { + if(!strcmp(argv[1], "autoconf")) { + if(access(PROC_NET_DEV, R_OK) == 0) { + puts("yes"); + return 0; + } else { + puts("no (/proc/net/dev not found)"); + return 1; + } + } + if(!strcmp(argv[1], "suggest")) { + if(NULL == (f = fopen(PROC_NET_DEV, "r"))) + return 1; + while(fgets(buff, 256, f)) { + for(s=buff;*s == ' ';++s) + ; + i = 0; + if(!strncmp(s, "eth", 3)) + i = 3; + else if(!strncmp(s, "wlan", 4)) + i = 4; + else if(!strncmp(s, "ath", 3)) + i = 3; + else if(!strncmp(s, "ra", 2)) + i = 2; + if(i == 0) + continue; + while(isdigit(s[i])) + ++i; + if(s[i] != ':') + continue; + s[i] = '\0'; + puts(s); + } + fclose(f); + return 0; + } + if(!strcmp(argv[1], "config")) { + puts("graph_order rcvd trans"); + printf("graph_title %s errors\n", interface); + puts("graph_args --base 1000\n" + "graph_vlabel packets in (-) / out (+) per " + "${graph_period}\n" + "graph_category network"); + printf("graph_info This graph shows the amount of " + "errors on the %s network interface.\n", + interface); + puts("rcvd.label packets\n" + "rcvd.type COUNTER\n" + "rcvd.graph no\n" + "rcvd.warning 1\n" + "trans.label packets\n" + "trans.type COUNTER\n" + "trans.negative rcvd\n" + "trans.warning 1"); + return 0; + } + } + if(NULL == (f = fopen(PROC_NET_DEV, "r"))) + return 1; + while(fgets(buff, 256, f)) { + for(s=buff;*s == ' ';++s) + ; + if(0 != strncmp(s, interface, strlen(interface))) + continue; + s += strlen(interface); + if(*s != ':') + continue; + ++s; + + while(*s == ' ') + ++s; + + for(i=1;i<3;++i) { + while(isdigit(*s)) + ++s; + while(isspace(*s)) + ++s; + } + for(i=0;isdigit(s[i]);++i) + ; + printf("rcvd.value "); + fwrite(s, 1, i, stdout); + putchar('\n'); + s += i; + while(isspace(*s)) + ++s; + + for(i=4;i<11;++i) { + while(isdigit(*s)) + ++s; + while(isspace(*s)) + ++s; + } + for(i=0;isdigit(s[i]);++i) + ; + printf("trans.value "); + fwrite(s, 1, i, stdout); + putchar('\n'); + } + return 0; +} diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index 348b4f65..b1833a04 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -6,6 +6,7 @@ int cpu(int argc, char **argv); int entropy(int argc, char **argv); int forks(int argc, char **argv); int fw_packets(int argc, char **argv); +int if_err_(int argc, char **argv); int interrupts(int argc, char **argv); int load(int argc, char **argv); int open_files(int argc, char **argv); @@ -35,6 +36,8 @@ int main(int argc, char **argv) { case 'i': if(!strcmp(progname+1, "nterrupts")) return interrupts(argc, argv); + if(!strncmp(progname+1, "f_err_", 6)) + return if_err_(argc, argv); break; case 'l': if(!strcmp(progname+1, "oad")) From 339b8f43a96583dcef3d6b1590ac2669418195ad Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Fri, 23 Jan 2009 12:48:30 +0000 Subject: [PATCH 054/109] added #define PROC_STAT "/proc/stat" --- tools/munin-plugins-busybox/common.h | 2 ++ tools/munin-plugins-busybox/cpu.c | 16 ++++++++-------- tools/munin-plugins-busybox/forks.c | 10 +++++----- tools/munin-plugins-busybox/interrupts.c | 8 ++++---- tools/munin-plugins-busybox/swap.c | 13 +++++++------ 5 files changed, 26 insertions(+), 23 deletions(-) diff --git a/tools/munin-plugins-busybox/common.h b/tools/munin-plugins-busybox/common.h index 67a5bebc..8db440a9 100644 --- a/tools/munin-plugins-busybox/common.h +++ b/tools/munin-plugins-busybox/common.h @@ -1,6 +1,8 @@ #ifndef COMMON_H #define COMMON_H +#define PROC_STAT "/proc/stat" + int writeyes(void); int writeno(const char *); diff --git a/tools/munin-plugins-busybox/cpu.c b/tools/munin-plugins-busybox/cpu.c index 171a3d3c..9f3483f8 100644 --- a/tools/munin-plugins-busybox/cpu.c +++ b/tools/munin-plugins-busybox/cpu.c @@ -19,8 +19,8 @@ int cpu(int argc, char **argv) { if(s && !strcmp(s, "yes")) scaleto100=1; - if(!(f=fopen("/proc/stat", "r"))) { - fputs("cannot open /proc/stat\n", stderr); + if(!(f=fopen(PROC_STAT, "r"))) { + fputs("cannot open " PROC_STAT "\n", stderr); return 1; } while(fgets(buff, 256, f)) { @@ -37,7 +37,7 @@ int cpu(int argc, char **argv) { fclose(f); if(ncpu < 1 || extinfo < 4) { - fputs("cannot parse /proc/stat\n", stderr); + fputs("cannot parse " PROC_STAT "\n", stderr); return 1; } @@ -114,14 +114,14 @@ int cpu(int argc, char **argv) { return 0; } if(!strcmp(argv[1], "autoconf")) { - if(0 == access("/proc/stat", R_OK)) + if(0 == access(PROC_STAT, R_OK)) return writeyes(); else - return writeno("/proc/stat not readable"); + return writeno(PROC_STAT " not readable"); } } - if(!(f=fopen("/proc/stat", "r"))) { - fputs("cannot open /proc/stat\n", stderr); + if(!(f=fopen(PROC_STAT, "r"))) { + fputs("cannot open " PROC_STAT "\n", stderr); return 1; } while(fgets(buff, 256, f)) { @@ -152,6 +152,6 @@ int cpu(int argc, char **argv) { } } fclose(f); - fputs("no cpu line found in /proc/stat\n", stderr); + fputs("no cpu line found in " PROC_STAT "\n", stderr); return 1; } diff --git a/tools/munin-plugins-busybox/forks.c b/tools/munin-plugins-busybox/forks.c index fa4dadb4..3d4a198e 100644 --- a/tools/munin-plugins-busybox/forks.c +++ b/tools/munin-plugins-busybox/forks.c @@ -21,14 +21,14 @@ int forks(int argc, char **argv) { return 0; } if(!strcmp(argv[1], "autoconf")) { - if(0 == access("/proc/stat", R_OK)) + if(0 == access(PROC_STAT, R_OK)) return writeyes(); else - return writeno("/proc/stat not readable"); + return writeno(PROC_STAT " not readable"); } } - if(!(f=fopen("/proc/stat", "r"))) { - fputs("cannot open /proc/stat\n", stderr); + if(!(f=fopen(PROC_STAT, "r"))) { + fputs("cannot open " PROC_STAT "\n", stderr); return 1; } while(fgets(buff, 256, f)) { @@ -39,6 +39,6 @@ int forks(int argc, char **argv) { } } fclose(f); - fputs("no processes line found in /proc/stat\n", stderr); + fputs("no processes line found in " PROC_STAT "\n", stderr); return 1; } diff --git a/tools/munin-plugins-busybox/interrupts.c b/tools/munin-plugins-busybox/interrupts.c index 2755ccf6..8c800c61 100644 --- a/tools/munin-plugins-busybox/interrupts.c +++ b/tools/munin-plugins-busybox/interrupts.c @@ -26,14 +26,14 @@ int interrupts(int argc, char **argv) { return 0; } if(!strcmp(argv[1], "autoconf")) { - if(0 == access("/proc/stat", R_OK)) + if(0 == access(PROC_STAT, R_OK)) return writeyes(); else - return writeno("/proc/stat not readable"); + return writeno(PROC_STAT " not readable"); } } - if(!(f=fopen("/proc/stat", "r"))) { - fputs("cannot open /proc/stat\n", stderr); + if(!(f=fopen(PROC_STAT, "r"))) { + fputs("cannot open " PROC_STAT "\n", stderr); return 1; } while(fgets(buff, 256, f)) { diff --git a/tools/munin-plugins-busybox/swap.c b/tools/munin-plugins-busybox/swap.c index 1a270fe8..3decfbb0 100644 --- a/tools/munin-plugins-busybox/swap.c +++ b/tools/munin-plugins-busybox/swap.c @@ -27,10 +27,10 @@ int swap(int argc, char **argv) { return 0; } if(!strcmp(argv[1], "autoconf")) { - if(0 == access("/proc/stat", R_OK)) + if(0 == access(PROC_STAT, R_OK)) return writeyes(); else - return writeno("/proc/stat not readable"); + return writeno(PROC_STAT " not readable"); } } if(!access("/proc/vmstat", F_OK)) { @@ -56,15 +56,16 @@ int swap(int argc, char **argv) { } return 0; } else { - if(!(f=fopen("/proc/stat", "r"))) { - fputs("cannot open /proc/stat\n", stderr); + if(!(f=fopen(PROC_STAT, "r"))) { + fputs("cannot open " PROC_STAT "\n", stderr); return 1; } while(fgets(buff, 256, f)) { if(!strncmp(buff, "swap ", 5)) { fclose(f); if(2 != sscanf(buff+5, "%d %d", &in, &out)) { - fputs("bad data on /proc/stat\n", stderr); + fputs("bad data on " PROC_STAT "\n", + stderr); return 1; } printf("swap_in.value %d\nswap_out.value %d\n", in, out); @@ -72,7 +73,7 @@ int swap(int argc, char **argv) { } } fclose(f); - fputs("no swap line found in /proc/stat\n", stderr); + fputs("no swap line found in " PROC_STAT "\n", stderr); return 1; } } From 611bfb05808041e6841b41cb5230515611c79d79 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Fri, 23 Jan 2009 12:56:20 +0000 Subject: [PATCH 055/109] made more paths be macros --- tools/munin-plugins-busybox/entropy.c | 8 ++++--- tools/munin-plugins-busybox/fw_packets.c | 12 ++++++----- tools/munin-plugins-busybox/load.c | 8 ++++--- tools/munin-plugins-busybox/open_files.c | 26 ++++++++++++++--------- tools/munin-plugins-busybox/open_inodes.c | 12 ++++++----- 5 files changed, 40 insertions(+), 26 deletions(-) diff --git a/tools/munin-plugins-busybox/entropy.c b/tools/munin-plugins-busybox/entropy.c index 4a5d8468..cc7791fd 100644 --- a/tools/munin-plugins-busybox/entropy.c +++ b/tools/munin-plugins-busybox/entropy.c @@ -2,6 +2,8 @@ #include #include "common.h" +#define ENTROPY_AVAIL "/proc/sys/kernel/random/entropy_avail" + int entropy(int argc, char **argv) { FILE *f; int entropy; @@ -20,12 +22,12 @@ int entropy(int argc, char **argv) { if(!strcmp(argv[1], "autoconf")) return writeyes(); } - if(!(f=fopen("/proc/sys/kernel/random/entropy_avail", "r"))) { - fputs("cannot open /proc/sys/kernel/random/entropy_avail\n", stderr); + if(!(f=fopen(ENTROPY_AVAIL, "r"))) { + fputs("cannot open " ENTROPY_AVAIL "\n", stderr); return 1; } if(1 != fscanf(f, "%d", &entropy)) { - fputs("cannot read from /proc/sys/kernel/random/entropy_avail\n", stderr); + fputs("cannot read from " ENTROPY_AVAIL "\n", stderr); fclose(f); return 1; } diff --git a/tools/munin-plugins-busybox/fw_packets.c b/tools/munin-plugins-busybox/fw_packets.c index 06367dde..8e94fdea 100644 --- a/tools/munin-plugins-busybox/fw_packets.c +++ b/tools/munin-plugins-busybox/fw_packets.c @@ -4,6 +4,8 @@ #include #include "common.h" +#define PROC_NET_SNMP "/proc/net/snmp" + int fw_packets(int argc, char **argv) { FILE *f; char buff[1024], *s; @@ -24,14 +26,14 @@ int fw_packets(int argc, char **argv) { return 0; } if(!strcmp(argv[1], "autoconf")) { - if(0 == access("/proc/net/snmp", R_OK)) + if(0 == access(PROC_NET_SNMP, R_OK)) return writeyes(); else - return writeno("/proc/net/snmp not readable"); + return writeno(PROC_NET_SNMP " not readable"); } } - if(!(f=fopen("/proc/net/snmp", "r"))) { - fputs("cannot open /proc/net/snmp\n", stderr); + if(!(f=fopen(PROC_NET_SNMP, "r"))) { + fputs("cannot open " PROC_NET_SNMP "\n", stderr); return 1; } while(fgets(buff, 1024, f)) { @@ -55,6 +57,6 @@ int fw_packets(int argc, char **argv) { } } fclose(f); - fputs("no ip line found in /proc/net/snmp\n", stderr); + fputs("no ip line found in " PROC_NET_SNMP "\n", stderr); return 1; } diff --git a/tools/munin-plugins-busybox/load.c b/tools/munin-plugins-busybox/load.c index c894f5e2..27e18437 100644 --- a/tools/munin-plugins-busybox/load.c +++ b/tools/munin-plugins-busybox/load.c @@ -3,6 +3,8 @@ #include #include "common.h" +#define PROC_LOADAVG "/proc/loadavg" + int load(int argc, char **argv) { FILE *f; int warn, crit; @@ -32,12 +34,12 @@ int load(int argc, char **argv) { if(!strcmp(argv[1], "autoconf")) return writeyes(); } - if(!(f=fopen("/proc/loadavg", "r"))) { - fputs("cannot open /proc/loadavg\n", stderr); + if(!(f=fopen(PROC_LOADAVG, "r"))) { + fputs("cannot open " PROC_LOADAVG "\n", stderr); return 1; } if(1 != fscanf(f, "%*f %f", &val)) { - fputs("cannot read from /proc/loadavg\n", stderr); + fputs("cannot read from " PROC_LOADAVG "\n", stderr); fclose(f); return 1; } diff --git a/tools/munin-plugins-busybox/open_files.c b/tools/munin-plugins-busybox/open_files.c index 3f82c8b5..9eb5c3d7 100644 --- a/tools/munin-plugins-busybox/open_files.c +++ b/tools/munin-plugins-busybox/open_files.c @@ -3,18 +3,21 @@ #include #include "common.h" +#define FS_FILE_NR "/proc/sys/fs/file-nr" + int open_files(int argc, char **argv) { FILE *f; int alloc, freeh, avail; if(argc > 1) { if(!strcmp(argv[1], "config")) { - if(!(f=fopen("/proc/sys/fs/file-nr", "r"))) { - fprintf(stderr, "cannot open /proc/sys/fs/file-nr\n"); + if(!(f=fopen(FS_FILE_NR, "r"))) { + fprintf(stderr, "cannot open " FS_FILE_NR "\n"); return 1; } if(1 != fscanf(f, "%*d %*d %d", &avail)) { fclose(f); - fprintf(stderr, "cannot read from /proc/sys/fs/file-nr\n"); + fprintf(stderr, "cannot read from " FS_FILE_NR + "\n"); return 1; } fclose(f); @@ -26,24 +29,27 @@ int open_files(int argc, char **argv) { "used.label open files\n" "used.info The number of currently open files.\n" "max.label max open files\n" - "max.info The maximum supported number of open files. Tune by modifying /proc/sys/fs/file-max."); - printf("used.warning %d\nused.critical %d\n", (int)(avail*0.92), (int)(avail*0.98)); + "max.info The maximum supported number of open " + "files. Tune by modifying " FS_FILE_NR + "."); + printf("used.warning %d\nused.critical %d\n", + (int)(avail*0.92), (int)(avail*0.98)); return 0; } if(!strcmp(argv[1], "autoconf")) { - if(0 == access("/proc/sys/fs/file-nr", R_OK)) + if(0 == access(FS_FILE_NR, R_OK)) return writeyes(); else - return writeno("/proc/sys/fs/file-nr not readable"); + return writeno(FS_FILE_NR " not readable"); } } - if(!(f=fopen("/proc/sys/fs/file-nr", "r"))) { - fputs("cannot open /proc/sys/fs/file-nr\n", stderr); + if(!(f=fopen(FS_FILE_NR, "r"))) { + fputs("cannot open " FS_FILE_NR "\n", stderr); return 1; } if(3 != fscanf(f, "%d %d %d", &alloc, &freeh, &avail)) { fclose(f); - fputs("cannot read from /proc/sys/fs/file-nr\n", stderr); + fputs("cannot read from " FS_FILE_NR "\n", stderr); return 1; } fclose(f); diff --git a/tools/munin-plugins-busybox/open_inodes.c b/tools/munin-plugins-busybox/open_inodes.c index bc20cc60..d9e86577 100644 --- a/tools/munin-plugins-busybox/open_inodes.c +++ b/tools/munin-plugins-busybox/open_inodes.c @@ -3,6 +3,8 @@ #include #include "common.h" +#define FS_INODE_NR "/proc/sys/fs/inode-nr" + int open_inodes(int argc, char **argv) { FILE *f; int nr, freen; @@ -21,19 +23,19 @@ int open_inodes(int argc, char **argv) { return 0; } if(!strcmp(argv[1], "autoconf")) { - if(0 == access("/proc/sys/fs/inode-nr", R_OK)) + if(0 == access(FS_INODE_NR, R_OK)) return writeyes(); else - return writeno("/proc/sys/fs/inode-nr not readable"); + return writeno(FS_INODE_NR " not readable"); } } - if(!(f=fopen("/proc/sys/fs/inode-nr", "r"))) { - fputs("cannot open /proc/sys/fs/inode-nr\n", stderr); + if(!(f=fopen(FS_INODE_NR, "r"))) { + fputs("cannot open " FS_INODE_NR "\n", stderr); return 1; } if(2 != fscanf(f, "%d %d", &nr, &freen)) { fclose(f); - fputs("cannot read from /proc/sys/fs/inode-nr\n", stderr); + fputs("cannot read from " FS_INODE_NR "\n", stderr); return 1; } fclose(f); From 5dcd2ea54d63682993bb7cbbf7c535c24875ce1d Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 28 Jan 2013 12:57:51 +0100 Subject: [PATCH 056/109] relicense as GPLv2 --- tools/munin-plugins-busybox/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-plugins-busybox/README b/tools/munin-plugins-busybox/README index 3e1457e0..4f8c56be 100644 --- a/tools/munin-plugins-busybox/README +++ b/tools/munin-plugins-busybox/README @@ -30,7 +30,7 @@ replace symlinks in /etc/munin/plugins/ with symlinks to this binary. License? ~~~~~~~~ (C) 2008 Helmut Grohne -GPLv3 applies to *.c *.h and Makefile +At your choice GPLv2 or GPLv3 applies to *.c *.h and Makefile # vim7:spelllang=en # vim:textwidth=75 From 1956b4dd7b574f8be03a355fa61b045fc5fdcae1 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 28 Jan 2013 14:12:17 +0100 Subject: [PATCH 057/109] fix interrupts.c to actually work --- tools/munin-plugins-busybox/interrupts.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/munin-plugins-busybox/interrupts.c b/tools/munin-plugins-busybox/interrupts.c index 8c800c61..32171f6d 100644 --- a/tools/munin-plugins-busybox/interrupts.c +++ b/tools/munin-plugins-busybox/interrupts.c @@ -37,10 +37,13 @@ int interrupts(int argc, char **argv) { return 1; } while(fgets(buff, 256, f)) { - if(!strncmp(buff, "intr ", 5)) - printf("intr.value %s", buff+5); - else if(!strncmp(buff, "ctxt ", 5)) - printf("ctx.value %s", buff+5); + if(!strncmp(buff, "intr ", 5)) { + buff[5 + strcspn(buff + 5, " \t\n")] = '\0'; + printf("intr.value %s\n", buff+5); + } else if(!strncmp(buff, "ctxt ", 5)) { + buff[5 + strcspn(buff + 5, " \t\n")] = '\0'; + printf("ctx.value %s\n", buff+5); + } } fclose(f); return 0; From b9c124798fa1018ec5ad4cd65533ee1419583ace Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 28 Jan 2013 14:18:45 +0100 Subject: [PATCH 058/109] fix cpu.c config for more recent kernels It still lacks behind the vanilla cpu plugin. --- tools/munin-plugins-busybox/cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/munin-plugins-busybox/cpu.c b/tools/munin-plugins-busybox/cpu.c index 9f3483f8..3f9d9ff7 100644 --- a/tools/munin-plugins-busybox/cpu.c +++ b/tools/munin-plugins-busybox/cpu.c @@ -42,7 +42,7 @@ int cpu(int argc, char **argv) { } puts("graph_title CPU usage"); - if(extinfo == 7) + if(extinfo >= 7) puts("graph_order system user nice idle iowait irq softirq"); else puts("graph_order system user nice idle"); @@ -87,7 +87,7 @@ int cpu(int argc, char **argv) { "user.cdef user,%d,/\n" "nice.cdef nice,%d,/\n" "idle.cdef idle,%d,/\n", ncpu, ncpu, ncpu, ncpu); - if(extinfo == 7) { + if(extinfo >= 7) { puts("iowait.label iowait\n" "iowait.draw STACK\n" "iowait.min 0"); From 20f9c7fc37fe2bb0ebea6ca3b18dc0ac4e551d02 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 28 Jan 2013 15:53:30 +0100 Subject: [PATCH 059/109] munin-plugins-busybox: provide supported plugins via listplugins --- tools/munin-plugins-busybox/main.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index b1833a04..6dc67251 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -15,6 +15,20 @@ int processes(int argc, char **argv); int swap(int argc, char **argv); int uptime(int argc, char **argv); +int busybox(int argc, char **argv) { + if(argc < 2) { + fprintf(stderr, "missing parameter\n"); + return 1; + } + if(0 != strcmp(argv[1], "listplugins")) { + fprintf(stderr, "unknown parameter\n"); + return 1; + } + puts("cpu\nentropy\nforks\nfw_packets\ninterrupts\nload\n" + "open_files\nopen_inodes\nprocesses\nswap\nuptime"); + return 0; +} + int main(int argc, char **argv) { char *progname; progname = basename(argv[0]); @@ -43,6 +57,10 @@ int main(int argc, char **argv) { if(!strcmp(progname+1, "oad")) return load(argc, argv); break; + case 'm': + if(!strcmp(progname+1, "unin-plugins-busybox")) + return busybox(argc, argv); + break; case 'o': if(!strcmp(progname+1, "pen_files")) return open_files(argc, argv); @@ -62,6 +80,6 @@ int main(int argc, char **argv) { return uptime(argc, argv); break; } - fprintf(stderr, "function not specified\n"); + fprintf(stderr, "unknown basename\n"); return 1; } From c01ddbb0c0942d82c979392eed10753d5e17a5de Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 28 Jan 2013 16:35:25 +0100 Subject: [PATCH 060/109] extract function getenvint to common.c --- tools/munin-plugins-busybox/common.c | 9 +++++++++ tools/munin-plugins-busybox/common.h | 1 + tools/munin-plugins-busybox/load.c | 16 +++------------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/munin-plugins-busybox/common.c b/tools/munin-plugins-busybox/common.c index 3d78e518..fd291f06 100644 --- a/tools/munin-plugins-busybox/common.c +++ b/tools/munin-plugins-busybox/common.c @@ -1,4 +1,5 @@ #include +#include int writeyes(void) { puts("yes"); @@ -12,3 +13,11 @@ int writeno(const char *s) { puts("no"); return 1; } + +int getenvint(const char *name, int defvalue) { + const char *value; + value = getenv(name); + if(value == NULL) + return defvalue; + return atoi(value); +} diff --git a/tools/munin-plugins-busybox/common.h b/tools/munin-plugins-busybox/common.h index 8db440a9..2a344085 100644 --- a/tools/munin-plugins-busybox/common.h +++ b/tools/munin-plugins-busybox/common.h @@ -5,5 +5,6 @@ int writeyes(void); int writeno(const char *); +int getenvint(const char *, int); #endif diff --git a/tools/munin-plugins-busybox/load.c b/tools/munin-plugins-busybox/load.c index 27e18437..ee1491c1 100644 --- a/tools/munin-plugins-busybox/load.c +++ b/tools/munin-plugins-busybox/load.c @@ -7,28 +7,18 @@ int load(int argc, char **argv) { FILE *f; - int warn, crit; float val; - char *s; if(argc > 1) { if(!strcmp(argv[1], "config")) { - s = getenv("load_warn"); - if(s) - warn = atoi(s); - else - warn = 10; - s = getenv("load_crit"); - if(s) - crit = atoi(s); - else - crit = 120; puts("graph_title Load average\n" "graph_args --base 1000 -l 0\n" "graph_vlabel load\n" "graph_scale no\n" "graph_category system\n" "load.label load"); - printf("load.warning %d\nload.critical %d\n", warn, crit); + printf("load.warning %d\nload.critical %d\n", + getenvint("load_warn", 10), + getenvint("load_crit", 120)); return 0; } if(!strcmp(argv[1], "autoconf")) From 4bd77f20a5130adea407839cc29d8da0c674bf24 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 28 Jan 2013 16:42:38 +0100 Subject: [PATCH 061/109] backport HZ functionality to cpu.c --- tools/munin-plugins-busybox/cpu.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tools/munin-plugins-busybox/cpu.c b/tools/munin-plugins-busybox/cpu.c index 3f9d9ff7..2b2f0248 100644 --- a/tools/munin-plugins-busybox/cpu.c +++ b/tools/munin-plugins-busybox/cpu.c @@ -12,7 +12,7 @@ int cpu(int argc, char **argv) { FILE *f; char buff[256], *s; - int ncpu=0, extinfo=0, scaleto100=0; + int ncpu=0, extinfo=0, scaleto100=0, hz; if(argc > 1) { if(!strcmp(argv[1], "config")) { s = getenv("scaleto100"); @@ -125,29 +125,30 @@ int cpu(int argc, char **argv) { return 1; } while(fgets(buff, 256, f)) { + hz = getenvint("HZ", 100); if(!strncmp(buff, "cpu ", 4)) { fclose(f); if(!(s = strtok(buff+4, " \t"))) break; - printf("user.value %s\n", s); + printf("user.value %ld\n", atol(s) * 100 / hz); if(!(s = strtok(NULL, " \t"))) break; - printf("nice.value %s\n", s); + printf("nice.value %ld\n", atol(s) * 100 / hz); if(!(s = strtok(NULL, " \t"))) break; - printf("system.value %s\n", s); + printf("system.value %ld\n", atol(s) * 100 / hz); if(!(s = strtok(NULL, " \t"))) break; - printf("idle.value %s\n", s); + printf("idle.value %ld\n", atol(s) * 100 / hz); if(!(s = strtok(NULL, " \t"))) return 0; - printf("iowait.value %s\n", s); + printf("iowait.value %ld\n", atol(s) * 100 / hz); if(!(s = strtok(NULL, " \t"))) return 0; - printf("irq.value %s\n", s); + printf("irq.value %ld\n", atol(s) * 100 / hz); if(!(s = strtok(NULL, " \t"))) return 0; - printf("softirq.value %s\n", s); + printf("softirq.value %ld\n", atol(s) * 100 / hz); return 0; } } From 58ec362bb35bf590139fa90f2c4288ad8bff55d9 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 28 Jan 2013 16:56:22 +0100 Subject: [PATCH 062/109] teach cpu.c to print steal and guest --- tools/munin-plugins-busybox/cpu.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tools/munin-plugins-busybox/cpu.c b/tools/munin-plugins-busybox/cpu.c index 2b2f0248..2c68f889 100644 --- a/tools/munin-plugins-busybox/cpu.c +++ b/tools/munin-plugins-busybox/cpu.c @@ -111,6 +111,26 @@ int cpu(int argc, char **argv) { "irq.cdef irq,%d,/\n" "softirq.cdef softirq,%d,/\n", ncpu, ncpu, ncpu); } + if(extinfo >= 8) { + puts("steal.label steal\n" + "steal.draw STACK\n" + "steal.min 0"); + printf("steal.max %d\n", 100 * ncpu); + puts("steal.type DERIVE\n" + "steal.info The time that a virtual CPU had runnable tasks, but the virtual CPU itself was not running"); + if(scaleto100) + printf("steal.cdef steal,%d,/\n", ncpu); + } + if(extinfo >= 9) { + puts("guest.label guest\n" + "guest.draw STACK\n" + "guest.min 0"); + printf("guest.max %d\n", 100 * ncpu); + puts("guest.type DERIVE\n" + "guest.info The time spent running a virtual CPU for guest operating systems under the control of the Linux kernel."); + if(scaleto100) + printf("guest.cdef guest,%d,/\n", ncpu); + } return 0; } if(!strcmp(argv[1], "autoconf")) { @@ -149,6 +169,12 @@ int cpu(int argc, char **argv) { if(!(s = strtok(NULL, " \t"))) return 0; printf("softirq.value %ld\n", atol(s) * 100 / hz); + if(!(s = strtok(NULL, " \t"))) + return 0; + printf("steal.value %ld\n", atol(s) * 100 / hz); + if(!(s = strtok(NULL, " \t"))) + return 0; + printf("guest.value %ld\n", atol(s) * 100 / hz); return 0; } } From 8fbe0ebe27240eefdfba819a6e9ebe41eec2f210 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Thu, 10 Jan 2013 18:00:05 +0100 Subject: [PATCH 063/109] qos_: add ability to use custom update_rate --- plugins/network/qos_ | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/plugins/network/qos_ b/plugins/network/qos_ index 6382cfe1..3b9bc6fa 100755 --- a/plugins/network/qos_ +++ b/plugins/network/qos_ @@ -16,6 +16,8 @@ # tc - Override default program # ignore_queue - Queue with handle not be plotted # label_name - Queue with handle as defined label +# update_rate - Custom update_rate, to be used with async +# graph_data_size - Custom graph_data_size, to be used with async & custom update_rate # # Magic markers: #%# family=manual @@ -100,6 +102,8 @@ if ( exists $ARGV[0] and $ARGV[0] eq 'config' ) { print "graph_vlabel bits per \${graph_period}\n"; print "graph_category network\n"; print "graph_info This graph shows the QoS queue of the $IFACE network interface.\n"; + print "update_rate $ENV{update_rate}\n" if $ENV{update_rate}; + print "graph_data_size $ENV{graph_data_size}\n" if $ENV{graph_data_size}; print "graph_order "; foreach my $key (sort by_handle keys %queues) { $haschild = 0; From cbfa6b45786e6b11c8f31a75f04932f14ae96af1 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Wed, 30 Jan 2013 12:14:28 +0100 Subject: [PATCH 064/109] support warning and critical environment variables Like the mainline plugins do. --- tools/munin-plugins-busybox/common.c | 43 +++++++++++++++++++++++ tools/munin-plugins-busybox/common.h | 4 +++ tools/munin-plugins-busybox/entropy.c | 1 + tools/munin-plugins-busybox/forks.c | 1 + tools/munin-plugins-busybox/if_err_.c | 3 ++ tools/munin-plugins-busybox/interrupts.c | 2 ++ tools/munin-plugins-busybox/load.c | 4 +-- tools/munin-plugins-busybox/open_inodes.c | 3 +- tools/munin-plugins-busybox/swap.c | 3 +- tools/munin-plugins-busybox/uptime.c | 1 + 10 files changed, 60 insertions(+), 5 deletions(-) diff --git a/tools/munin-plugins-busybox/common.c b/tools/munin-plugins-busybox/common.c index fd291f06..3527ef78 100644 --- a/tools/munin-plugins-busybox/common.c +++ b/tools/munin-plugins-busybox/common.c @@ -1,5 +1,9 @@ #include #include +#include +#include + +extern char **environ; int writeyes(void) { puts("yes"); @@ -21,3 +25,42 @@ int getenvint(const char *name, int defvalue) { return defvalue; return atoi(value); } + +const char *getenv_composed(const char *name1, const char *name2) { + char **p; + size_t len1 = strlen(name1), len2 = strlen(name2); + for(p = environ; *p; ++p) { + if(0 == strncmp(*p, name1, len1) && + 0 == strncmp(len1 + *p, name2, len2) && + (*p)[len1 + len2] == '=') + return len1 + len2 + 1 + *p; + } + return NULL; +} + +void print_warning(const char *name) { + const char *p; + p = getenv_composed(name, "_warning"); + if(p == NULL) + p = getenv("warning"); + if(p == NULL) + return; + + printf("%s.warning %s\n", name, p); +} + +void print_critical(const char *name) { + const char *p; + p = getenv_composed(name, "_critical"); + if(p == NULL) + p = getenv("critical"); + if(p == NULL) + return; + + printf("%s.critial %s\n", name, p); +} + +void print_warncrit(const char *name) { + print_warning(name); + print_critical(name); +} diff --git a/tools/munin-plugins-busybox/common.h b/tools/munin-plugins-busybox/common.h index 2a344085..ac4d08c8 100644 --- a/tools/munin-plugins-busybox/common.h +++ b/tools/munin-plugins-busybox/common.h @@ -6,5 +6,9 @@ int writeyes(void); int writeno(const char *); int getenvint(const char *, int); +const char *getenv_composed(const char *, const char *); +void print_warning(const char *); +void print_critical(const char *); +void print_warncrit(const char *); #endif diff --git a/tools/munin-plugins-busybox/entropy.c b/tools/munin-plugins-busybox/entropy.c index cc7791fd..57206d2a 100644 --- a/tools/munin-plugins-busybox/entropy.c +++ b/tools/munin-plugins-busybox/entropy.c @@ -17,6 +17,7 @@ int entropy(int argc, char **argv) { "graph_info This graph shows the amount of entropy available in the system.\n" "entropy.label entropy\n" "entropy.info The number of random bytes available. This is typically used by cryptographic applications."); + print_warncrit("entropy"); return 0; } if(!strcmp(argv[1], "autoconf")) diff --git a/tools/munin-plugins-busybox/forks.c b/tools/munin-plugins-busybox/forks.c index 3d4a198e..eac1ccc4 100644 --- a/tools/munin-plugins-busybox/forks.c +++ b/tools/munin-plugins-busybox/forks.c @@ -18,6 +18,7 @@ int forks(int argc, char **argv) { "forks.min 0\n" "forks.max 100000\n" "forks.info The number of forks per second."); + print_warncrit("forks"); return 0; } if(!strcmp(argv[1], "autoconf")) { diff --git a/tools/munin-plugins-busybox/if_err_.c b/tools/munin-plugins-busybox/if_err_.c index caee6b3a..9bb62570 100644 --- a/tools/munin-plugins-busybox/if_err_.c +++ b/tools/munin-plugins-busybox/if_err_.c @@ -3,6 +3,7 @@ #include #include #include +#include "common.h" #define PROC_NET_DEV "/proc/net/dev" @@ -74,6 +75,8 @@ int if_err_(int argc, char **argv) { "trans.type COUNTER\n" "trans.negative rcvd\n" "trans.warning 1"); + print_warncrit("rcvd"); + print_warncrit("trans"); return 0; } } diff --git a/tools/munin-plugins-busybox/interrupts.c b/tools/munin-plugins-busybox/interrupts.c index 32171f6d..d38e05f2 100644 --- a/tools/munin-plugins-busybox/interrupts.c +++ b/tools/munin-plugins-busybox/interrupts.c @@ -23,6 +23,8 @@ int interrupts(int argc, char **argv) { "ctx.max 100000\n" "intr.min 0\n" "ctx.min 0"); + print_warncrit("intr"); + print_warncrit("ctx"); return 0; } if(!strcmp(argv[1], "autoconf")) { diff --git a/tools/munin-plugins-busybox/load.c b/tools/munin-plugins-busybox/load.c index ee1491c1..8161890f 100644 --- a/tools/munin-plugins-busybox/load.c +++ b/tools/munin-plugins-busybox/load.c @@ -16,9 +16,7 @@ int load(int argc, char **argv) { "graph_scale no\n" "graph_category system\n" "load.label load"); - printf("load.warning %d\nload.critical %d\n", - getenvint("load_warn", 10), - getenvint("load_crit", 120)); + print_warncrit("load"); return 0; } if(!strcmp(argv[1], "autoconf")) diff --git a/tools/munin-plugins-busybox/open_inodes.c b/tools/munin-plugins-busybox/open_inodes.c index d9e86577..a8db64f6 100644 --- a/tools/munin-plugins-busybox/open_inodes.c +++ b/tools/munin-plugins-busybox/open_inodes.c @@ -19,7 +19,8 @@ int open_inodes(int argc, char **argv) { "used.info The number of currently open inodes.\n" "max.label inode table size\n" "max.info The size of the system inode table. This is dynamically adjusted by the kernel."); - + print_warncrit("used"); + print_warncrit("max"); return 0; } if(!strcmp(argv[1], "autoconf")) { diff --git a/tools/munin-plugins-busybox/swap.c b/tools/munin-plugins-busybox/swap.c index 3decfbb0..a1b67234 100644 --- a/tools/munin-plugins-busybox/swap.c +++ b/tools/munin-plugins-busybox/swap.c @@ -23,7 +23,8 @@ int swap(int argc, char **argv) { "swap_out.max 100000\n" "swap_out.min 0\n" "swap_out.negative swap_in"); - + print_warncrit("swap_in"); + print_warncrit("swap_out"); return 0; } if(!strcmp(argv[1], "autoconf")) { diff --git a/tools/munin-plugins-busybox/uptime.c b/tools/munin-plugins-busybox/uptime.c index ce6093fa..bb3e02cd 100644 --- a/tools/munin-plugins-busybox/uptime.c +++ b/tools/munin-plugins-busybox/uptime.c @@ -12,6 +12,7 @@ int uptime(int argc, char **argv) { "graph_vlabel uptime in days\n" "uptime.label uptime\n" "uptime.draw AREA"); + print_warncrit("uptime"); return 0; } if(!strcmp(argv[1], "autoconf")) From 332c74d72025f9a2b51e0852125a484902f83f80 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 30 Jan 2013 19:34:30 +0100 Subject: [PATCH 065/109] CPU usage graph, skip list, some cleanup - xenskip option to skip graph types env.xenskip "" Modules: cput, cpup, mem, disk, net - CPU percentage graph added --- plugins/virtualization/xen-multi | 194 +++++++++++++++++++------------ 1 file changed, 122 insertions(+), 72 deletions(-) diff --git a/plugins/virtualization/xen-multi b/plugins/virtualization/xen-multi index c57a2b8d..4b61d876 100755 --- a/plugins/virtualization/xen-multi +++ b/plugins/virtualization/xen-multi @@ -19,6 +19,9 @@ configuration: [xen-multi] user root + env.xenskip "" + +Modules: cput, cpup, mem, disk, net Then restart munin-node and you're done. @@ -34,10 +37,14 @@ NOTE: xentop always reports 0 for dom0's disk IOs and network traffic, but both graphs show its entry all the same, so each domain can keep its own color along the different graphs. -=head2 CPU usage +=head2 CPU time This graph shows a percentage of the CPU time used by each domain. +=head2 CPU usage + +This graph shows a percentage of the CPU percentage used by each domain. + =head2 Memory usage This graph shows the amount of memory (in bytes) used by each domain. @@ -66,6 +73,7 @@ Michael Renner for the C plugin which I borrowed some code from. =head1 AUTHOR Raphael HALIMI +Modified by Krisztian IVANCSO =head1 LICENSE @@ -76,6 +84,8 @@ GPLv2 use strict; use Munin::Plugin; +my $XEN_SKIP = $ENV{xenskip} || ""; + # autoconf - quite simple if ($ARGV[0] eq "autoconf") { if (`which xentop`) { @@ -101,7 +111,7 @@ if ($ARGV[0] eq "autoconf") { sub trim_label { my ($type, $label) = @_; my $data_characters; - my ($graph_width, $graph_border_width, $padding_characters, $pixels_per_character) = (400,97,10,6); + my ($graph_width, $graph_border_width, $padding_characters, $pixels_per_character) = (497,3,5,6); if ($type eq 'pos') {$data_characters = 32;} elsif ($type eq 'neg') {$data_characters = 64;} else {return $label;} my $available_characters = abs(($graph_width+$graph_border_width)/$pixels_per_character)-$padding_characters-$data_characters; @@ -117,9 +127,9 @@ sub trim_label { } # Global variables -my (%domains,$domain,$munindomain,$cpusecs,$memk,$nettxk,$netrxk,$vbdrd,$vbdwr); +my (%domains,$domain,@domainlist,$munindomain,$cpusecs,$cpupercent,$memk,$nettxk,$netrxk,$vbdrd,$vbdwr); -open (XENTOP,"xentop -b -f -i1 |") or die "Could not execute xentop, $!"; +open (XENTOP,"xentop -b -f -i2 |") or die "Could not execute xentop, $!"; # Now we build a hash of hashes to store information while () { @@ -129,7 +139,7 @@ while () { next if /^NAME/; # We define only what we need - ($domain,undef,$cpusecs,undef,$memk,undef,undef,undef,undef,undef,$nettxk,$netrxk,undef,undef,$vbdrd,$vbdwr,undef,undef,undef) = split(/\s+/); + ($domain,undef,$cpusecs,$cpupercent,$memk,undef,undef,undef,undef,undef,$nettxk,$netrxk,undef,undef,$vbdrd,$vbdwr,undef,undef,undef) = split(/\s+/); # We have to store the sanitised domain name in a separate variable $domains{$domain}{'munindomain'} = clean_fieldname($domain); @@ -137,6 +147,7 @@ while () { # We need the remaining data only for a normal run if ($ARGV[0] eq "") { $domains{$domain}{'cpusecs'} = $cpusecs; + $domains{$domain}{'cpupercent'} = $cpupercent; $domains{$domain}{'mem'} = $memk; $domains{$domain}{'nettx'} = $nettxk; $domains{$domain}{'netrx'} = $netrxk; @@ -145,71 +156,94 @@ while () { } } +@domainlist = sort(keys(%domains)); # # config - quite simple, too # if ($ARGV[0] eq "config") { - print "multigraph xen_cpu_time\n"; - print "graph_title Xen domains CPU time\n"; - print "graph_args --base 1000 -l 0\n"; - print "graph_vlabel %\n"; - print "graph_scale no\n"; - print "graph_category xen\n"; - print "graph_info This graph shows CPU time for each Xen domain.\n"; - for $domain (sort(keys(%domains))) { - print "$domains{$domain}{'munindomain'}_cpu_time.label ".trim_label('pos',$domain)."\n"; - print "$domains{$domain}{'munindomain'}_cpu_time.type DERIVE\n"; - print "$domains{$domain}{'munindomain'}_cpu_time.cdef $domains{$domain}{'munindomain'}_cpu_time,100,*\n"; - print "$domains{$domain}{'munindomain'}_cpu_time.min 0\n"; - print "$domains{$domain}{'munindomain'}_cpu_time.draw AREASTACK\n"; + if ($XEN_SKIP !~ /cput/) { + print "multigraph xen_cpu_time\n"; + print "graph_title Xen domains CPU time\n"; + print "graph_args --base 1000 -l 0\n"; + print "graph_vlabel cpu seconds\n"; + print "graph_scale no\n"; + print "graph_category xen\n"; + print "graph_info This graph shows CPU time for each Xen domain.\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_cpu_time.label ".trim_label('pos',$domain)."\n"; + print "$domains{$domain}{'munindomain'}_cpu_time.type DERIVE\n"; + print "$domains{$domain}{'munindomain'}_cpu_time.cdef $domains{$domain}{'munindomain'}_cpu_time,100,*\n"; + print "$domains{$domain}{'munindomain'}_cpu_time.min 0\n"; + print "$domains{$domain}{'munindomain'}_cpu_time.draw AREASTACK\n"; + } } - print "\nmultigraph xen_mem\n"; - print "graph_title Xen domains memory usage\n"; - print "graph_args --base 1024 -l 0\n"; - print "graph_vlabel bytes\n"; - print "graph_category xen\n"; - print "graph_info This graph shows memory usage for each Xen domain.\n"; - for $domain (sort(keys(%domains))) { - print "$domains{$domain}{'munindomain'}_mem.label ".trim_label('pos',$domain)."\n"; - print "$domains{$domain}{'munindomain'}_mem.cdef $domains{$domain}{'munindomain'}_mem,1024,*\n"; - print "$domains{$domain}{'munindomain'}_mem.draw AREASTACK\n"; + if ($XEN_SKIP !~ /cpup/) { + print "\nmultigraph xen_cpu\n"; + print "graph_title Xen domains CPU utilization\n"; + print "graph_args --base 1000 -l 0 --upper-limit 100\n"; + print "graph_vlabel %\n"; + print "graph_scale no\n"; + print "graph_category xen\n"; + print "graph_info This graph shows CPU utilization for each Xen domain.\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_cpu.label ".trim_label('pos',$domain)."\n"; + print "$domains{$domain}{'munindomain'}_cpu.draw AREASTACK\n" + } } - print "\nmultigraph xen_net\n"; - print "graph_title Xen domains network traffic\n"; - print "graph_args --base 1000\n"; - print "graph_vlabel bits per \${graph_period} in (-) / out (+)\n"; - print "graph_category xen\n"; - print "graph_info This graph shows network traffic for each Xen domain.\n"; - for $domain (sort(keys(%domains))) { - print "$domains{$domain}{'munindomain'}_netrx.label none\n"; - print "$domains{$domain}{'munindomain'}_netrx.cdef $domains{$domain}{'munindomain'}_netrx,8192,*\n"; - print "$domains{$domain}{'munindomain'}_netrx.type COUNTER\n"; - print "$domains{$domain}{'munindomain'}_netrx.graph no\n"; - print "$domains{$domain}{'munindomain'}_nettx.label ".trim_label('neg',$domain)."\n"; - print "$domains{$domain}{'munindomain'}_nettx.cdef $domains{$domain}{'munindomain'}_nettx,8192,*\n"; - print "$domains{$domain}{'munindomain'}_nettx.type COUNTER\n"; - print "$domains{$domain}{'munindomain'}_nettx.draw AREASTACK\n"; - print "$domains{$domain}{'munindomain'}_nettx.negative $domains{$domain}{'munindomain'}_netrx\n"; + if ($XEN_SKIP !~ /mem/) { + print "\nmultigraph xen_mem\n"; + print "graph_title Xen domains memory usage\n"; + print "graph_args --base 1024 -l 0\n"; + print "graph_vlabel bytes\n"; + print "graph_category xen\n"; + print "graph_info This graph shows memory usage for each Xen domain.\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_mem.label ".trim_label('pos',$domain)."\n"; + print "$domains{$domain}{'munindomain'}_mem.cdef $domains{$domain}{'munindomain'}_mem,1024,*\n"; + print "$domains{$domain}{'munindomain'}_mem.draw AREASTACK\n"; + } } - print "\nmultigraph xen_disk\n"; - print "graph_title Xen domains disk IOs\n"; - print "graph_args --base 1000\n"; - print "graph_vlabel IOs per \${graph_period} read (-) / write (+)\n"; - print "graph_category xen\n"; - print "graph_info This graph shows disk IOs for each Xen domain.\n"; - for $domain (sort(keys(%domains))) { - print "$domains{$domain}{'munindomain'}_vbdrd.label none\n"; - print "$domains{$domain}{'munindomain'}_vbdrd.type COUNTER\n"; - print "$domains{$domain}{'munindomain'}_vbdrd.graph no\n"; - print "$domains{$domain}{'munindomain'}_vbdwr.label ".trim_label('neg',$domain)."\n"; - print "$domains{$domain}{'munindomain'}_vbdwr.type COUNTER\n"; - print "$domains{$domain}{'munindomain'}_vbdwr.draw AREASTACK\n"; - print "$domains{$domain}{'munindomain'}_vbdwr.negative $domains{$domain}{'munindomain'}_vbdrd\n"; + if ($XEN_SKIP !~ /net/) { + print "\nmultigraph xen_net\n"; + print "graph_title Xen domains network traffic\n"; + print "graph_args --base 1000\n"; + print "graph_vlabel bits per \${graph_period} in (-) / out (+)\n"; + print "graph_category xen\n"; + print "graph_info This graph shows network traffic for each Xen domain.\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_netrx.label none\n"; + print "$domains{$domain}{'munindomain'}_netrx.cdef $domains{$domain}{'munindomain'}_netrx,8192,*\n"; + print "$domains{$domain}{'munindomain'}_netrx.type COUNTER\n"; + print "$domains{$domain}{'munindomain'}_netrx.graph no\n"; + print "$domains{$domain}{'munindomain'}_nettx.label ".trim_label('neg',$domain)."\n"; + print "$domains{$domain}{'munindomain'}_nettx.cdef $domains{$domain}{'munindomain'}_nettx,8192,*\n"; + print "$domains{$domain}{'munindomain'}_nettx.type COUNTER\n"; + print "$domains{$domain}{'munindomain'}_nettx.draw AREASTACK\n"; + print "$domains{$domain}{'munindomain'}_nettx.negative $domains{$domain}{'munindomain'}_netrx\n"; + } + } + + if ($XEN_SKIP !~ /disk/) { + print "\nmultigraph xen_disk\n"; + print "graph_title Xen domains disk IOs\n"; + print "graph_args --base 1000\n"; + print "graph_vlabel IOs per \${graph_period} read (-) / write (+)\n"; + print "graph_category xen\n"; + print "graph_info This graph shows disk IOs for each Xen domain.\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_vbdrd.label none\n"; + print "$domains{$domain}{'munindomain'}_vbdrd.type COUNTER\n"; + print "$domains{$domain}{'munindomain'}_vbdrd.graph no\n"; + print "$domains{$domain}{'munindomain'}_vbdwr.label ".trim_label('neg',$domain)."\n"; + print "$domains{$domain}{'munindomain'}_vbdwr.type COUNTER\n"; + print "$domains{$domain}{'munindomain'}_vbdwr.draw AREASTACK\n"; + print "$domains{$domain}{'munindomain'}_vbdwr.negative $domains{$domain}{'munindomain'}_vbdrd\n"; + } } exit 0; @@ -220,24 +254,40 @@ if ($ARGV[0] eq "config") { # Normal run # -print "multigraph xen_cpu_time\n"; -for $domain (sort(keys(%domains))) { - print "$domains{$domain}{'munindomain'}_cpu_time.value $domains{$domain}{'cpusecs'}\n"; +if ($XEN_SKIP !~ /cput/) { + print "multigraph xen_cpu_time\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_cpu_time.value $domains{$domain}{'cpusecs'}\n"; + } } -print "\nmultigraph xen_mem\n"; -for $domain (sort(keys(%domains))) { - print "$domains{$domain}{'munindomain'}_mem.value $domains{$domain}{'mem'}\n"; +if ($XEN_SKIP !~ /cpup/) { + print "\nmultigraph xen_cpu\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_cpu.value $domains{$domain}{'cpupercent'}\n"; + } } -print "\nmultigraph xen_net\n"; -for $domain (sort(keys(%domains))) { - print "$domains{$domain}{'munindomain'}_nettx.value $domains{$domain}{'nettx'}\n"; - print "$domains{$domain}{'munindomain'}_netrx.value $domains{$domain}{'netrx'}\n"; +if ($XEN_SKIP !~ /mem/) { + print "\nmultigraph xen_mem\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_mem.value $domains{$domain}{'mem'}\n"; + } } -print "\nmultigraph xen_disk\n"; -for $domain (sort(keys(%domains))) { - print "$domains{$domain}{'munindomain'}_vbdrd.value $domains{$domain}{'vbdrd'}\n"; - print "$domains{$domain}{'munindomain'}_vbdwr.value $domains{$domain}{'vbdwr'}\n"; +if ($XEN_SKIP !~ /net/) { + print "\nmultigraph xen_net\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_nettx.value $domains{$domain}{'nettx'}\n"; + print "$domains{$domain}{'munindomain'}_netrx.value $domains{$domain}{'netrx'}\n"; + } } + +if ($XEN_SKIP !~ /disk/) { + print "\nmultigraph xen_disk\n"; + for $domain (@domainlist) { + print "$domains{$domain}{'munindomain'}_vbdrd.value $domains{$domain}{'vbdrd'}\n"; + print "$domains{$domain}{'munindomain'}_vbdwr.value $domains{$domain}{'vbdwr'}\n"; + } +} + From 67cdc919bbf7801f6110628105469ae23f703471 Mon Sep 17 00:00:00 2001 From: ufoonline Date: Sat, 2 Feb 2013 21:27:37 +0100 Subject: [PATCH 066/109] Update plugins/mail/qmailconn # 2013-02-02 - Added support for Greylist and simscan Virus\Spam detect # Added LOGPATH env var --- plugins/mail/qmailconn | 58 +++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/plugins/mail/qmailconn b/plugins/mail/qmailconn index 65413ef2..51f7070c 100755 --- a/plugins/mail/qmailconn +++ b/plugins/mail/qmailconn @@ -2,7 +2,11 @@ # # Plugin to show amount of smtp-connections per hour # -# Contributed by Håkon Nessjøen +# Contributed by H�kon Nessj�en +# +# Modified by Massimiliano Cianelli +# 2013-02-02 - Added support for Greylist and simscan Virus\Spam detect +# Added LOGPATH env var # # Magic markers - optional - used by installation scripts and # munin-config: @@ -10,6 +14,9 @@ #%# family=manual #%# capabilities=autoconf +# get: env.logpath +LOGPATH=${logpath:-/var/log/qmail/qmail-smtpd/} + if [ "$1" = "autoconf" ]; then echo yes exit 0 @@ -17,26 +24,41 @@ fi if [ "$1" = "config" ]; then - echo 'graph_title Qmail SMTP connections' - echo 'graph_args --base 1000 -l 0 ' - echo 'graph_vlabel connections/hour' - echo 'graph_category Mail' - echo 'graph_order rbl accepted total' - echo 'rbl.label RBL rejected connections' - echo 'rbl.min 0' - echo 'rbl.draw AREA' - echo 'accepted.label Accepted connections' - echo 'accepted.min 0' - echo 'accepted.draw STACK' - echo 'total.label Total connections' - echo 'total.min 0' - echo 'total.draw LINE1' + echo 'graph_title Qmail SMTP connections' + echo 'graph_args --base 1000 -l 0 ' + echo 'graph_vlabel connections/hour' + echo 'graph_category mail' + echo 'graph_order rbl greylisted accepted simscan_spam simscan_virus total' + echo 'rbl.label RBL rejected connections' + echo 'rbl.min 0' + echo 'rbl.draw AREA' + echo 'greylisted.label Greylisted connections' + echo 'greylisted.min 0' + echo 'greylisted.draw STACK' + echo 'accepted.label Accepted connections' + echo 'accepted.min 0' + echo 'accepted.draw STACK' + echo 'simscan_spam.label Rejected SPAM' + echo 'simscan_spam.min 0' + echo 'simscan_spam.draw STACK' + echo 'simscan_virus.label Rejected VIRUS' + echo 'simscan_virus.min 0' + echo 'simscan_virus.draw STACK' + echo 'total.label Total connections' + echo 'total.min 0' + echo 'total.draw LINE1' exit 0 fi -rbl=`cat /var/log/qmail/smtpd/@* /var/log/qmail/smtpd/current | grep -c rblsmtp` -accepted=`cat /var/log/qmail/smtpd/@* /var/log/qmail/smtpd/current | grep -c 'tcpserver: ok'` +rbl=`cat $LOGPATH/@* $LOGPATH/current | grep -c rblsmtp` +accepted=`cat $LOGPATH/@* $LOGPATH/current | grep -c 'tcpserver: ok'` +greylisted=`cat $LOGPATH/@* $LOGPATH/current | grep -ce "jgreylist\[[[:digit:]]\+\]: .\+\: GREY"` +simscan_spam=`cat $LOGPATH/@* $LOGPATH/current | grep -ce "simscan:\[[[:digit:]]\+\]:SPAM"` +simscan_virus=`cat $LOGPATH/@* $LOGPATH/current | grep -ce "simscan:\[[[:digit:]]\+\]:VIRUS"` echo -n "rbl.value " && ( echo $rbl || echo U ) echo -n "accepted.value " && ( echo $accepted || echo U ) -echo "total.value $[$rbl + $accepted]" +echo -n "greylisted.value " && ( echo $greylisted || echo U ) +echo -n "simscan_spam.value " && ( echo $simscan_spam || echo U ) +echo -n "simscan_virus.value " && ( echo $simscan_virus || echo U ) +echo "total.value $(expr $rbl + $accepted + $greylisted)" From 7d0375b365a157a71d913dc07b0326ef49d7a397 Mon Sep 17 00:00:00 2001 From: Kenyon Ralph Date: Sat, 2 Feb 2013 20:14:37 -0800 Subject: [PATCH 067/109] mail/qmailconn: fix author's name --- plugins/mail/qmailconn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mail/qmailconn b/plugins/mail/qmailconn index 51f7070c..eb4fbf9e 100755 --- a/plugins/mail/qmailconn +++ b/plugins/mail/qmailconn @@ -2,7 +2,7 @@ # # Plugin to show amount of smtp-connections per hour # -# Contributed by H�kon Nessj�en +# Contributed by HÃ¥kon Nessjøen # # Modified by Massimiliano Cianelli # 2013-02-02 - Added support for Greylist and simscan Virus\Spam detect From d00cbc952c24ba1755efb4cc6e27ddb72b1a886f Mon Sep 17 00:00:00 2001 From: Michiel Holtkamp Date: Sun, 3 Feb 2013 02:57:04 +0100 Subject: [PATCH 068/109] Converted traffic plugin to use iptables/ip6tables You can now choose to use the snmp counters or if your host does not support it (in some containers for example), you can set rules in your firewall and count based on that. --- plugins/network/traffic_ipt | 128 ++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100755 plugins/network/traffic_ipt diff --git a/plugins/network/traffic_ipt b/plugins/network/traffic_ipt new file mode 100755 index 00000000..d03b45b2 --- /dev/null +++ b/plugins/network/traffic_ipt @@ -0,0 +1,128 @@ +#!/bin/bash +# -*- bash -*- + +: << =cut + +=head1 NAME + +traffic - Plugin to monitor the traffic (throughput) by IP protocols. + +=head1 CONFIGURATION + +To make this plugin work, you need to add rules to your firewall. +They are empty rules, we only use them to count traffic, not do anything +with them. To make this plugin work correctly, these rules have to +in the beginning of the chain(s), or else traffic that matches rules +above will not be counted (you can use this to your advantage of course). + +The rules can be added with: +iptables -I INPUT +iptables -I OUTPUT +ip6tables -I INPUT +ip6tables -I OUTPUT + +If trouble reading output, use: + + [traffic_ipt] + user root + +=head1 AUTHORS + +=over + +=item 2012.09.20: Initial version by Arturo Borrero Gonzalez + +=item 2013.01.12: Added percentage graphing by Michiel Holtkamp + +=item 2013.02.03: Converted to use iptables/ip6tables by Michiel Holtkamp + +=back + +=head1 LICENSE + +GPLv2 + +=head1 MAGIC MARKERS + + #%# family=auto + #%# capabilities=autoconf + +=cut + + +if [ "$1" == "config" ] +then + cat <<'EOF' +multigraph traffic_ipt +graph_title Throughput by IP protocol +graph_vlabel bits per ${graph_period} +graph_category network +graph_args --base 1000 --upper-limit 100 -l 0 +IPv4.label IPv4 bps +IPv4.min 0 +IPv4.type DERIVE +IPv4.draw AREA +IPv6.label IPv6 bps +IPv6.min 0 +IPv6.type DERIVE +IPv6.draw STACK +total.label Total bps +total.min 0 +total.type DERIVE +total.draw LINE1 +EOF + + # Adapted from http://munin-monitoring.org/wiki/PercentGraphHowto + cat <<'EOF' +multigraph traffic_ipt_percent +graph_scale no +graph_title Throughput of IP protocols by percentage +graph_vlabel Percentage +graph_order IPv4=traffic_ipt.IPv4 IPv6=traffic_ipt.IPv6 total=traffic_ipt.total IPv4_percent=traffic_ipt.total IPv6_percent=traffic_ipt.total total_percent=traffic_ipt.total +graph_category network +graph_args --upper-limit 100 -l 0 -r +IPv4.label no +IPv6.label no +total.label no +total_percent.label no +IPv4.graph no +IPv6.graph no +total.graph no +total_percent.graph no +total_percent.cdef total,0.0000001,+ +IPv4_percent.label IPv4 +IPv4_percent.cdef IPv4,total_percent,/,100,* +IPv4_percent.draw AREASTACK +IPv6_percent.label IPv6 +IPv6_percent.cdef IPv6,total_percent,/,100,* +IPv6_percent.draw AREASTACK +EOF + exit 0 +fi + + +ipv4=0 +ipv6=0 + +IPv4_bytes=$(iptables -L -n -v -x | egrep '^\W+[0-9]+\W+[0-9]+\W+all\W+--\W+\*\W+\*\W+0.0.0.0/0\W+0.0.0.0/0\W+$' | while read pkts bytes rest; do echo $bytes; done) +if [ -z "$IPv4_bytes" ]; +then + echo "W: Unable to read rule from iptables, please add rules" >&2 +else + ipv4=$(echo $IPv4_bytes | sed -e 's/ / + /' | bc -l) +fi + +IPv6_bytes=$(ip6tables -L -n -v -x | egrep '^\W+[0-9]+\W+[0-9]+\W+all\W+\*\W+\*\W+::/0\W+::/0\W+$' | while read pkts bytes rest; do echo $bytes; done) +if [ -z "$IPv6_bytes" ]; +then + echo "W: Unable to read rule from ip6tables, please add rules" >&2 +else + ipv6=$(echo $IPv6_bytes | sed -e 's/ / + /' | bc -l) +fi + +echo "IPv4.value $ipv4" +echo "IPv6.value $ipv6" +echo "total.value $( echo $ipv4 + $ipv6 | bc )" + +exit 0 + From 5b56bd2973ea92b27146b24cff596b3f357b912a Mon Sep 17 00:00:00 2001 From: Kenyon Ralph Date: Sat, 2 Feb 2013 22:31:45 -0800 Subject: [PATCH 069/109] http/http_request_time: fix documentation --- plugins/http/http_request_time | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/http/http_request_time b/plugins/http/http_request_time index a5852a16..8ecd774d 100755 --- a/plugins/http/http_request_time +++ b/plugins/http/http_request_time @@ -10,7 +10,7 @@ =head1 CONFIGURATION [http_request_time] - env.url http://127.0.0.1/1 + env.url1 http://127.0.0.1/1 env.url2 http://127.0.0.1/2 env.url3 http://www.example.com env.url3_name some_munin_internal_name From 208874d74d128f856ff9ed1c1a24090d480c2898 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sun, 3 Feb 2013 21:34:36 +0100 Subject: [PATCH 070/109] if1sec_: initial version --- plugins/network/if1sec_ | 44 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100755 plugins/network/if1sec_ diff --git a/plugins/network/if1sec_ b/plugins/network/if1sec_ new file mode 100755 index 00000000..fe07f4a9 --- /dev/null +++ b/plugins/network/if1sec_ @@ -0,0 +1,44 @@ +#! /bin/sh + +pluginfull="$0" # full name of plugin +plugin="${0##*/}" # name of plugin +pidfile="$MUNIN_PLUGSTATE/munin.$plugin.pid" +cache="$MUNIN_PLUGSTATE/munin.$plugin.value" + +IFACE="${0##*/if1sec_}" # interface + +if [ "$1" = "acquire" ] +then + while sleep 1 + do + echo $( + date +%s + cat /sys/class/net/$IFACE/statistics/tx_bytes + cat /sys/class/net/$IFACE/statistics/rx_bytes + ) + done | awk "{ + print \"${IFACE}_tx.value \" \$1 \":\" \$2; + print \"${IFACE}_rx.value \" \$1 \":\" \$3; + }" >> $cache & + echo $! > $pidfile + exit 0 +fi + + +if [ "$1" = "config" ] +then + cat < ${FILE_VALUES} + +exit 0 + From 63d61bc52e0c6952277537453143940543a397df Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 4 Feb 2013 10:18:40 +0100 Subject: [PATCH 071/109] if1sec: fixes --- plugins/network/if1sec_ | 45 +++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/plugins/network/if1sec_ b/plugins/network/if1sec_ index fe07f4a9..a08cd906 100755 --- a/plugins/network/if1sec_ +++ b/plugins/network/if1sec_ @@ -7,38 +7,49 @@ cache="$MUNIN_PLUGSTATE/munin.$plugin.value" IFACE="${0##*/if1sec_}" # interface +if [ ! -r "/sys/class/net/$IFACE/statistics/tx_bytes" ] +then + echo "# Unknown Interface : $IFACE" + exit 1 +fi + if [ "$1" = "acquire" ] then - while sleep 1 - do - echo $( - date +%s - cat /sys/class/net/$IFACE/statistics/tx_bytes - cat /sys/class/net/$IFACE/statistics/rx_bytes - ) - done | awk "{ - print \"${IFACE}_tx.value \" \$1 \":\" \$2; - print \"${IFACE}_rx.value \" \$1 \":\" \$3; - }" >> $cache & + ( + while sleep 1 + do + echo $( + date +%s + cat /sys/class/net/$IFACE/statistics/tx_bytes + cat /sys/class/net/$IFACE/statistics/rx_bytes + ) + done | awk "{ + print \"${IFACE}_tx.value \" \$1 \":\" \$2; + print \"${IFACE}_rx.value \" \$1 \":\" \$3; + }" >> $cache + ) & echo $! > $pidfile - exit 0 + exit 0 fi if [ "$1" = "config" ] then - cat < ${FILE_VALUES} +cat ${cache} +> ${cache} exit 0 - From 2fd52dfb38e4a55c357784485f5e397d6f1a1eed Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 4 Feb 2013 10:52:02 +0100 Subject: [PATCH 072/109] if1sec_: adding a proper label --- plugins/network/if1sec_ | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/network/if1sec_ b/plugins/network/if1sec_ index a08cd906..992e7547 100755 --- a/plugins/network/if1sec_ +++ b/plugins/network/if1sec_ @@ -39,9 +39,12 @@ then graph_title Interface 1sec stats for ${IFACE} graph_category 1sec::network graph_data_size custom 1d, 10s for 1w, 1m for 1t, 5m for 1y +graph_vlabel Bytes update_rate 1 +${IFACE}_tx.label ${IFACE} TX bytes ${IFACE}_tx.type DERIVE ${IFACE}_tx.min 0 +${IFACE}_rx.label ${IFACE} RX bytes ${IFACE}_rx.type DERIVE ${IFACE}_rx.min 0 EOF From 7beab0e4203f2247f08c62038cc6edfa8877f1bf Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 4 Feb 2013 10:52:29 +0100 Subject: [PATCH 073/109] if1sec_: explicit flushing when appending to cache --- plugins/network/if1sec_ | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/network/if1sec_ b/plugins/network/if1sec_ index 992e7547..6e5ad6d4 100755 --- a/plugins/network/if1sec_ +++ b/plugins/network/if1sec_ @@ -26,6 +26,7 @@ then done | awk "{ print \"${IFACE}_tx.value \" \$1 \":\" \$2; print \"${IFACE}_rx.value \" \$1 \":\" \$3; + system(\"\"); }" >> $cache ) & echo $! > $pidfile From e3744a09f9e5fd530335d99f273fd0af5f20c352 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 4 Feb 2013 14:30:11 +0100 Subject: [PATCH 074/109] multicpu1sec: add a flush to awk --- plugins/system/multicpu1sec/multicpu1sec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/system/multicpu1sec/multicpu1sec b/plugins/system/multicpu1sec/multicpu1sec index 92fa98cf..c98dfa2b 100644 --- a/plugins/system/multicpu1sec/multicpu1sec +++ b/plugins/system/multicpu1sec/multicpu1sec @@ -26,7 +26,7 @@ run_watchdog() { # should also trap kill and term signals run_acquire() { echo "$$" > $pidfile mpstat -P ALL $interval | - awk -v cpus=$cpus '$2>=0&&$2<10 {print $2, systime(), (100-$11)/cpus}' >> $cache + awk -v cpus=$cpus '$2>=0&&$2<10 {print $2, systime(), (100-$11)/cpus; system("");}' >> $cache rm -f $pidfile $cache } From 5090a771c87b72dd35e8f49e46a81a34d33e906f Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 4 Feb 2013 15:20:50 +0100 Subject: [PATCH 075/109] multicpu1sec: use LANG=C to avoid S_TIME_FORMAT issues --- plugins/system/multicpu1sec/multicpu1sec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/system/multicpu1sec/multicpu1sec b/plugins/system/multicpu1sec/multicpu1sec index c98dfa2b..888e7e99 100644 --- a/plugins/system/multicpu1sec/multicpu1sec +++ b/plugins/system/multicpu1sec/multicpu1sec @@ -25,7 +25,7 @@ run_watchdog() { # should also trap kill and term signals run_acquire() { echo "$$" > $pidfile - mpstat -P ALL $interval | + LANG=C mpstat -P ALL $interval | awk -v cpus=$cpus '$2>=0&&$2<10 {print $2, systime(), (100-$11)/cpus; system("");}' >> $cache rm -f $pidfile $cache } From 729c61237a0b35e2065b0315bc78f9f0524683ae Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Mon, 4 Feb 2013 15:21:25 +0100 Subject: [PATCH 076/109] multicpu1sec: enable up to 99 CPUs --- plugins/system/multicpu1sec/multicpu1sec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/system/multicpu1sec/multicpu1sec b/plugins/system/multicpu1sec/multicpu1sec index 888e7e99..4d69f137 100644 --- a/plugins/system/multicpu1sec/multicpu1sec +++ b/plugins/system/multicpu1sec/multicpu1sec @@ -26,7 +26,7 @@ run_watchdog() { # should also trap kill and term signals run_acquire() { echo "$$" > $pidfile LANG=C mpstat -P ALL $interval | - awk -v cpus=$cpus '$2>=0&&$2<10 {print $2, systime(), (100-$11)/cpus; system("");}' >> $cache + awk -v cpus=$cpus '$2>=0&&$2<99 {print $2, systime(), (100-$11)/cpus; system("");}' >> $cache rm -f $pidfile $cache } From 0b0f98c44cdc51459d986c9f1610d3fd5054be0d Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Mon, 4 Feb 2013 21:50:26 +0100 Subject: [PATCH 077/109] adapt if_err_.c suggest to the mainline plugin Previously it would only detect specific interfaces. Now detecting bios named devices should work. --- tools/munin-plugins-busybox/if_err_.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tools/munin-plugins-busybox/if_err_.c b/tools/munin-plugins-busybox/if_err_.c index 9bb62570..f4fe8174 100644 --- a/tools/munin-plugins-busybox/if_err_.c +++ b/tools/munin-plugins-busybox/if_err_.c @@ -37,20 +37,18 @@ int if_err_(int argc, char **argv) { for(s=buff;*s == ' ';++s) ; i = 0; - if(!strncmp(s, "eth", 3)) - i = 3; - else if(!strncmp(s, "wlan", 4)) - i = 4; - else if(!strncmp(s, "ath", 3)) - i = 3; - else if(!strncmp(s, "ra", 2)) - i = 2; - if(i == 0) + if(!strncmp(s, "lo:", 3)) continue; - while(isdigit(s[i])) + if(!strncmp(s, "sit", 3)) { + for(i=3; isdigit(s[i]); ++i) + ; + if(s[i] == ':') + continue; + } + while(s[i] != ':' && s[i] != '\0') ++i; if(s[i] != ':') - continue; + continue; /* a header line */ s[i] = '\0'; puts(s); } From e71641b88f8e6221173c84e36205c2ef08150657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20H=C3=A4hnel?= Date: Mon, 21 Jan 2013 15:27:26 +0100 Subject: [PATCH 078/109] Update plugins/wowza/wowza-media-server -Fix Graph wowza_app_listeners -Compatibility to python 2.6 --- plugins/wowza/wowza-media-server | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/wowza/wowza-media-server b/plugins/wowza/wowza-media-server index 81fee466..d732687d 100755 --- a/plugins/wowza/wowza-media-server +++ b/plugins/wowza/wowza-media-server @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/python """ Plugin to monitor Wowza streaming servers. @@ -83,14 +83,14 @@ tree.parse(f) f.close() vhosts = [] -for vh in tree.iter("VHost"): +for vh in tree.findall("VHost"): if vh.find("Name").text not in vhost_exclude: applications = [] - for app in vh.iter("Application"): + for app in vh.findall("Application"): if app.find("Name").text not in app_exclude: if app.find("Status").text == "loaded": clients = [] - for client in app.iter("Client"): + for client in app.findall("Client"): if client.find("IpAddress").text not in client_exclude: clients.append({"ClientId": client.find("ClientId").text, "FlashVersion": client.find("FlashVersion").text, @@ -289,7 +289,7 @@ elif plugin_name == "wowza_vhost_uptime": elif plugin_name == "wowza_app_listeners": for vh in vhosts: for app in vh["Applications"]: - print (vh["Name"].strip("/").replace(".","_").replace("-","_"),"_",app["Name"].strip("/").replace(".","_").replace("-","_"),".value ",app["TimeRunning"],sep='') + print (vh["Name"].strip("/").replace(".","_").replace("-","_"),"_",app["Name"].strip("/").replace(".","_").replace("-","_"),".value ",app["ConnectionsCurrent"],sep='') elif plugin_name == "wowza_app_duration": alldurations = {} From df82b943ad1dbcca9bd29671ba09371799f398c0 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Tue, 5 Feb 2013 11:31:37 +0100 Subject: [PATCH 079/109] make main.c grepable easier grepable --- tools/munin-plugins-busybox/main.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index 6dc67251..0a6c5a34 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -34,49 +34,49 @@ int main(int argc, char **argv) { progname = basename(argv[0]); switch(*progname) { case 'c': - if(!strcmp(progname+1, "pu")) + if(!strcmp(progname+1, "cpu"+1)) return cpu(argc, argv); break; case 'e': - if(!strcmp(progname+1, "ntropy")) + if(!strcmp(progname+1, "entropy"+1)) return entropy(argc, argv); break; case 'f': - if(!strcmp(progname+1, "orks")) + if(!strcmp(progname+1, "forks"+1)) return forks(argc, argv); - if(!strcmp(progname+1, "w_packets")) + if(!strcmp(progname+1, "fw_packets"+1)) return fw_packets(argc, argv); break; case 'i': - if(!strcmp(progname+1, "nterrupts")) + if(!strcmp(progname+1, "interrupts"+1)) return interrupts(argc, argv); - if(!strncmp(progname+1, "f_err_", 6)) + if(!strncmp(progname+1, "if_err_"+1, 6)) return if_err_(argc, argv); break; case 'l': - if(!strcmp(progname+1, "oad")) + if(!strcmp(progname+1, "load"+1)) return load(argc, argv); break; case 'm': - if(!strcmp(progname+1, "unin-plugins-busybox")) + if(!strcmp(progname+1, "munin-plugins-busybox"+1)) return busybox(argc, argv); break; case 'o': - if(!strcmp(progname+1, "pen_files")) + if(!strcmp(progname+1, "open_files"+1)) return open_files(argc, argv); - if(!strcmp(progname+1, "pen_inodes")) + if(!strcmp(progname+1, "open_inodes"+1)) return open_inodes(argc, argv); break; case 'p': - if(!strcmp(progname+1, "rocesses")) + if(!strcmp(progname+1, "processes"+1)) return processes(argc, argv); break; case 's': - if(!strcmp(progname+1, "wap")) + if(!strcmp(progname+1, "swap"+1)) return swap(argc, argv); break; case 'u': - if(!strcmp(progname+1, "ptime")) + if(!strcmp(progname+1, "uptime"+1)) return uptime(argc, argv); break; } From bb7bf0bcd7930c89dcd1af60ff8ed767c1db425b Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Tue, 5 Feb 2013 12:38:12 +0100 Subject: [PATCH 080/109] refactor code Added common functions autoconf_check_readable and fail. Added some TODOs for later completion. Updated messages from upstream plugins. --- tools/munin-plugins-busybox/common.c | 20 +++++++++---- tools/munin-plugins-busybox/common.h | 3 +- tools/munin-plugins-busybox/cpu.c | 31 +++++++------------ tools/munin-plugins-busybox/entropy.c | 12 ++++---- tools/munin-plugins-busybox/forks.c | 17 ++++------- tools/munin-plugins-busybox/fw_packets.c | 17 ++++------- tools/munin-plugins-busybox/if_err_.c | 23 +++++---------- tools/munin-plugins-busybox/interrupts.c | 16 ++++------ tools/munin-plugins-busybox/load.c | 11 ++++--- tools/munin-plugins-busybox/main.c | 16 ++++------ tools/munin-plugins-busybox/open_files.c | 29 +++++++----------- tools/munin-plugins-busybox/open_inodes.c | 17 ++++------- tools/munin-plugins-busybox/processes.c | 6 ++-- tools/munin-plugins-busybox/swap.c | 36 +++++++---------------- tools/munin-plugins-busybox/uptime.c | 9 ++---- 15 files changed, 97 insertions(+), 166 deletions(-) diff --git a/tools/munin-plugins-busybox/common.c b/tools/munin-plugins-busybox/common.c index 3527ef78..83457c17 100644 --- a/tools/munin-plugins-busybox/common.c +++ b/tools/munin-plugins-busybox/common.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -10,12 +11,13 @@ int writeyes(void) { return 0; } -int writeno(const char *s) { - if(s) - printf("no (%s)\n", s); - else - puts("no"); - return 1; +int autoconf_check_readable(const char *path) { + if(0 == access(path, R_OK)) + return writeyes(); + else { + printf("no (%s is not readable, errno=%d)\n", path, errno); + return 1; + } } int getenvint(const char *name, int defvalue) { @@ -64,3 +66,9 @@ void print_warncrit(const char *name) { print_warning(name); print_critical(name); } + +int fail(const char *message) { + fputs(message, stderr); + fputc('\n', stderr); + return 1; +} diff --git a/tools/munin-plugins-busybox/common.h b/tools/munin-plugins-busybox/common.h index ac4d08c8..c35cac85 100644 --- a/tools/munin-plugins-busybox/common.h +++ b/tools/munin-plugins-busybox/common.h @@ -4,11 +4,12 @@ #define PROC_STAT "/proc/stat" int writeyes(void); -int writeno(const char *); +int autoconf_check_readable(const char *); int getenvint(const char *, int); const char *getenv_composed(const char *, const char *); void print_warning(const char *); void print_critical(const char *); void print_warncrit(const char *); +int fail(const char *); #endif diff --git a/tools/munin-plugins-busybox/cpu.c b/tools/munin-plugins-busybox/cpu.c index 2c68f889..0cfa1d45 100644 --- a/tools/munin-plugins-busybox/cpu.c +++ b/tools/munin-plugins-busybox/cpu.c @@ -9,6 +9,8 @@ #define SYSCRITICAL 50 #define USRWARNING 80 +/* TODO: port support for env.foo_warning and env.foo_critical from mainline plugin */ + int cpu(int argc, char **argv) { FILE *f; char buff[256], *s; @@ -19,10 +21,8 @@ int cpu(int argc, char **argv) { if(s && !strcmp(s, "yes")) scaleto100=1; - if(!(f=fopen(PROC_STAT, "r"))) { - fputs("cannot open " PROC_STAT "\n", stderr); - return 1; - } + if(!(f=fopen(PROC_STAT, "r"))) + return fail("cannot open " PROC_STAT); while(fgets(buff, 256, f)) { if(!strncmp(buff, "cpu", 3)) { if(isdigit(buff[3])) @@ -36,10 +36,8 @@ int cpu(int argc, char **argv) { } fclose(f); - if(ncpu < 1 || extinfo < 4) { - fputs("cannot parse " PROC_STAT "\n", stderr); - return 1; - } + if(ncpu < 1 || extinfo < 4) + return fail("cannot parse " PROC_STAT); puts("graph_title CPU usage"); if(extinfo >= 7) @@ -133,17 +131,11 @@ int cpu(int argc, char **argv) { } return 0; } - if(!strcmp(argv[1], "autoconf")) { - if(0 == access(PROC_STAT, R_OK)) - return writeyes(); - else - return writeno(PROC_STAT " not readable"); - } - } - if(!(f=fopen(PROC_STAT, "r"))) { - fputs("cannot open " PROC_STAT "\n", stderr); - return 1; + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(PROC_STAT); } + if(!(f=fopen(PROC_STAT, "r"))) + return fail("cannot open " PROC_STAT); while(fgets(buff, 256, f)) { hz = getenvint("HZ", 100); if(!strncmp(buff, "cpu ", 4)) { @@ -179,6 +171,5 @@ int cpu(int argc, char **argv) { } } fclose(f); - fputs("no cpu line found in " PROC_STAT "\n", stderr); - return 1; + return fail("no cpu line found in " PROC_STAT); } diff --git a/tools/munin-plugins-busybox/entropy.c b/tools/munin-plugins-busybox/entropy.c index 57206d2a..2f7d998f 100644 --- a/tools/munin-plugins-busybox/entropy.c +++ b/tools/munin-plugins-busybox/entropy.c @@ -1,5 +1,6 @@ #include #include +#include #include "common.h" #define ENTROPY_AVAIL "/proc/sys/kernel/random/entropy_avail" @@ -21,16 +22,13 @@ int entropy(int argc, char **argv) { return 0; } if(!strcmp(argv[1], "autoconf")) - return writeyes(); - } - if(!(f=fopen(ENTROPY_AVAIL, "r"))) { - fputs("cannot open " ENTROPY_AVAIL "\n", stderr); - return 1; + return autoconf_check_readable(ENTROPY_AVAIL); } + if(!(f=fopen(ENTROPY_AVAIL, "r"))) + return fail("cannot open " ENTROPY_AVAIL); if(1 != fscanf(f, "%d", &entropy)) { - fputs("cannot read from " ENTROPY_AVAIL "\n", stderr); fclose(f); - return 1; + return fail("cannot read from " ENTROPY_AVAIL); } fclose(f); printf("entropy.value %d\n", entropy); diff --git a/tools/munin-plugins-busybox/forks.c b/tools/munin-plugins-busybox/forks.c index eac1ccc4..fbbc5e59 100644 --- a/tools/munin-plugins-busybox/forks.c +++ b/tools/munin-plugins-busybox/forks.c @@ -21,17 +21,11 @@ int forks(int argc, char **argv) { print_warncrit("forks"); return 0; } - if(!strcmp(argv[1], "autoconf")) { - if(0 == access(PROC_STAT, R_OK)) - return writeyes(); - else - return writeno(PROC_STAT " not readable"); - } - } - if(!(f=fopen(PROC_STAT, "r"))) { - fputs("cannot open " PROC_STAT "\n", stderr); - return 1; + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(PROC_STAT); } + if(!(f=fopen(PROC_STAT, "r"))) + return fail("cannot open " PROC_STAT); while(fgets(buff, 256, f)) { if(!strncmp(buff, "processes ", 10)) { fclose(f); @@ -40,6 +34,5 @@ int forks(int argc, char **argv) { } } fclose(f); - fputs("no processes line found in " PROC_STAT "\n", stderr); - return 1; + return fail("no processes line found in " PROC_STAT); } diff --git a/tools/munin-plugins-busybox/fw_packets.c b/tools/munin-plugins-busybox/fw_packets.c index 8e94fdea..1bb9f0f0 100644 --- a/tools/munin-plugins-busybox/fw_packets.c +++ b/tools/munin-plugins-busybox/fw_packets.c @@ -25,17 +25,11 @@ int fw_packets(int argc, char **argv) { "forwarded.min 0"); return 0; } - if(!strcmp(argv[1], "autoconf")) { - if(0 == access(PROC_NET_SNMP, R_OK)) - return writeyes(); - else - return writeno(PROC_NET_SNMP " not readable"); - } - } - if(!(f=fopen(PROC_NET_SNMP, "r"))) { - fputs("cannot open " PROC_NET_SNMP "\n", stderr); - return 1; + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(PROC_NET_SNMP); } + if(!(f=fopen(PROC_NET_SNMP, "r"))) + return fail("cannot open " PROC_NET_SNMP); while(fgets(buff, 1024, f)) { if(!strncmp(buff, "Ip: ", 4) && isdigit(buff[4])) { fclose(f); @@ -57,6 +51,5 @@ int fw_packets(int argc, char **argv) { } } fclose(f); - fputs("no ip line found in " PROC_NET_SNMP "\n", stderr); - return 1; + return fail("no ip line found in " PROC_NET_SNMP); } diff --git a/tools/munin-plugins-busybox/if_err_.c b/tools/munin-plugins-busybox/if_err_.c index f4fe8174..4ebfe961 100644 --- a/tools/munin-plugins-busybox/if_err_.c +++ b/tools/munin-plugins-busybox/if_err_.c @@ -9,27 +9,20 @@ int if_err_(int argc, char **argv) { char *interface; + size_t interface_len; FILE *f; char buff[256], *s; int i; interface = basename(argv[0]); - if(strncmp(interface, "if_err_", 7) != 0) { - fputs("if_err_ invoked with invalid basename\n", stderr); - return 1; - } + if(strncmp(interface, "if_err_", 7) != 0) + return fail("if_err_ invoked with invalid basename"); interface += 7; + interface_len = strlen(interface); if(argc > 1) { - if(!strcmp(argv[1], "autoconf")) { - if(access(PROC_NET_DEV, R_OK) == 0) { - puts("yes"); - return 0; - } else { - puts("no (/proc/net/dev not found)"); - return 1; - } - } + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(PROC_NET_DEV); if(!strcmp(argv[1], "suggest")) { if(NULL == (f = fopen(PROC_NET_DEV, "r"))) return 1; @@ -83,9 +76,9 @@ int if_err_(int argc, char **argv) { while(fgets(buff, 256, f)) { for(s=buff;*s == ' ';++s) ; - if(0 != strncmp(s, interface, strlen(interface))) + if(0 != strncmp(s, interface, interface_len)) continue; - s += strlen(interface); + s += interface_len; if(*s != ':') continue; ++s; diff --git a/tools/munin-plugins-busybox/interrupts.c b/tools/munin-plugins-busybox/interrupts.c index d38e05f2..7fcc6094 100644 --- a/tools/munin-plugins-busybox/interrupts.c +++ b/tools/munin-plugins-busybox/interrupts.c @@ -8,7 +8,7 @@ int interrupts(int argc, char **argv) { char buff[256]; if(argc > 1) { if(!strcmp(argv[1], "config")) { - puts("graph_title Interrupts & context switches\n" + puts("graph_title Interrupts and context switches\n" "graph_args --base 1000 -l 0\n" "graph_vlabel interrupts & ctx switches / ${graph_period}\n" "graph_category system\n" @@ -27,17 +27,11 @@ int interrupts(int argc, char **argv) { print_warncrit("ctx"); return 0; } - if(!strcmp(argv[1], "autoconf")) { - if(0 == access(PROC_STAT, R_OK)) - return writeyes(); - else - return writeno(PROC_STAT " not readable"); - } - } - if(!(f=fopen(PROC_STAT, "r"))) { - fputs("cannot open " PROC_STAT "\n", stderr); - return 1; + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(PROC_STAT); } + if(!(f=fopen(PROC_STAT, "r"))) + return fail("cannot open " PROC_STAT); while(fgets(buff, 256, f)) { if(!strncmp(buff, "intr ", 5)) { buff[5 + strcspn(buff + 5, " \t\n")] = '\0'; diff --git a/tools/munin-plugins-busybox/load.c b/tools/munin-plugins-busybox/load.c index 8161890f..3b608ca2 100644 --- a/tools/munin-plugins-busybox/load.c +++ b/tools/munin-plugins-busybox/load.c @@ -17,19 +17,18 @@ int load(int argc, char **argv) { "graph_category system\n" "load.label load"); print_warncrit("load"); + puts("graph_info The load average of the machine describes how many processes are in the run-queue (scheduled to run \"immediately\").\n" + "load.info 5 minute load average"); return 0; } if(!strcmp(argv[1], "autoconf")) return writeyes(); } - if(!(f=fopen(PROC_LOADAVG, "r"))) { - fputs("cannot open " PROC_LOADAVG "\n", stderr); - return 1; - } + if(!(f=fopen(PROC_LOADAVG, "r"))) + return fail("cannot open " PROC_LOADAVG); if(1 != fscanf(f, "%*f %f", &val)) { - fputs("cannot read from " PROC_LOADAVG "\n", stderr); fclose(f); - return 1; + return fail("cannot read from " PROC_LOADAVG); } fclose(f); printf("load.value %.2f\n", val); diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index 6dc67251..5e5545bc 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -1,6 +1,7 @@ #include #include #include +#include "common.h" int cpu(int argc, char **argv); int entropy(int argc, char **argv); @@ -16,14 +17,10 @@ int swap(int argc, char **argv); int uptime(int argc, char **argv); int busybox(int argc, char **argv) { - if(argc < 2) { - fprintf(stderr, "missing parameter\n"); - return 1; - } - if(0 != strcmp(argv[1], "listplugins")) { - fprintf(stderr, "unknown parameter\n"); - return 1; - } + if(argc < 2) + return fail("missing parameter"); + if(0 != strcmp(argv[1], "listplugins")) + return fail("unknown parameter"); puts("cpu\nentropy\nforks\nfw_packets\ninterrupts\nload\n" "open_files\nopen_inodes\nprocesses\nswap\nuptime"); return 0; @@ -80,6 +77,5 @@ int main(int argc, char **argv) { return uptime(argc, argv); break; } - fprintf(stderr, "unknown basename\n"); - return 1; + return fail("unknown basename"); } diff --git a/tools/munin-plugins-busybox/open_files.c b/tools/munin-plugins-busybox/open_files.c index 9eb5c3d7..f83a9f6c 100644 --- a/tools/munin-plugins-busybox/open_files.c +++ b/tools/munin-plugins-busybox/open_files.c @@ -5,20 +5,18 @@ #define FS_FILE_NR "/proc/sys/fs/file-nr" +/* TODO: support env.warning and friends after the upstream plugin is fixed */ + int open_files(int argc, char **argv) { FILE *f; int alloc, freeh, avail; if(argc > 1) { if(!strcmp(argv[1], "config")) { - if(!(f=fopen(FS_FILE_NR, "r"))) { - fprintf(stderr, "cannot open " FS_FILE_NR "\n"); - return 1; - } + if(!(f=fopen(FS_FILE_NR, "r"))) + return fail("cannot open " FS_FILE_NR); if(1 != fscanf(f, "%*d %*d %d", &avail)) { fclose(f); - fprintf(stderr, "cannot read from " FS_FILE_NR - "\n"); - return 1; + return fail("cannot read from " FS_FILE_NR); } fclose(f); puts("graph_title File table usage\n" @@ -36,21 +34,14 @@ int open_files(int argc, char **argv) { (int)(avail*0.92), (int)(avail*0.98)); return 0; } - if(!strcmp(argv[1], "autoconf")) { - if(0 == access(FS_FILE_NR, R_OK)) - return writeyes(); - else - return writeno(FS_FILE_NR " not readable"); - } - } - if(!(f=fopen(FS_FILE_NR, "r"))) { - fputs("cannot open " FS_FILE_NR "\n", stderr); - return 1; + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(FS_FILE_NR); } + if(!(f=fopen(FS_FILE_NR, "r"))) + return fail("cannot open " FS_FILE_NR); if(3 != fscanf(f, "%d %d %d", &alloc, &freeh, &avail)) { fclose(f); - fputs("cannot read from " FS_FILE_NR "\n", stderr); - return 1; + return fail("cannot read from " FS_FILE_NR); } fclose(f); printf("used.value %d\nmax.value %d\n", alloc-freeh, avail); diff --git a/tools/munin-plugins-busybox/open_inodes.c b/tools/munin-plugins-busybox/open_inodes.c index a8db64f6..1c33e4de 100644 --- a/tools/munin-plugins-busybox/open_inodes.c +++ b/tools/munin-plugins-busybox/open_inodes.c @@ -23,21 +23,14 @@ int open_inodes(int argc, char **argv) { print_warncrit("max"); return 0; } - if(!strcmp(argv[1], "autoconf")) { - if(0 == access(FS_INODE_NR, R_OK)) - return writeyes(); - else - return writeno(FS_INODE_NR " not readable"); - } - } - if(!(f=fopen(FS_INODE_NR, "r"))) { - fputs("cannot open " FS_INODE_NR "\n", stderr); - return 1; + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(FS_INODE_NR); } + if(!(f=fopen(FS_INODE_NR, "r"))) + return fail("cannot open " FS_INODE_NR); if(2 != fscanf(f, "%d %d", &nr, &freen)) { fclose(f); - fputs("cannot read from " FS_INODE_NR "\n", stderr); - return 1; + return fail("cannot read from " FS_INODE_NR); } fclose(f); printf("used.value %d\nmax.value %d\n", nr-freen, nr); diff --git a/tools/munin-plugins-busybox/processes.c b/tools/munin-plugins-busybox/processes.c index b5227686..5f085f54 100644 --- a/tools/munin-plugins-busybox/processes.c +++ b/tools/munin-plugins-busybox/processes.c @@ -25,10 +25,8 @@ int processes(int argc, char **argv) { if(!strcmp(argv[1], "autoconf")) return writeyes(); } - if(!(d = opendir("/proc"))) { - fputs("cannot open /proc\n", stderr); - return 1; - } + if(!(d = opendir("/proc"))) + return fail("cannot open /proc"); while((e = readdir(d))) { for(s=e->d_name;*s;++s) if(!isdigit(*s)) diff --git a/tools/munin-plugins-busybox/swap.c b/tools/munin-plugins-busybox/swap.c index a1b67234..2c46fd49 100644 --- a/tools/munin-plugins-busybox/swap.c +++ b/tools/munin-plugins-busybox/swap.c @@ -27,19 +27,13 @@ int swap(int argc, char **argv) { print_warncrit("swap_out"); return 0; } - if(!strcmp(argv[1], "autoconf")) { - if(0 == access(PROC_STAT, R_OK)) - return writeyes(); - else - return writeno(PROC_STAT " not readable"); - } + if(!strcmp(argv[1], "autoconf")) + return autoconf_check_readable(PROC_STAT); } if(!access("/proc/vmstat", F_OK)) { in=out=0; - if(!(f=fopen("/proc/vmstat", "r"))) { - fputs("cannot open /proc/vmstat\n", stderr); - return 1; - } + if(!(f=fopen("/proc/vmstat", "r"))) + return fail("cannot open /proc/vmstat"); while(fgets(buff, 256, f)) { if(!in && !strncmp(buff, "pswpin ", 7)) { ++in; @@ -51,30 +45,22 @@ int swap(int argc, char **argv) { } } fclose(f); - if(!(in*out)) { - fputs("no usable data on /proc/vmstat\n", stderr); - return 1; - } + if(!(in*out)) + return fail("no usable data on /proc/vmstat"); return 0; } else { - if(!(f=fopen(PROC_STAT, "r"))) { - fputs("cannot open " PROC_STAT "\n", stderr); - return 1; - } + if(!(f=fopen(PROC_STAT, "r"))) + return fail("cannot open " PROC_STAT); while(fgets(buff, 256, f)) { if(!strncmp(buff, "swap ", 5)) { fclose(f); - if(2 != sscanf(buff+5, "%d %d", &in, &out)) { - fputs("bad data on " PROC_STAT "\n", - stderr); - return 1; - } + if(2 != sscanf(buff+5, "%d %d", &in, &out)) + return fail("bad data on " PROC_STAT); printf("swap_in.value %d\nswap_out.value %d\n", in, out); return 0; } } fclose(f); - fputs("no swap line found in " PROC_STAT "\n", stderr); - return 1; + return fail("no swap line found in " PROC_STAT); } } diff --git a/tools/munin-plugins-busybox/uptime.c b/tools/munin-plugins-busybox/uptime.c index bb3e02cd..6270acb6 100644 --- a/tools/munin-plugins-busybox/uptime.c +++ b/tools/munin-plugins-busybox/uptime.c @@ -18,14 +18,11 @@ int uptime(int argc, char **argv) { if(!strcmp(argv[1], "autoconf")) return writeyes(); } - if(!(f=fopen("/proc/uptime", "r"))) { - fputs("cannot open /proc/uptime\n", stderr); - return 1; - } + if(!(f=fopen("/proc/uptime", "r"))) + return fail("cannot open /proc/uptime"); if(1 != fscanf(f, "%f", &uptime)) { - fputs("cannot read from /proc/uptime\n", stderr); fclose(f); - return 1; + return fail("cannot read from /proc/uptime"); } fclose(f); printf("uptime.value %.2f\n", uptime/86400); From e2faabaff686a55cc822c3741d33ab440e6e7b63 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Tue, 5 Feb 2013 12:40:56 +0100 Subject: [PATCH 081/109] fix resource leak in if_err_.c --- tools/munin-plugins-busybox/if_err_.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/munin-plugins-busybox/if_err_.c b/tools/munin-plugins-busybox/if_err_.c index 4ebfe961..8858a4a5 100644 --- a/tools/munin-plugins-busybox/if_err_.c +++ b/tools/munin-plugins-busybox/if_err_.c @@ -113,5 +113,6 @@ int if_err_(int argc, char **argv) { fwrite(s, 1, i, stdout); putchar('\n'); } + fclose(f); return 0; } From 05a642549de5f913819fba998be2c6e63b1774ad Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Tue, 5 Feb 2013 12:50:13 +0100 Subject: [PATCH 082/109] autoconf should exit with 0 when writing no --- tools/munin-plugins-busybox/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-plugins-busybox/common.c b/tools/munin-plugins-busybox/common.c index 83457c17..03638b10 100644 --- a/tools/munin-plugins-busybox/common.c +++ b/tools/munin-plugins-busybox/common.c @@ -16,7 +16,7 @@ int autoconf_check_readable(const char *path) { return writeyes(); else { printf("no (%s is not readable, errno=%d)\n", path, errno); - return 1; + return 0; } } From 4337b550a01e9f18a2470c30fc96627528de7bef Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Tue, 5 Feb 2013 13:12:43 +0100 Subject: [PATCH 083/109] mpb: add threads.c plugin --- tools/munin-plugins-busybox/Makefile | 5 +- tools/munin-plugins-busybox/main.c | 5 ++ tools/munin-plugins-busybox/threads.c | 70 +++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 tools/munin-plugins-busybox/threads.c diff --git a/tools/munin-plugins-busybox/Makefile b/tools/munin-plugins-busybox/Makefile index fe465f64..74de3046 100644 --- a/tools/munin-plugins-busybox/Makefile +++ b/tools/munin-plugins-busybox/Makefile @@ -1,9 +1,10 @@ CC=gcc CFLAGS=-W -Wall -pedantic -Wextra -g -O2 OBJS=main.o common.o cpu.o entropy.o forks.o fw_packets.o interrupts.o \ - if_err_.o load.o open_files.o open_inodes.o processes.o swap.o uptime.o + if_err_.o load.o open_files.o open_inodes.o processes.o swap.o threads.o \ + uptime.o LINKS=cpu entropy forks fw_packets interrupts if_err_eth0 load open_files \ - open_inodes processes swap uptime + open_inodes processes swap threads uptime %.o:%.c ${CC} ${CFLAGS} -c $< -o $@ diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index 5e5545bc..535b8a9d 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -14,6 +14,7 @@ int open_files(int argc, char **argv); int open_inodes(int argc, char **argv); int processes(int argc, char **argv); int swap(int argc, char **argv); +int threads(int argc, char **argv); int uptime(int argc, char **argv); int busybox(int argc, char **argv) { @@ -72,6 +73,10 @@ int main(int argc, char **argv) { if(!strcmp(progname+1, "wap")) return swap(argc, argv); break; + case 't': + if(!strcmp(progname+1, "hreads")) + return threads(argc, argv); + break; case 'u': if(!strcmp(progname+1, "ptime")) return uptime(argc, argv); diff --git a/tools/munin-plugins-busybox/threads.c b/tools/munin-plugins-busybox/threads.c new file mode 100644 index 00000000..c3389e60 --- /dev/null +++ b/tools/munin-plugins-busybox/threads.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include "common.h" + +int threads(int argc, char **argv) { + FILE *f; + char buff[256]; + const char *s; + int i, sum; + DIR *d; + struct dirent *e; + + if(argc > 1) { + if(!strcmp(argv[1], "autoconf")) { + i = getpid(); + sprintf(buff, "/proc/%d/status", i); + if(NULL == (f = fopen(buff, "r"))) + return fail("failed to open /proc/$$/status"); + while(fgets(buff, 256, f)) + if(!strncmp(buff, "Threads:", 8)) { + fclose(f); + return writeyes(); + } + fclose(f); + puts("no"); + return 0; + } + if(!strcmp(argv[1], "config")) { + puts("graph_title Number of threads\n" + "graph_vlabel number of threads\n" + "graph_category processes\n" + "graph_info This graph shows the number of threads.\n" + "threads.label threads\n" + "threads.info The current number of threads."); + return 0; + } + } + if(NULL == (d = opendir("/proc"))) + return fail("cannot open /proc"); + sum = 0; + while((e = readdir(d))) { + for(s=e->d_name;*s;++s) + if(!isdigit(*s)) + break; + if(*s) /* non-digit found */ + continue; + snprintf(buff, 256, "/proc/%s/status", e->d_name); + if(!(f = fopen(buff, "r"))) + continue; /* process has vanished */ + while(fgets(buff, 256, f)) { + if(strncmp(buff, "Threads:", 8)) + continue; + if(1 != sscanf(buff+8, "%d", &i)) { + fclose(f); + closedir(d); + return fail("failed to parse " + "/proc/somepid/status"); + } + sum += i; + } + fclose(f); + } + closedir(d); + printf("threads.value %d\n", sum); + return 0; +} From c4ad7d72b7a4eb148345e520ba13e1819bee192e Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Thu, 7 Feb 2013 18:47:55 +0100 Subject: [PATCH 084/109] mpb: forgot to add threads to listplugins --- tools/munin-plugins-busybox/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index 535b8a9d..ecf2a42f 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -23,7 +23,7 @@ int busybox(int argc, char **argv) { if(0 != strcmp(argv[1], "listplugins")) return fail("unknown parameter"); puts("cpu\nentropy\nforks\nfw_packets\ninterrupts\nload\n" - "open_files\nopen_inodes\nprocesses\nswap\nuptime"); + "open_files\nopen_inodes\nprocesses\nswap\nthreads\nuptime"); return 0; } From a354c47f89e8e26167f70a690ed34c21977fb363 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Fri, 8 Feb 2013 11:20:49 +0100 Subject: [PATCH 085/109] mpb: stop advertising processes.c The upstream plugin does way more nowadays. This is no longer a drop-in replacement. --- tools/munin-plugins-busybox/main.c | 2 +- tools/munin-plugins-busybox/processes.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index ecf2a42f..a2bb650c 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -23,7 +23,7 @@ int busybox(int argc, char **argv) { if(0 != strcmp(argv[1], "listplugins")) return fail("unknown parameter"); puts("cpu\nentropy\nforks\nfw_packets\ninterrupts\nload\n" - "open_files\nopen_inodes\nprocesses\nswap\nthreads\nuptime"); + "open_files\nopen_inodes\nswap\nthreads\nuptime"); return 0; } diff --git a/tools/munin-plugins-busybox/processes.c b/tools/munin-plugins-busybox/processes.c index 5f085f54..8eb0b72e 100644 --- a/tools/munin-plugins-busybox/processes.c +++ b/tools/munin-plugins-busybox/processes.c @@ -5,6 +5,8 @@ #include #include "common.h" +/* TODO: The upstream plugin does way more nowawdays. */ + int processes(int argc, char **argv) { DIR *d; struct dirent *e; From a91cbefc8dd4b06880bbcbd60c746aeb542b0289 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Fri, 8 Feb 2013 18:08:41 +0100 Subject: [PATCH 086/109] mpb: use full arg to ease code reading --- tools/munin-plugins-busybox/main.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index 0a6c5a34..91e09567 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -34,49 +34,49 @@ int main(int argc, char **argv) { progname = basename(argv[0]); switch(*progname) { case 'c': - if(!strcmp(progname+1, "cpu"+1)) + if(!strcmp(progname, "cpu")) return cpu(argc, argv); break; case 'e': - if(!strcmp(progname+1, "entropy"+1)) + if(!strcmp(progname, "entropy")) return entropy(argc, argv); break; case 'f': - if(!strcmp(progname+1, "forks"+1)) + if(!strcmp(progname, "forks")) return forks(argc, argv); - if(!strcmp(progname+1, "fw_packets"+1)) + if(!strcmp(progname, "fw_packets")) return fw_packets(argc, argv); break; case 'i': - if(!strcmp(progname+1, "interrupts"+1)) + if(!strcmp(progname, "interrupts")) return interrupts(argc, argv); - if(!strncmp(progname+1, "if_err_"+1, 6)) + if(!strncmp(progname, "if_err_", 6)) return if_err_(argc, argv); break; case 'l': - if(!strcmp(progname+1, "load"+1)) + if(!strcmp(progname, "load")) return load(argc, argv); break; case 'm': - if(!strcmp(progname+1, "munin-plugins-busybox"+1)) + if(!strcmp(progname, "munin-plugins-busybox")) return busybox(argc, argv); break; case 'o': - if(!strcmp(progname+1, "open_files"+1)) + if(!strcmp(progname, "open_files")) return open_files(argc, argv); - if(!strcmp(progname+1, "open_inodes"+1)) + if(!strcmp(progname, "open_inodes")) return open_inodes(argc, argv); break; case 'p': - if(!strcmp(progname+1, "processes"+1)) + if(!strcmp(progname, "processes")) return processes(argc, argv); break; case 's': - if(!strcmp(progname+1, "swap"+1)) + if(!strcmp(progname, "swap")) return swap(argc, argv); break; case 'u': - if(!strcmp(progname+1, "uptime"+1)) + if(!strcmp(progname, "uptime")) return uptime(argc, argv); break; } From 69b46e42f6f2757cc7442c5dcd4320494fd2e957 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sat, 9 Feb 2013 11:49:42 +0100 Subject: [PATCH 087/109] add gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a01ee289 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.*.swp From e041ac213559661b430b054aad16aa1b3715cfce Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Fri, 8 Feb 2013 17:09:11 +0100 Subject: [PATCH 088/109] mnc: starting with adding a gitignore --- tools/munin-node-c/.gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tools/munin-node-c/.gitignore diff --git a/tools/munin-node-c/.gitignore b/tools/munin-node-c/.gitignore new file mode 100644 index 00000000..16edcbc0 --- /dev/null +++ b/tools/munin-node-c/.gitignore @@ -0,0 +1,3 @@ +# output files +/*.o +/munin-node-c From 52369dbed12986398a77c7ed74d965a76647893f Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Fri, 8 Feb 2013 17:36:32 +0100 Subject: [PATCH 089/109] mnc: initial add --- tools/munin-node-c/Makefile | 14 +++++++++ tools/munin-node-c/README | 28 ++++++++++++++++++ tools/munin-node-c/main.c | 58 +++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 tools/munin-node-c/Makefile create mode 100644 tools/munin-node-c/README create mode 100644 tools/munin-node-c/main.c diff --git a/tools/munin-node-c/Makefile b/tools/munin-node-c/Makefile new file mode 100644 index 00000000..bec42767 --- /dev/null +++ b/tools/munin-node-c/Makefile @@ -0,0 +1,14 @@ +CC=gcc +CFLAGS=-W -Wall -pedantic -Wextra -g -O2 +OBJS=main.o +LINKS= + +%.o: %.c + ${CC} ${CFLAGS} -c $< -o $@ +all: munin-node-c + +munin-node-c: ${OBJS} + ${CC} ${CFLAGS} $^ -o $@ +clean: + rm -f munin-node-c ${OBJS} ${LINKS} +.PHONY: all clean diff --git a/tools/munin-node-c/README b/tools/munin-node-c/README new file mode 100644 index 00000000..67c1544f --- /dev/null +++ b/tools/munin-node-c/README @@ -0,0 +1,28 @@ +This is a rewrite of munin node in C. + +Pro: +---- + +The purpose is multiple: + + * reducing resource usage for embedded plateforms, specially when paired + with the C rewrite of the core plugins. + + * no need for Perl + + * Everything runs from inetd. + +Cons: +----- + + * You lose flexibility + + It is compiled code, so you have to create binaries. Even one for each + architecture. + + * Not all the features are implemented + + - root uid is not supported. All plugins are run with a single user, usually nobody. + - no socket is opened. Everything runs from inetd. + +GPLv2 - (C) 2013 Steve SCHNEPP diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c new file mode 100644 index 00000000..e173ee59 --- /dev/null +++ b/tools/munin-node-c/main.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include + + +char VERSION[] = "1.0.0"; + +int verbose; + +char* host = ""; +char* plugin_dir = "plugins"; +char* spoolfetch_dir = ""; + +int main(int argc, char *argv[]) { + + int optch; + extern int opterr; + int optarg_len; + + char format[] = "vd:h:s:"; + + opterr = 1; + + while ((optch = getopt(argc, argv, format)) != -1) + switch (optch) { + case 'v': + verbose ++; + break; + case 'd': + optarg_len = strlen(optarg); + plugin_dir = (char *) malloc(optarg_len + 1); + strcpy(plugin_dir, optarg); + break; + case 'h': + optarg_len = strlen(optarg); + host = (char *) malloc(optarg_len + 1); + strcpy(host, optarg); + break; + case 's': + optarg_len = strlen(optarg); + spoolfetch_dir = (char *) malloc(optarg_len + 1); + strcpy(spoolfetch_dir, optarg); + break; + } + + /* get default hostname if not precised */ + if (! strlen(host)) { + host = (char *) malloc(HOST_NAME_MAX + 1); + gethostname(host, HOST_NAME_MAX); + } + + printf("verbose: %d, host: %s, plugin_dir: %s, spoolfetch_dir: %s\n", verbose, host, plugin_dir, spoolfetch_dir); + + + return 0; +} From acea10b2030e6738eca947a83fc1f1bb4d183042 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Fri, 8 Feb 2013 21:00:58 +0100 Subject: [PATCH 090/109] mnc: initial arg handling --- tools/munin-node-c/main.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index e173ee59..ad54a8f4 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -21,6 +21,8 @@ int main(int argc, char *argv[]) { char format[] = "vd:h:s:"; + char line[LINE_MAX]; + opterr = 1; while ((optch = getopt(argc, argv, format)) != -1) @@ -51,8 +53,30 @@ int main(int argc, char *argv[]) { gethostname(host, HOST_NAME_MAX); } - printf("verbose: %d, host: %s, plugin_dir: %s, spoolfetch_dir: %s\n", verbose, host, plugin_dir, spoolfetch_dir); + fprintf(stderr, "verbose: %d, host: %s, plugin_dir: %s, spoolfetch_dir: %s\n", verbose, host, plugin_dir, spoolfetch_dir); + printf("# munin node at %s\n", host); + while (fgets(line, LINE_MAX, stdin) != NULL) { + char* cmd; + char* arg; + + line[LINE_MAX-1] = '\0'; + + cmd = strtok(line, " \t\n"); + arg = strtok(line, " \t\n"); + + if (strlen(cmd) == 0) continue; + + if (strcmp(cmd, "version") == 0) { + } else if (strcmp(cmd, "nodes") == 0) { + } else if (strcmp(cmd, "quit") == 0) { + } else if (strcmp(cmd, "list") == 0) { + } else if (strcmp(cmd, "config") == 0) { + } else if (strcmp(cmd, "fetch") == 0) { + } else if (strcmp(cmd, "cap") == 0) { + } else if (strcmp(cmd, "spoolfetch") == 0) { + } + } return 0; } From 1d56b5845d4147e0fd432e59e8997fd7ac1b3ff0 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sat, 9 Feb 2013 12:58:16 +0100 Subject: [PATCH 091/109] mnc: suppress debug output --- tools/munin-node-c/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index ad54a8f4..22706444 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -53,8 +53,6 @@ int main(int argc, char *argv[]) { gethostname(host, HOST_NAME_MAX); } - fprintf(stderr, "verbose: %d, host: %s, plugin_dir: %s, spoolfetch_dir: %s\n", verbose, host, plugin_dir, spoolfetch_dir); - printf("# munin node at %s\n", host); while (fgets(line, LINE_MAX, stdin) != NULL) { char* cmd; From 773d5ed4cf06e389ae4cab6acae0f613345808da Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Fri, 8 Feb 2013 21:12:30 +0100 Subject: [PATCH 092/109] mnc: implem first commands --- tools/munin-node-c/main.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 22706444..201a7f48 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -63,16 +63,26 @@ int main(int argc, char *argv[]) { cmd = strtok(line, " \t\n"); arg = strtok(line, " \t\n"); - if (strlen(cmd) == 0) continue; - - if (strcmp(cmd, "version") == 0) { + if (strlen(cmd) == 0) { + } else if (strcmp(cmd, "version") == 0) { + printf("munin c node version: %s\n", VERSION); } else if (strcmp(cmd, "nodes") == 0) { + printf("%s\n", host); + printf(".\n"); } else if (strcmp(cmd, "quit") == 0) { + return(0); } else if (strcmp(cmd, "list") == 0) { } else if (strcmp(cmd, "config") == 0) { } else if (strcmp(cmd, "fetch") == 0) { } else if (strcmp(cmd, "cap") == 0) { + printf("cap "); + if (strlen(spoolfetch_dir)) { + printf("spool "); + } + printf("\n"); } else if (strcmp(cmd, "spoolfetch") == 0) { + } else { + printf("# unknown cmd: %s\n", cmd); } } From 2cdb57aec2f8dae09a36e0b5113a668a67a1b671 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Fri, 8 Feb 2013 21:24:44 +0100 Subject: [PATCH 093/109] mnc: handle empty input lines --- tools/munin-node-c/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 201a7f48..180d0678 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) { cmd = strtok(line, " \t\n"); arg = strtok(line, " \t\n"); - if (strlen(cmd) == 0) { + if (!cmd || strlen(cmd) == 0) { } else if (strcmp(cmd, "version") == 0) { printf("munin c node version: %s\n", VERSION); } else if (strcmp(cmd, "nodes") == 0) { From f3ae51d938753768a289f0e9146f9ce2a5e2511b Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sat, 9 Feb 2013 11:27:05 +0100 Subject: [PATCH 094/109] mnc: add placeholder --- tools/munin-node-c/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 180d0678..8f2c0575 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -72,6 +72,7 @@ int main(int argc, char *argv[]) { } else if (strcmp(cmd, "quit") == 0) { return(0); } else if (strcmp(cmd, "list") == 0) { + printf("# not implem yet cmd: %s\n", cmd); } else if (strcmp(cmd, "config") == 0) { } else if (strcmp(cmd, "fetch") == 0) { } else if (strcmp(cmd, "cap") == 0) { @@ -81,6 +82,7 @@ int main(int argc, char *argv[]) { } printf("\n"); } else if (strcmp(cmd, "spoolfetch") == 0) { + printf("# not implem yet cmd: %s\n", cmd); } else { printf("# unknown cmd: %s\n", cmd); } From b95b1672c6d8ee6c3d389390ef355c46fb2ff3a0 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sat, 9 Feb 2013 11:29:04 +0100 Subject: [PATCH 095/109] mnc: add empty handler --- tools/munin-node-c/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 8f2c0575..e814bb49 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -64,6 +64,7 @@ int main(int argc, char *argv[]) { arg = strtok(line, " \t\n"); if (!cmd || strlen(cmd) == 0) { + printf("# empty cmd\n"); } else if (strcmp(cmd, "version") == 0) { printf("munin c node version: %s\n", VERSION); } else if (strcmp(cmd, "nodes") == 0) { From bf25714e3ae3956666b34a3e0d18434165f05b3e Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sat, 9 Feb 2013 11:30:00 +0100 Subject: [PATCH 096/109] mnc: add config/fetch handler --- tools/munin-node-c/main.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index e814bb49..4dbae5d2 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -3,6 +3,7 @@ #include #include #include +#include char VERSION[] = "1.0.0"; @@ -61,7 +62,7 @@ int main(int argc, char *argv[]) { line[LINE_MAX-1] = '\0'; cmd = strtok(line, " \t\n"); - arg = strtok(line, " \t\n"); + arg = strtok(NULL, " \t\n"); if (!cmd || strlen(cmd) == 0) { printf("# empty cmd\n"); @@ -74,8 +75,18 @@ int main(int argc, char *argv[]) { return(0); } else if (strcmp(cmd, "list") == 0) { printf("# not implem yet cmd: %s\n", cmd); - } else if (strcmp(cmd, "config") == 0) { - } else if (strcmp(cmd, "fetch") == 0) { + } else if ( + strcmp(cmd, "config") == 0 || + strcmp(cmd, "fetch") == 0 + ) { + char cmdline[LINE_MAX]; + if (! access(arg, X_OK)) { + printf("# unknown plugin: %s\n", arg); + continue; + } + sprintf(cmdline, "exec %s/%s %s", plugin_dir, arg, cmd); + system(cmdline); + printf(".\n"); } else if (strcmp(cmd, "cap") == 0) { printf("cap "); if (strlen(spoolfetch_dir)) { From c32620c6451ce976c48139d6cc18c341acbc6dde Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sat, 9 Feb 2013 13:28:59 +0100 Subject: [PATCH 097/109] mnc: interact with munin-plugins-busybox --- tools/munin-node-c/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/munin-node-c/Makefile b/tools/munin-node-c/Makefile index bec42767..58b4b59f 100644 --- a/tools/munin-node-c/Makefile +++ b/tools/munin-node-c/Makefile @@ -11,4 +11,11 @@ munin-node-c: ${OBJS} ${CC} ${CFLAGS} $^ -o $@ clean: rm -f munin-node-c ${OBJS} ${LINKS} -.PHONY: all clean + rm -Rf plugins + +plugins: + mkdir -p plugins + cd ../munin-plugins-busybox && make + cd plugins && for i in $$(find ../../munin-plugins-busybox -type l); do ln -s $$i; done + +.PHONY: all clean plugins From aae73ff3b184cdf29ed6887b10e831f74683baab Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sat, 9 Feb 2013 14:11:56 +0100 Subject: [PATCH 098/109] mnc: conditional make of munin-plugins-busybox --- tools/munin-node-c/.gitignore | 1 + tools/munin-node-c/Makefile | 5 ++++- tools/munin-plugins-busybox/.gitignore | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 tools/munin-plugins-busybox/.gitignore diff --git a/tools/munin-node-c/.gitignore b/tools/munin-node-c/.gitignore index 16edcbc0..91f33c2b 100644 --- a/tools/munin-node-c/.gitignore +++ b/tools/munin-node-c/.gitignore @@ -1,3 +1,4 @@ # output files /*.o /munin-node-c +/plugins/* diff --git a/tools/munin-node-c/Makefile b/tools/munin-node-c/Makefile index 58b4b59f..d4c79fdc 100644 --- a/tools/munin-node-c/Makefile +++ b/tools/munin-node-c/Makefile @@ -13,9 +13,12 @@ clean: rm -f munin-node-c ${OBJS} ${LINKS} rm -Rf plugins -plugins: +plugins: plugins/.munin-plugins-busybox.installed + +plugins/.munin-plugins-busybox.installed: mkdir -p plugins cd ../munin-plugins-busybox && make cd plugins && for i in $$(find ../../munin-plugins-busybox -type l); do ln -s $$i; done + touch plugins/.munin-plugins-busybox.installed .PHONY: all clean plugins diff --git a/tools/munin-plugins-busybox/.gitignore b/tools/munin-plugins-busybox/.gitignore new file mode 100644 index 00000000..5761abcf --- /dev/null +++ b/tools/munin-plugins-busybox/.gitignore @@ -0,0 +1 @@ +*.o From 90c41118998a8d59dbcd984413e9f0687203b6aa Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sun, 10 Feb 2013 00:49:31 +0100 Subject: [PATCH 099/109] mnc: implement the "list" cmd --- tools/munin-node-c/main.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 4dbae5d2..990374cb 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include char VERSION[] = "1.0.0"; @@ -74,7 +76,24 @@ int main(int argc, char *argv[]) { } else if (strcmp(cmd, "quit") == 0) { return(0); } else if (strcmp(cmd, "list") == 0) { - printf("# not implem yet cmd: %s\n", cmd); + DIR* dirp = opendir(plugin_dir); + struct dirent* dp; + while ((dp = readdir(dirp)) != NULL) { + char cmdline[LINE_MAX]; + char* plugin_filename = dp->d_name;; + + if (plugin_filename[0] == '.') { + /* No dotted plugin */ + continue; + } + + sprintf(cmdline, "%s/%s", plugin_dir, plugin_filename); + if (access(cmdline, X_OK) == 0) { + printf("%s ", plugin_filename); + } + } + printf("\n"); + closedir(dirp); } else if ( strcmp(cmd, "config") == 0 || strcmp(cmd, "fetch") == 0 From c2ea44730c16bcbe214678f426aa1767950ff7f7 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sun, 10 Feb 2013 00:53:09 +0100 Subject: [PATCH 100/109] mnc: fix plugin existance control --- tools/munin-node-c/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 990374cb..483ca810 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -99,7 +99,8 @@ int main(int argc, char *argv[]) { strcmp(cmd, "fetch") == 0 ) { char cmdline[LINE_MAX]; - if (! access(arg, X_OK)) { + sprintf(cmdline, "%s/%s", plugin_dir, arg); + if (access(cmdline, X_OK) == -1) { printf("# unknown plugin: %s\n", arg); continue; } From a07c3d558b46a04065d42e96b519dabc0e2598f0 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sun, 10 Feb 2013 08:22:57 +0100 Subject: [PATCH 101/109] mnc: explict init of verbose --- tools/munin-node-c/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 483ca810..bd05ecbd 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -10,7 +10,7 @@ char VERSION[] = "1.0.0"; -int verbose; +int verbose = 0; char* host = ""; char* plugin_dir = "plugins"; From af04bfead685271cb0b259ee3f6b4c8cbd7c4be3 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sun, 10 Feb 2013 08:56:59 +0100 Subject: [PATCH 102/109] mnc: avoid out-of-bounds write using strtok --- tools/munin-node-c/main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index bd05ecbd..08d4080a 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -64,7 +64,10 @@ int main(int argc, char *argv[]) { line[LINE_MAX-1] = '\0'; cmd = strtok(line, " \t\n"); - arg = strtok(NULL, " \t\n"); + if(cmd == NULL) + arg = NULL; + else + arg = strtok(NULL, " \t\n"); if (!cmd || strlen(cmd) == 0) { printf("# empty cmd\n"); From 34b87128dead40b82f4d06e4cff089fe3090d633 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sun, 10 Feb 2013 08:58:16 +0100 Subject: [PATCH 103/109] mnc: avoid sprintf based stackoverflow --- tools/munin-node-c/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 08d4080a..4299f04a 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -90,7 +90,7 @@ int main(int argc, char *argv[]) { continue; } - sprintf(cmdline, "%s/%s", plugin_dir, plugin_filename); + snprintf(cmdline, LINE_MAX, "%s/%s", plugin_dir, plugin_filename); if (access(cmdline, X_OK) == 0) { printf("%s ", plugin_filename); } @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) { printf("# unknown plugin: %s\n", arg); continue; } - sprintf(cmdline, "exec %s/%s %s", plugin_dir, arg, cmd); + snprintf(cmdline, LINE_MAX, "exec %s/%s %s", plugin_dir, arg, cmd); system(cmdline); printf(".\n"); } else if (strcmp(cmd, "cap") == 0) { From 55c20ee59b48e6b840bca467b547c97753019007 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sun, 10 Feb 2013 09:02:40 +0100 Subject: [PATCH 104/109] mnc: fix arbitrary execution via ../ traversal --- tools/munin-node-c/main.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 4299f04a..5ae77285 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -102,6 +102,14 @@ int main(int argc, char *argv[]) { strcmp(cmd, "fetch") == 0 ) { char cmdline[LINE_MAX]; + if(arg == NULL) { + printf("# no plugin given\n"); + continue; + } + if(arg[0] == '.' || strchr(arg, '/')) { + printf("# invalid plugin character"); + continue; + } sprintf(cmdline, "%s/%s", plugin_dir, arg); if (access(cmdline, X_OK) == -1) { printf("# unknown plugin: %s\n", arg); From a752d8c5dae05a951578c3a4561800adea082bda Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sun, 10 Feb 2013 09:10:43 +0100 Subject: [PATCH 105/109] mnc: avoid execution via shell meta characters And remove dependency on /bin/sh. --- tools/munin-node-c/main.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tools/munin-node-c/main.c b/tools/munin-node-c/main.c index 5ae77285..88a97561 100644 --- a/tools/munin-node-c/main.c +++ b/tools/munin-node-c/main.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -102,6 +103,7 @@ int main(int argc, char *argv[]) { strcmp(cmd, "fetch") == 0 ) { char cmdline[LINE_MAX]; + pid_t pid; if(arg == NULL) { printf("# no plugin given\n"); continue; @@ -110,13 +112,21 @@ int main(int argc, char *argv[]) { printf("# invalid plugin character"); continue; } - sprintf(cmdline, "%s/%s", plugin_dir, arg); + snprintf(cmdline, LINE_MAX, "%s/%s", plugin_dir, arg); if (access(cmdline, X_OK) == -1) { printf("# unknown plugin: %s\n", arg); continue; } - snprintf(cmdline, LINE_MAX, "exec %s/%s %s", plugin_dir, arg, cmd); - system(cmdline); + if(0 == (pid = vfork())) { + execl(cmdline, arg, cmd, NULL); + /* according to vfork(2) we must use _exit */ + _exit(1); + } else if(pid < 0) { + printf("# fork failed\n"); + continue; + } else { + waitpid(pid, NULL, 0); + } printf(".\n"); } else if (strcmp(cmd, "cap") == 0) { printf("cap "); From 99a00144325a3ec6ca4717846e3733631bd2e097 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Sun, 10 Feb 2013 09:23:43 +0100 Subject: [PATCH 106/109] mnc: support parallel builds --- tools/munin-node-c/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-node-c/Makefile b/tools/munin-node-c/Makefile index d4c79fdc..8081951c 100644 --- a/tools/munin-node-c/Makefile +++ b/tools/munin-node-c/Makefile @@ -17,7 +17,7 @@ plugins: plugins/.munin-plugins-busybox.installed plugins/.munin-plugins-busybox.installed: mkdir -p plugins - cd ../munin-plugins-busybox && make + cd ../munin-plugins-busybox && $(MAKE) cd plugins && for i in $$(find ../../munin-plugins-busybox -type l); do ln -s $$i; done touch plugins/.munin-plugins-busybox.installed From d42785438b5f0d1c4a2dcd23737af31b5e246be8 Mon Sep 17 00:00:00 2001 From: Steve Schnepp Date: Sun, 10 Feb 2013 10:02:26 +0100 Subject: [PATCH 107/109] mpb: convert threads arg parsing to plain one --- tools/munin-plugins-busybox/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/munin-plugins-busybox/main.c b/tools/munin-plugins-busybox/main.c index 4b05abeb..205731b2 100644 --- a/tools/munin-plugins-busybox/main.c +++ b/tools/munin-plugins-busybox/main.c @@ -74,7 +74,7 @@ int main(int argc, char **argv) { return swap(argc, argv); break; case 't': - if(!strcmp(progname+1, "hreads")) + if(!strcmp(progname, "threads")) return threads(argc, argv); break; case 'u': From 5e6330c6c2bf704ecbb68c04718016fdfc83e0aa Mon Sep 17 00:00:00 2001 From: Phil! Gold Date: Mon, 11 Feb 2013 13:28:01 -0500 Subject: [PATCH 108/109] Document how to add an ESXi monitoring account. --- plugins/sensors/esxi__sensors | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/sensors/esxi__sensors b/plugins/sensors/esxi__sensors index d33b507f..87556193 100755 --- a/plugins/sensors/esxi__sensors +++ b/plugins/sensors/esxi__sensors @@ -27,6 +27,11 @@ file: env.user monitor env.pass passw0rd +To create an account just for monitoring the ESXi, add a user to the host, +make it a member of the 'root' group, and give it the 'No access' role. +That will allow the account to connect via WBEM, but not via any of the +management tools. + In the event that not all sensor types are desired, the plugin can be limited to a subset of the types available: From 7688a3f5ba982ae3421335a5e0fbf6798889d90d Mon Sep 17 00:00:00 2001 From: CWempe Date: Tue, 12 Feb 2013 15:30:59 +0100 Subject: [PATCH 109/109] deletet unnecessary output "\n" Output looked like this: root@htpc:/etc/munin/plugins# ./nvidia_gpu_mem mem0.value 0\n --- plugins/gpu/nvidia_gpu_ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/gpu/nvidia_gpu_ b/plugins/gpu/nvidia_gpu_ index a43f5989..453c50fa 100755 --- a/plugins/gpu/nvidia_gpu_ +++ b/plugins/gpu/nvidia_gpu_ @@ -180,7 +180,7 @@ case $name in totalMemGpu=`echo "$totalMemGpus" | sed -n $(( $nGpusCounter + 1 ))p` usedMemGpu=`echo "$usedMemGpus" | sed -n $(( $nGpusCounter + 1 ))p` percentMemUsed=$(( $usedMemGpu * 100 / $totalMemGpu )) - valueGpus="${valueGpus}${percentMemUsed}\n" + valueGpus="${valueGpus}${percentMemUsed}" : $(( nGpusCounter = $nGpusCounter + 1 )) done ;;