1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-25 02:18:08 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Dave Fennell 2013-02-22 17:12:49 +00:00
commit cdda2d6bf2
65 changed files with 3666 additions and 159 deletions

378
plugins/asterisk/asterisk Executable file
View file

@ -0,0 +1,378 @@
#!/usr/bin/perl -w
# -*- cperl -*-
=head1 NAME
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);
- the number of messages in all voicemail boxes (replaces
asterisk_voicemail);
- the number of active MeetMe conferences and users connected to them
(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
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
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.
=head2 DEFAULT CONFIGURATION
[asterisk]
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
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-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
Copyright (C) 2012 Diego Elio Pettenò <flameeyes@flameeyes.eu>
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=cut
use strict;
use Munin::Plugin;
use IO::Socket;
sub asterisk_command {
my ($socket, $command) = @_;
my $line, my $reply;
$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;
}
# 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(?:_(.+))$/;
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 @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,
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 $response_status = $socket->getline;
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' ) {
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 <<END;
multigraph asterisk_channels
graph_title Asterisk active channels
graph_args --base 1000 -l 0
graph_vlabel channels
graph_category asterisk
total.label channels
END
foreach my $channel (@CHANNELS) {
print <<END;
$channel.draw AREASTACK
$channel.label $channel channels
END
}
print <<END;
multigraph asterisk_voicemail
graph_title Asterisk voicemail messages
graph_args --base 1000 -l 0
graph_vlabel messages
graph_category asterisk
messages.label Total messages
END
print <<END;
multigraph asterisk_meetme
graph_title Asterisk meetme statistics
graph_args --base 1000 -l 0
graph_category asterisk
users.label Connected users
conferences.label Active conferences
END
print <<END;
multigraph asterisk_codecs
graphs_title Asterisk channels per codec
graph_args --base 1000 -l 0
graph_vlabel channels
graph_category asterisk
END
foreach my $codec (@CODECS) {
print <<END;
$codec.draw AREASTACK
$codec.label $codec channels
END
}
print <<END;
other.draw AREASTACK
other.label Other known codecs
unknwon.draw AREASTACK
unknown.label Unknown codec
END
unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) {
exit 0;
}
}
# if we arrive here and we don't have a socket, it's time to exit.
die $error if $error;
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
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.
my $meetme_response = asterisk_command($socket, "meetme list");
#Conf Num Parties Marked Activity Creation
#5500 0001 N/A 00:00:03 Static
#* Total number of MeetMe users: 1
my $sipchannels_response = asterisk_command($socket, "sip show channels");
#Peer User/ANR Call ID Seq (Tx/Rx) Format
#192.168.1.135 yann 6902112b3e0 00101/00002 g729
#1 active SIP channel(s)
my $iaxchannels_response = asterisk_command($socket, "iax2 show channels");
#Channel Peer Username ID (Lo/Rem) Seq (Tx/Rx) Lag Jitter JitBuf Format
#IAX2/rodolphe@rodolp 10.8.53.6 rodolphe 00003/01287 00006/00004 00000ms 0148ms 0000ms gsm
#1 active IAX channel(s)
# After all the data is fetched we can proceed to process it, the
# connection can be closed as we don't need any more data.
$socket->close();
my $active_channels = 'U';
$active_channels = $1 if $channels_response =~ /\n([0-9]+) active channels/;
print <<END;
multigraph asterisk_channels
total.value $active_channels
END
my @channels_list = split(/\r\n/, $channels_response) if $channels_response;
foreach my $channel (@CHANNELS) {
print "$channel.value ";
print $channels_response ? scalar(grep(/^$channel\//, @channels_list)) : "U";
print "\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";
}
print "\nmultigraph asterisk_meetme\n";
if ( !$meetme_response ) {
print <<END;
users.value U
conferences.value U
END
} else {
if ( $meetme_response =~ /No active/ ) {
print <<END;
users.value 0
conferences.value 0
END
} else {
my @meetme_list = split(/\r\n/, $meetme_response);
my $users = pop(@meetme_list);
$users =~ s/^Total number of MeetMe users: ([0-9]+)$/$1/;
print "users.value $users\n";
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 <<END;
other.value U
unknown.valeu U
END
} else {
my @results;
my ($i, $start, $unknown, $other)=(0,0,0,0);
foreach my $codec (@CODECS) {
$results[$i] = 0;
$i++;
}
# split the channels' listing and drop header and footnotes
my @sipchannels = $sipchannels_response ? split(/\r\n/, $sipchannels_response) : ();
pop(@sipchannels); shift(@sipchannels);
my @iaxchannels = $iaxchannels_response ? split(/\r\n/, $iaxchannels_response) : ();
pop(@iaxchannels); shift(@iaxchannels);
foreach my $sipchan (@sipchannels) {
my $found = 0;
my @fields = split ' ', $sipchan;
if ($fields[4] eq '0x0') {
$unknown += 1;
next;
}
foreach my $codec (@CODECSX) {
if ($fields[4] eq "$codec") {
$results[$i] = $results[$i] + 1;
$found = 1;
last;
}
$i++;
}
if (! $found) {
$other += 1;
print STDERR "CODEC: SIP other format $fields[4]\n" if $Munin::Plugin::DEBUG;
}
}
foreach my $iaxchan (@iaxchannels) {
my $found = 0;
my @fields = split ' ', $iaxchan;
if ($fields[8] eq '0x0') {
$unknown += 1;
next;
}
foreach my $codec (@CODECSX) {
if ($fields[8] eq "$codec") {
$results[$i] = $results[$i] + 1;
$found = 1;
last;
}
$i++;
}
if (! $found) {
$other += 1;
print STDERR "CODEC: IAX2 other format: $fields[8]\n" if $Munin::Plugin::DEBUG;
}
}
$i = 0;
foreach my $codec (@CODECS) {
print "$codec.value $results[$i]\n";
$i++;
}
print "other.value $other\n";
print "unknown.value $unknown\n";
}

37
plugins/db2/db2_cnx Executable file
View file

@ -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

View file

@ -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
;;

View file

@ -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.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
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

View file

@ -2,7 +2,11 @@
#
# Plugin to show amount of smtp-connections per hour
#
# Contributed by Håkon Nessjøen <lunatic@cpan.org>
# Contributed by Håkon Nessjøen <lunatic@cpan.org>
#
# Modified by Massimiliano Cianelli <massimiliano@cianelli.eu>
# 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)"

80
plugins/mysql/mysql_size_ondisk Executable file
View file

@ -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 <j.unterwurzacher@web-tech.at>
#%# 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 <br> which will be rendered to newlines in
# the web interface.
echo "graph_info ${INFO//$'\n'/<br>}"
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

59
plugins/network/if1sec_ Executable file
View file

@ -0,0 +1,59 @@
#! /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 [ ! -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;
system(\"\");
}" >> $cache
) &
echo $! > $pidfile
exit 0
fi
if [ "$1" = "config" ]
then
cat <<EOF
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
exit 0
fi
# values
cat ${cache}
> ${cache}
exit 0

0
plugins/network/netatalk Normal file → Executable file
View file

View file

@ -164,6 +164,12 @@ 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
if $warning;
printf "%s.critical %s\n", $h_norm_name, $critical
if $critical;
} else {
my $pid = $fork ? fork() : -1;
if ($pid <= 0) {

View file

@ -16,6 +16,8 @@
# tc - Override default program
# ignore_queue<n> - Queue with handle <n> not be plotted
# label_name<n> - Queue with handle <n> 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;

View file

@ -22,6 +22,8 @@ If trouble reading files, use:
=item 2012.09.20: Initial version by Arturo Borrero Gonzalez <aborrero@cica.es>
=item 2013.01.12: Added percentage graphing by Michiel Holtkamp <michiel@supermind.nl>
=back
=head1 LICENSE
@ -39,6 +41,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 +58,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

128
plugins/network/traffic_ipt Executable file
View file

@ -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 <aborrero@cica.es>
=item 2013.01.12: Added percentage graphing by Michiel Holtkamp <michiel@supermind.nl>
=item 2013.02.03: Converted to use iptables/ip6tables by Michiel Holtkamp <michiel@supermind.nl>
=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

View file

@ -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:

48
plugins/qpid/qpid_bytedepth Executable file
View file

@ -0,0 +1,48 @@
#!/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
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)

48
plugins/qpid/qpid_discardsring Executable file
View file

@ -0,0 +1,48 @@
#!/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
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)

48
plugins/qpid/qpid_enqueuebytes Executable file
View file

@ -0,0 +1,48 @@
#!/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
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)

48
plugins/qpid/qpid_enqueuecount Executable file
View file

@ -0,0 +1,48 @@
#!/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
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)

48
plugins/qpid/qpid_msgdepth Executable file
View file

@ -0,0 +1,48 @@
#!/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
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)

View file

@ -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:

View file

@ -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ò <flameeyes@flameeyes.eu>.
With help and suggestions of:
Bart ten Brinke <info@retrosync.com>
=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' ) {
@ -109,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" ) {
@ -158,7 +180,7 @@ END
}
}
unless ( $ENV{MUNIN_CAP_DIRTYCONFIG} == 1 ) {
unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) {
exit 0;
}
}

View file

@ -173,7 +173,7 @@ END
}
}
unless ( $ENV{MUNIN_CAP_DIRTYCONFIG} == 1 ) {
unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) {
exit 0;
}
}

View file

@ -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 <http://www.gnu.org/licenses/>.
#
# 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 <<EOC
graph_title Episodes
graph_vlabel Episodes
graph_category Sick-Beard
down.label Downloaded
total.label Total
EOC
;
exit 0;
}
my $get = LWP::UserAgent->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;
}

View file

@ -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 <http://www.gnu.org/licenses/>.
#
# 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 <<EOC
graph_title Shows
graph_vlabel Shows
graph_category Sick-Beard
active.label Active
total.label Total
EOC
;
exit 0;
}
my $get = LWP::UserAgent->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;
}

106
plugins/system/cpu_by_process Executable file
View file

@ -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 = <PS>;
my %total_cpu_by_process;
while (<PS>)
{
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] eq "config")
{
print <<END;
graph_title CPU time by Process
graph_args --base 1000
graph_vlabel seconds
graph_category system
graph_info Shows CPU time used by each process name
END
my $stack = 0;
sub draw() { return $stack++ ? "STACK" : "AREA" }
print map
{
"$_.label $_\n" .
"$_.min 0\n" .
"$_.type DERIVE\n" .
"$_.draw " . draw() . "\n"
} sort keys %total_cpu_by_process;
}
else
{
print map
{
"$_.value $total_cpu_by_process{$_}\n"
} sort keys %total_cpu_by_process;
}
exit(0);

0
plugins/system/membyuser Normal file → Executable file
View file

0
plugins/system/memory_by_process Normal file → Executable file
View file

View file

@ -25,8 +25,8 @@ 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
LANG=C mpstat -P ALL $interval |
awk -v cpus=$cpus '$2>=0&&$2<99 {print $2, systime(), (100-$11)/cpus; system("");}' >> $cache
rm -f $pidfile $cache
}

View file

@ -0,0 +1,105 @@
#!/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.
#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 maj_flt,comm h";
open PS, "$cmd|" or die "Failed to run ps command: $cmd: $!";
# my $header_line = <PS>;
my %total_by_process;
while (<PS>)
{
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] eq "config")
{
print <<END;
graph_title Page faults by Process
graph_args --base 1000
graph_vlabel seconds
graph_category system
graph_info Shows number of major page faults caused by each process name
END
my $stack = 0;
sub draw() { return $stack++ ? "STACK" : "AREA" }
print map
{
"$_.label $_\n" .
"$_.min 0\n" .
"$_.type DERIVE\n" .
"$_.draw " . draw() . "\n"
} sort keys %total_by_process;
}
else
{
print map
{
"$_.value $total_by_process{$_}\n"
} sort keys %total_by_process;
}
exit(0);

119
plugins/system/total_by_process_ Executable file
View file

@ -0,0 +1,119 @@
#!/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 = <PS>;
my %total_by_process;
while (<PS>)
{
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 <<END;
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
# graph_vlabel seconds
my $stack = 0;
sub draw() { return $stack++ ? "STACK" : "AREA" }
print map
{
"$_.label $_\n" .
"$_.min 0\n" .
"$_.type $fieldtype\n" .
"$_.draw " . draw() . "\n"
} sort keys %total_by_process;
}
else
{
print map
{
"$_.value $total_by_process{$_}\n"
} sort keys %total_by_process;
}
exit(0);

View file

@ -1,19 +1,21 @@
#!/bin/sh
# This plugin shows Solaris zone memory usage.
#%# family=auto
#%# 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
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
@ -24,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
@ -48,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

View file

@ -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;

View file

@ -19,6 +19,9 @@ configuration:
[xen-multi]
user root
env.xenskip "<space separated module list>"
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<diskstats> plugin which I borrowed some code from.
=head1 AUTHOR
Raphael HALIMI <raphael.halimi@gmail.com>
Modified by Krisztian IVANCSO <github-ivan@ivancso.net>
=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 (<XENTOP>) {
@ -129,7 +139,7 @@ while (<XENTOP>) {
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 (<XENTOP>) {
# 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 (<XENTOP>) {
}
}
@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";
}
}

View file

@ -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 = {}

117
plugins/xastir/xastir Executable file
View file

@ -0,0 +1,117 @@
#!/bin/bash
## Copyright (C) 2012 Robert Kilian <robertkilian@ostechnologies.net>
##
## 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 <http://www.gnu.org/licenses/>.
##
## 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"
# 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"

View file

@ -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

285
plugins/zfs/zfs_usage_ Executable file
View file

@ -0,0 +1,285 @@
#!/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
=head1 LICENSE
GPLv2
=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__