mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-25 10:28:36 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
56aa139205
63 changed files with 3233 additions and 380 deletions
42
plugins/apache/apache_average_time_last_n_requests
Executable file → Normal file
42
plugins/apache/apache_average_time_last_n_requests
Executable file → Normal file
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/perl -w
|
||||
# $Id$
|
||||
# Author: Nicolas Mendoza <nicolasm@opera.com> - 2008-06-18
|
||||
# Raphaël Droz <raphael.droz@gmail.com> - 2016-01-08
|
||||
#
|
||||
# Monitors the average time requests matching a custom regexp takes
|
||||
# For instance monitor time execution of files in http://example.com/foo/bar,
|
||||
|
@ -16,12 +16,37 @@
|
|||
# For instance:
|
||||
# LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %T %v"
|
||||
# Check http://httpd.apache.org/docs/2.2/mod/mod_log_config.html#formats for more info
|
||||
#
|
||||
# Configurable variables
|
||||
# fieldno - Override the default field number
|
||||
# linecount - How many last request to consider
|
||||
# Multiples instances for specific log files could be created by suffixing a configuration group.
|
||||
# Eg: ln -s apache_average_time_last_n_requests apache_average_time_last_n_requests_vhost1
|
||||
# Then:
|
||||
# [apache_average_time_last_n_requests]
|
||||
# logfile_vhost1 /var/log/apache/vhost1.log
|
||||
#
|
||||
#%# family=auto
|
||||
|
||||
use strict;
|
||||
|
||||
my $LAST_N_REQUESTS = 100000; # calculate based on this amount of requests
|
||||
my $ACCESS_LOG_PATTERN = '/var/log/apache2/access.log.*'; # log pattern, if many it will take the last one.
|
||||
my $TIME_FIELD_INDEX = -2; # second last field
|
||||
$0 =~ /apache_average_time_last_n_requests_(.+)*$/;
|
||||
my $name = $1;
|
||||
|
||||
my $LAST_N_REQUESTS = exists $ENV{'linecount'} ? $ENV{'linecount'} : 100000; # calculate based on this amount of requests
|
||||
my $TIME_FIELD_INDEX = exists $ENV{'fieldno'} ? $ENV{'fieldno'} : -2; # second last field
|
||||
my $ACCESS_LOG_PATTERN;
|
||||
|
||||
# log pattern, if globbing is used, it will take the last one.
|
||||
if (! $name) {
|
||||
$ACCESS_LOG_PATTERN = exists $ENV{'logfile'} ? $ENV{'logfile'} : '/var/log/apache2/access.log.*';
|
||||
}
|
||||
elsif (exists $ENV{'logfile_' . $name}) {
|
||||
$ACCESS_LOG_PATTERN = $ENV{'logfile_' . $name};
|
||||
}
|
||||
else {
|
||||
$ACCESS_LOG_PATTERN = '/var/log/apache2/access.log.*';
|
||||
}
|
||||
|
||||
my $config =<< "CONFIG"
|
||||
graph_title Apache average seconds last $LAST_N_REQUESTS requests
|
||||
|
@ -61,12 +86,12 @@ my $types = {
|
|||
my ($fields) = @_;
|
||||
my $script;
|
||||
($script = $fields->[6]) =~ s/\?.*\z //mx;
|
||||
return $script =~ m{ \.(png|jpe?g|jpg|gif|tiff|ilbm|tga) \z }mx;
|
||||
return $script =~ m{ \.(png|jpe?g|gif|tiff|ilbm|tga) \z }mx;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
if (defined(@ARGV) && ($ARGV[0] eq 'config')) {
|
||||
if (@ARGV && $ARGV[0] eq 'config') {
|
||||
|
||||
print $config;
|
||||
|
||||
|
@ -84,16 +109,21 @@ chomp $config_file;
|
|||
|
||||
my @lines = `tail -n $LAST_N_REQUESTS "$config_file"`;
|
||||
|
||||
FOO: {
|
||||
foreach my $line (@lines) {
|
||||
foreach my $type (keys %{$types}) {
|
||||
my @fields = split /\s+/, $line;
|
||||
if ($types->{$type}->{'matches'}(\@fields)) {
|
||||
if ($fields[$TIME_FIELD_INDEX] !~ m/^[0-9]+$/) {
|
||||
last FOO;
|
||||
}
|
||||
$types->{$type}->{'sum'} += $fields[$TIME_FIELD_INDEX];
|
||||
$types->{$type}->{'lines'}++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
foreach my $type (keys %{$types}) {
|
||||
my $value = $types->{$type}->{'lines'} ? $types->{$type}->{'sum'} / $types->{$type}->{'lines'} : 'U';
|
||||
printf "%s.value %s\n", ($type, $value);
|
||||
|
|
123
plugins/apache/apache_cache_disk_count
Executable file
123
plugins/apache/apache_cache_disk_count
Executable file
|
@ -0,0 +1,123 @@
|
|||
#!/bin/bash
|
||||
|
||||
: << =cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Munin plugin to monitor apache mod_cache_disk usage.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
[apache_cache_disk_count]
|
||||
user www-data
|
||||
env.cache_path /var/cache/apache2/mod_cache_disk
|
||||
env.strings css js
|
||||
env.label_cs CSS
|
||||
env.colour_css FFFF00
|
||||
env.label_js JS
|
||||
env.colour_js FF0000
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Raphaël Droz <raphael.droz+floss@gmail.com>
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2
|
||||
|
||||
=head1 MAGICK MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=cut
|
||||
|
||||
. $MUNIN_LIBDIR/plugins/plugin.sh
|
||||
|
||||
my_cache_path="${cache_path:-/var/cache/apache2/mod_cache_disk}"
|
||||
declare -a fieldnames labels colours
|
||||
|
||||
getenvdata() {
|
||||
let during_autoconf=0
|
||||
[[ $1 == -v ]] && during_autoconf=1
|
||||
arg=( "${strings:-}" )
|
||||
for i in ${arg[*]}; do
|
||||
if [[ ! $i =~ ^[a-zA-Z0-9]+$ ]]; then
|
||||
(( $during_autoconf )) && echo "no ($i isn't a valid fixed-string)"
|
||||
ok=0
|
||||
continue
|
||||
fi
|
||||
label=label_$i
|
||||
if [[ -z "${!label}" ]]; then
|
||||
(( $during_autoconf )) && echo "no ($i isn't given a label)"
|
||||
ok=0
|
||||
continue
|
||||
fi
|
||||
colour=colour_$i
|
||||
if [[ -z "${!colour}" ]]; then
|
||||
(( $during_autoconf )) && echo "no ($i isn't given a colour)"
|
||||
ok=0
|
||||
continue
|
||||
fi
|
||||
|
||||
fieldnames+=($i)
|
||||
labels+=("${!label}")
|
||||
colours+=("${!colour}")
|
||||
done
|
||||
}
|
||||
|
||||
if [[ $1 == autoconf ]]; then
|
||||
let ok=1
|
||||
|
||||
[[ -z $strings ]] && echo "no strings to monitor defined" && ok=0
|
||||
! type -P htcacheclean &>/dev/null && echo "can't find htcacheclean" && ok=0
|
||||
! test -d "$my_cache_path" && echo "cache_path \"$cache_path\" is not readable" && ok=0
|
||||
|
||||
getenvdata -v
|
||||
|
||||
(( ${#fieldnames[*]} == 0 )) && echo "no (no valid strings)" && ok=0
|
||||
(( $ok == 1 )) && echo yes
|
||||
exit 0
|
||||
fi
|
||||
|
||||
getenvdata
|
||||
|
||||
if [[ $1 == config ]]; then
|
||||
cat <<EOF
|
||||
graph_title Apache mod_cache_disk usage
|
||||
graph_title Number of entries in mod_cache_disk Apache cache
|
||||
graph_args --base 1000 -l 0
|
||||
graph_vlabel Y
|
||||
graph_category Apache
|
||||
graph_order ${fieldnames[*]} total
|
||||
total.draw LINE1
|
||||
total.label all
|
||||
total.type GAUGE
|
||||
total.min 0
|
||||
EOF
|
||||
|
||||
let i=0
|
||||
while (( $i < ${#fieldnames[*]} )); do
|
||||
string=${fieldnames[$i]}
|
||||
label="${labels[$i]}"
|
||||
colour="${colours[$i]}"
|
||||
cat <<EOF
|
||||
${string}.draw AREASTACK
|
||||
${string}.label ${label}
|
||||
${string}.colour ${colour}
|
||||
EOF
|
||||
((i++))
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
total=$(htcacheclean -a -p "$my_cache_path"|wc -l)
|
||||
asset_count=$(htcacheclean -a -p "$my_cache_path"|egrep -o "\.($(echo ${fieldnames[*]}|tr ' ' '|'))"|sort|uniq --count)
|
||||
printf "total.value %d\n" "$total"
|
||||
for i in ${fieldnames[*]}; do
|
||||
c=$(echo "$asset_count"|sed -rn "/$i/s;^\s*([0-9]+).*;\1;p")
|
||||
[[ -z $c ]] && c=U
|
||||
printf "%s.value %s\n" "$i" "$c"
|
||||
done
|
||||
|
||||
exit 0
|
196
plugins/apt/acng
Executable file
196
plugins/apt/acng
Executable file
|
@ -0,0 +1,196 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
=head1 NAME
|
||||
|
||||
acng - Graph activity for Apt-Cacher NG, request count and bytes
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Systems with "Apt-Cacher NG" installed and running.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This plugin will add graphs for "bytes in and out" and "requests in
|
||||
and out" for systems with "Apt-Cacher NG" installed.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
The plugin must have permission to read the log of Apt-Cacher NG. (On
|
||||
Debian 8, this file is world readable by default).
|
||||
|
||||
The path to the logfile can be set with the "logfile" environment
|
||||
variable.
|
||||
|
||||
=head2 DEFAULT CONFIGURATION
|
||||
|
||||
[acng]
|
||||
env.logfile /var/log/apt-cacher-ng/apt-cacher.log
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
Link this plugin to /etc/munin/plugins/ and restart the munin-node.
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=contrib
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Stig Sandbeck Mathisen
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv3
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Munin::Plugin;
|
||||
|
||||
use Storable qw(nfreeze thaw);
|
||||
use MIME::Base64;
|
||||
|
||||
my $logfile = $ENV{'logfile'} ||= '/var/log/apt-cacher-ng/apt-cacher.log';
|
||||
|
||||
need_multigraph;
|
||||
|
||||
# Read or initialize state used by the log tailer, and the plugin.
|
||||
sub read_state {
|
||||
|
||||
my ($pos, $statsin) = restore_state;
|
||||
my $stats = thaw(decode_base64 $statsin) if $statsin;
|
||||
|
||||
$pos = 0 unless defined $pos;
|
||||
$stats = {} unless defined $stats;
|
||||
|
||||
return ($pos, $stats);
|
||||
}
|
||||
|
||||
# Write state.
|
||||
#
|
||||
# "pos" is logfile position, and "stats" is a data structure with
|
||||
# counters used by the plugin.
|
||||
#
|
||||
# Note: Munin::Plugin::save_state has limited functionality, so the
|
||||
# data structure is serialized and converted to plain text.
|
||||
sub write_state {
|
||||
my ($pos, $stats) = @_;
|
||||
|
||||
my $statsout = encode_base64 nfreeze($stats);
|
||||
save_state($pos, $statsout);
|
||||
}
|
||||
|
||||
sub parse_logfile {
|
||||
my $logfile = shift;
|
||||
my ($pos, $stats) = read_state;
|
||||
|
||||
my @keys = ( 'time', 'direction', 'size', 'client', 'file' );
|
||||
|
||||
# Open log
|
||||
my ( $fh, $reset ) = tail_open( $logfile, $pos );
|
||||
|
||||
die "Unable to open logfile\n" unless ($fh);
|
||||
|
||||
while (<$fh>) {
|
||||
chomp;
|
||||
my @values = split( /\|/, $_ );
|
||||
|
||||
my %logentry;
|
||||
@logentry{@keys} = @values;
|
||||
|
||||
$stats->{'bytes'}{ $logentry{'direction'} } += $logentry{'size'};
|
||||
$stats->{'requests'}{ $logentry{'direction'} }++;
|
||||
}
|
||||
|
||||
# Close log
|
||||
$pos = tail_close($fh);
|
||||
|
||||
write_state($pos, $stats);
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
sub print_autoconf{
|
||||
my $logfile = shift;
|
||||
if ( open(my $fh, '<', $logfile) ) {
|
||||
print "yes\n";
|
||||
}
|
||||
else {
|
||||
printf "no (could not open %s)\n", $logfile;
|
||||
}
|
||||
}
|
||||
|
||||
sub print_config{
|
||||
my $stats = shift;
|
||||
|
||||
print << 'EOC';
|
||||
multigraph acng_bytes
|
||||
graph_title Apt-Cacher NG bytes
|
||||
graph_order origin client
|
||||
graph_vlabel bytes per ${graph_period}
|
||||
graph_info Bytes transferred between origin, apt-cacher-ng and clients
|
||||
origin.info bytes transferred between origin and apt-cacher-ng
|
||||
origin.label origin
|
||||
origin.type DERIVE
|
||||
origin.min 0
|
||||
client.info bytes transferred between apt-cacher-ng and clients
|
||||
client.label client
|
||||
client.type DERIVE
|
||||
client.min 0
|
||||
EOC
|
||||
print << "EOV" if $ENV{'MUNIN_CAP_DIRTYCONFIG'};
|
||||
origin.value $stats->{bytes}{I}
|
||||
client.value $stats->{bytes}{O}
|
||||
EOV
|
||||
|
||||
print << 'EOC';
|
||||
|
||||
multigraph acng_requests
|
||||
graph_title Apt-Cacher NG requests
|
||||
graph_order origin client
|
||||
graph_vlabel requests per ${graph_period}
|
||||
graph_info Requests from clients to apt-cacher-ng, and from apt-cacher-ng to origin
|
||||
origin.info requests from apt-cacher-ng to origin
|
||||
origin.label origin
|
||||
origin.type DERIVE
|
||||
origin.min 0
|
||||
client.info requests from clients to apt-cacher-ng
|
||||
client.label client
|
||||
client.type DERIVE
|
||||
client.min 0
|
||||
EOC
|
||||
|
||||
print << "EOV" if $ENV{'MUNIN_CAP_DIRTYCONFIG'};
|
||||
origin.value $stats->{requests}{I}
|
||||
client.value $stats->{requests}{O}
|
||||
EOV
|
||||
|
||||
}
|
||||
|
||||
sub print_values{
|
||||
my $stats = shift;
|
||||
|
||||
print << "EOV";
|
||||
multigraph acng_bytes
|
||||
origin.value $stats->{bytes}{I}
|
||||
client.value $stats->{bytes}{O}
|
||||
|
||||
multigraph acng_requests
|
||||
origin.value $stats->{requests}{I}
|
||||
client.value $stats->{requests}{O}
|
||||
EOV
|
||||
}
|
||||
|
||||
if ($ARGV[0] and $ARGV[0] eq 'autoconf') {
|
||||
print_autoconf($logfile);
|
||||
}
|
||||
elsif ($ARGV[0] and $ARGV[0] eq 'config') {
|
||||
my $stats = parse_logfile($logfile);
|
||||
print_config($stats);
|
||||
}
|
||||
else {
|
||||
my $stats = parse_logfile($logfile);
|
||||
print_values($stats);
|
||||
}
|
|
@ -29,9 +29,13 @@ check out this git repository from
|
|||
aptitude install python-apt
|
||||
git clone git://github.com/munin-monitoring/contrib.git
|
||||
cd contrib/plugins/apt/deb_packages
|
||||
sudo cp deb_packages.py /etc/munin/plugins
|
||||
sudo cp deb_packages.py /etc/munin/plugins/deb_packages
|
||||
sudo cp deb_packages.munin-conf /etc/munin/plugin-conf.d/deb_packages
|
||||
|
||||
Verify the installation by
|
||||
|
||||
sudo munin-run deb_packages
|
||||
|
||||
### Configuration
|
||||
If you copied deb_packages.munin-conf to plugin-conf.d you have a starting point.
|
||||
A typical configuration looks like this
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
# [backuppc]
|
||||
# user backuppc
|
||||
# env.pcdir /var/lib/BackupPC/pc
|
||||
# env.full_warning 10 # warn if FULL backup older than N days
|
||||
# env.full_critical 20 # critical if FULL backup older than N days
|
||||
# env.incr_warning 1 # warn if INCR backup older than N days
|
||||
# env.incr_critical 3 # critical if INCR backup older than N days
|
||||
#
|
||||
#%# family=backuppc
|
||||
#%# capabilities=autoconf
|
||||
|
@ -42,6 +46,18 @@ if [ "$1" = "config" ]; then
|
|||
do
|
||||
echo "$(clean_fieldname ${h})_full.label $(clean_fieldname ${h}) Full"
|
||||
echo "$(clean_fieldname ${h})_incr.label $(clean_fieldname ${h}) Incr"
|
||||
if [ -n "$full_warning" ]; then
|
||||
echo "$(clean_fieldname ${h})_full.warning $full_warning"
|
||||
fi
|
||||
if [ -n "$incr_warning" ]; then
|
||||
echo "$(clean_fieldname ${h})_incr.warning $incr_warning"
|
||||
fi
|
||||
if [ -n "$full_critical" ]; then
|
||||
echo "$(clean_fieldname ${h})_full.critical $full_critical"
|
||||
fi
|
||||
if [ -n "$incr_critical" ]; then
|
||||
echo "$(clean_fieldname ${h})_incr.critical $incr_critical"
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
@ -150,3 +166,5 @@ one per row. The columns are:
|
|||
mangle
|
||||
Set if this backup has mangled file names and attributes. Always true
|
||||
for backups in v1.4.0 and above. False for all backups prior to v1.4.0.
|
||||
|
||||
__END__
|
||||
|
|
274
plugins/balanceng/bng
Executable file
274
plugins/balanceng/bng
Executable file
|
@ -0,0 +1,274 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# munin plugin for BalanceNG
|
||||
# https://www.inlab.de/load-balancer/index.html
|
||||
#
|
||||
# (w) 2015 by Rhonda D'Vine <rhonda@strg.at>
|
||||
# (c) 2015 by strg.at GmbH <http://strg.at/>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; version 2 dated June,
|
||||
# 1991.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Munin::Plugin;
|
||||
|
||||
my $host;
|
||||
|
||||
my %servers;
|
||||
my %targets;
|
||||
|
||||
# we support autoconf
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf suggest
|
||||
|
||||
# Check for multigraph capabilities
|
||||
need_multigraph();
|
||||
|
||||
# Handle munin 'autoconf' command
|
||||
do_autoconf() if ( $ARGV[0] && $ARGV[0] eq 'autoconf' );
|
||||
|
||||
# Fetch data values
|
||||
do_fetch_values();
|
||||
|
||||
# Handle munin 'config' command
|
||||
# This can only be done after getting the data
|
||||
if ( defined $ARGV[0] && $ARGV[0] eq 'config' ) {
|
||||
do_config();
|
||||
}
|
||||
|
||||
|
||||
generate_output();
|
||||
|
||||
exit 0;
|
||||
|
||||
sub do_autoconf { # {{{ check if we can offer autoconf
|
||||
print (-x '/sbin/bng' ? "yes\n" : "no\n");
|
||||
exit 0;
|
||||
} # }}}
|
||||
|
||||
sub do_fetch_values { # {{{ fetch all the names and values needed
|
||||
|
||||
## MIBs from https://www.inlab.de/load-balancer/BalanceNG-V3-Manual.pdf
|
||||
|
||||
# node name
|
||||
open READ, "/sbin/bng -g .1.3.6.1.4.1.2771.1.5 |" || die "$0: can't fork bng: $!\n";
|
||||
<READ>;
|
||||
<READ>;
|
||||
$host = <READ>;
|
||||
chomp $host;
|
||||
close READ;
|
||||
|
||||
my $next;
|
||||
|
||||
# server names
|
||||
$next = '.1.3.6.1.4.1.2771.1.60.3';
|
||||
while (open READ, "/sbin/bng -n $next |") {
|
||||
$next = <READ>;
|
||||
chomp $next;
|
||||
|
||||
if ($next !~ /^\.1\.3\.6\.1\.4\.1\.2771\.1\.60\.3/) {
|
||||
close READ;
|
||||
last;
|
||||
}
|
||||
|
||||
<READ>;
|
||||
my $name = <READ>;
|
||||
chomp $name;
|
||||
push @{$servers{name}}, clean_fieldname($name);
|
||||
|
||||
close READ;
|
||||
}
|
||||
|
||||
# server sent bytes
|
||||
$next = '.1.3.6.1.4.1.2771.1.60.15';
|
||||
while (open READ, "/sbin/bng -n $next |") {
|
||||
$next = <READ>;
|
||||
chomp $next;
|
||||
|
||||
if ($next !~ /^\.1\.3\.6\.1\.4\.1\.2771\.1\.60\.15/) {
|
||||
close READ;
|
||||
last;
|
||||
}
|
||||
|
||||
<READ>;
|
||||
my $name = <READ>;
|
||||
chomp $name;
|
||||
push @{$servers{sent}}, $name;
|
||||
$servers{senttotal} += $name;
|
||||
|
||||
close READ;
|
||||
}
|
||||
|
||||
# server recv bytes
|
||||
$next = '.1.3.6.1.4.1.2771.1.60.17';
|
||||
while (open READ, "/sbin/bng -n $next |") {
|
||||
$next = <READ>;
|
||||
chomp $next;
|
||||
|
||||
if ($next !~ /^\.1\.3\.6\.1\.4\.1\.2771\.1\.60\.17/) {
|
||||
close READ;
|
||||
last;
|
||||
}
|
||||
|
||||
<READ>;
|
||||
my $name = <READ>;
|
||||
chomp $name;
|
||||
push @{$servers{recv}}, $name;
|
||||
$servers{recvtotal} += $name;
|
||||
|
||||
close READ;
|
||||
}
|
||||
|
||||
# target names
|
||||
$next = '.1.3.6.1.4.1.2771.1.70.3';
|
||||
while (open READ, "/sbin/bng -n $next |") {
|
||||
$next = <READ>;
|
||||
chomp $next;
|
||||
|
||||
if ($next !~ /^\.1\.3\.6\.1\.4\.1\.2771\.1\.70\.3/) {
|
||||
close READ;
|
||||
last;
|
||||
}
|
||||
|
||||
<READ>;
|
||||
my $name = <READ>;
|
||||
chomp $name;
|
||||
push @{$targets{name}}, clean_fieldname($name);
|
||||
|
||||
close READ;
|
||||
}
|
||||
|
||||
# target sent bytes
|
||||
$next = '.1.3.6.1.4.1.2771.1.70.27';
|
||||
while (open READ, "/sbin/bng -n $next |") {
|
||||
$next = <READ>;
|
||||
chomp $next;
|
||||
|
||||
if ($next !~ /^\.1\.3\.6\.1\.4\.1\.2771\.1\.70\.27/) {
|
||||
close READ;
|
||||
last;
|
||||
}
|
||||
|
||||
<READ>;
|
||||
my $name = <READ>;
|
||||
chomp $name;
|
||||
push @{$targets{sent}}, $name;
|
||||
$targets{senttotal} += $name;
|
||||
|
||||
close READ;
|
||||
}
|
||||
|
||||
# target recv bytes
|
||||
$next = '.1.3.6.1.4.1.2771.1.70.29';
|
||||
while (open READ, "/sbin/bng -n $next |") {
|
||||
$next = <READ>;
|
||||
chomp $next;
|
||||
|
||||
if ($next !~ /^\.1\.3\.6\.1\.4\.1\.2771\.1\.70\.29/) {
|
||||
close READ;
|
||||
last;
|
||||
}
|
||||
|
||||
<READ>;
|
||||
my $name = <READ>;
|
||||
chomp $name;
|
||||
push @{$targets{recv}}, $name;
|
||||
$targets{recvtotal} += $name;
|
||||
|
||||
close READ;
|
||||
}
|
||||
|
||||
} # }}}
|
||||
|
||||
sub do_config { # {{{ write out the configuration
|
||||
print <<"EOF";
|
||||
multigraph bng
|
||||
graph_title Bng Throughput
|
||||
graph_order sent recv
|
||||
graph_args --base 1000 -l 0
|
||||
graph_vlabel Packets/\${graph_period}
|
||||
graph_category network
|
||||
graph_info this graph shows the outbound traffic for $host
|
||||
|
||||
sent.label Sent
|
||||
sent.draw AREA
|
||||
sent.type DERIVE
|
||||
sent.min 0
|
||||
recv.label Received
|
||||
recv.draw AREA
|
||||
recv.type DERIVE
|
||||
recv.min 0
|
||||
|
||||
EOF
|
||||
|
||||
foreach my $interface (@{$servers{name}}, @{$targets{name}}) {
|
||||
print <<"EOF";
|
||||
multigraph bng.${interface}
|
||||
|
||||
graph_title Interface $interface traffic
|
||||
graph_order sent recv
|
||||
graph_args --base 1000 -l 0
|
||||
graph_vlabel Packets/\${graph_period}
|
||||
graph_category network
|
||||
graph_info this graph shows the total traffic for ${interface}
|
||||
|
||||
sent.label ${interface}_Sent
|
||||
sent.draw AREA
|
||||
sent.type DERIVE
|
||||
sent.min 0
|
||||
recv.label ${interface}_Received
|
||||
recv.draw AREA
|
||||
recv.type DERIVE
|
||||
recv.min 0
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
exit 0;
|
||||
} # }}}
|
||||
|
||||
sub generate_output { # {{{ write out the data
|
||||
print <<"EOF";
|
||||
multigraph bng
|
||||
sent.value $servers{senttotal}
|
||||
recv.value $servers{recvtotal}
|
||||
EOF
|
||||
|
||||
my $i;
|
||||
$i = 0;
|
||||
foreach my $interface (@{$servers{name}}) {
|
||||
print <<"EOF";
|
||||
multigraph bng.${interface}
|
||||
sent.value $servers{sent}[$i]
|
||||
recv.value $servers{recv}[$i]
|
||||
EOF
|
||||
$i++;
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
foreach my $interface (@{$targets{name}}) {
|
||||
print <<"EOF";
|
||||
multigraph bng.${interface}
|
||||
sent.value $targets{sent}[$i]
|
||||
recv.value $targets{recv}[$i]
|
||||
EOF
|
||||
$i++;
|
||||
}
|
||||
|
||||
} # }}}
|
||||
|
||||
# vim:fdm=marker:
|
|
@ -66,11 +66,14 @@ GPLv2
|
|||
=cut
|
||||
|
||||
# IMAP Configuration Directory
|
||||
CONFIGDIR=$(awk -F : '/^configdirectory:/ { gsub(/ /, "", $2); print $2 }' /etc/imapd.conf 2> /dev/null)
|
||||
PROCDIR="${CONFIGDIR}/proc"
|
||||
PROCDIR=$(awk -F : '/^proc_path:/ { gsub(/ /, "", $2); print $2 }' /etc/imapd.conf 2> /dev/null)
|
||||
if [ "x${PROCDIR}x" = "xx" ]; then
|
||||
CONFIGDIR=$(awk -F : '/^configdirectory:/ { gsub(/ /, "", $2); print $2 }' /etc/imapd.conf 2> /dev/null)
|
||||
PROCDIR="${CONFIGDIR}/proc"
|
||||
fi
|
||||
|
||||
if [ "$1" = "autoconf" ]; then
|
||||
if [ "x${CONFIGDIR}x" != "xx" ] && [ -d ${PROCDIR} ]; then
|
||||
if [ "x${PROCDIR}x" != "xx" ] && [ -d ${PROCDIR} ]; then
|
||||
echo yes
|
||||
else
|
||||
echo "no (no cyrus-imapd procdir found)"
|
||||
|
@ -79,7 +82,7 @@ if [ "$1" = "autoconf" ]; then
|
|||
fi
|
||||
|
||||
# Check if we actually got some sensible data
|
||||
if [ "x${CONFIGDIR}x" = "xx" ]; then
|
||||
if [ "x${PROCDIR}x" = "xx" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ my %runtime_stats = (
|
|||
"vnodes" => ["vn_active","vn_alloc","vn_get","vn_hold","vn_rele","vn_reclaim","vn_remove","vn_free"],
|
||||
"buf" => ["xb_get","xb_create","xb_get_locked","xb_get_locked_waited","xb_busy_locked","xb_miss_locked","xb_page_retries","xb_page_found","xb_get_read"],
|
||||
"ibt2" => ["xs_ibt_2_lookup","xs_ibt_2_compare","xs_ibt_2_insrec","xs_ibt_2_delrec","xs_ibt_2_newroot","xs_ibt_2_killroot","xs_ibt_2_increment","xs_ibt_2_decrement","xs_ibt_2_lshift","xs_ibt_2_rshift","xs_ibt_2_split","xs_ibt_2_join","xs_ibt_2_alloc","xs_ibt_2_free","xs_ibt_2_moves"],
|
||||
"fibt2" => ["xs_fibt_2_lookup","xs_fibt_2_compare","xs_fibt_2_insrec","xs_fibt_2_delrec","xs_fibt_2_newroot","xs_fibt_2_killroot","xs_fibt_2_increment","xs_fibt_2_decrement","xs_fibt_2_lshift","xs_fibt_2_rshift","xs_fibt_2_split","xs_fibt_2_join","xs_fibt_2_alloc","xs_fibt_2_free","xs_fibt_2_moves"],
|
||||
"bmbt2" => ["xs_bmbt_2_lookup","xs_bmbt_2_compare","xs_bmbt_2_insrec","xs_bmbt_2_delrec","xs_bmbt_2_newroot","xs_bmbt_2_killroot","xs_bmbt_2_increment","xs_bmbt_2_decrement","xs_bmbt_2_lshift","xs_bmbt_2_rshift","xs_bmbt_2_split","xs_bmbt_2_join","xs_bmbt_2_alloc","xs_bmbt_2_free","xs_bmbt_2_moves"],
|
||||
"abtc2" => ["xs_abtc_2_lookup","xs_abtc_2_compare","xs_abtc_2_insrec","xs_abtc_2_delrec","xs_abtc_2_newroot","xs_abtc_2_killroot","xs_abtc_2_increment","xs_abtc_2_decrement","xs_abtc_2_lshift","xs_abtc_2_rshift","xs_abtc_2_split","xs_abtc_2_join","xs_abtc_2_alloc","xs_abtc_2_free","xs_abtc_2_moves"],
|
||||
"abtb2" => ["xs_abtb_2_lookup","xs_abtb_2_compare","xs_abtb_2_insrec","xs_abtb_2_delrec","xs_abtb_2_newroot","xs_abtb_2_killroot","xs_abtb_2_increment","xs_abtb_2_decrement","xs_abtb_2_lshift","xs_abtb_2_rshift","xs_abtb_2_split","xs_abtb_2_join","xs_abtb_2_alloc","xs_abtb_2_free","xs_abtb_2_moves"],
|
||||
|
|
120
plugins/docker/docker_cpu
Executable file
120
plugins/docker/docker_cpu
Executable file
|
@ -0,0 +1,120 @@
|
|||
#!/usr/bin/perl -w
|
||||
# -*- perl -*-
|
||||
|
||||
=head1 NAME
|
||||
|
||||
docker_cpu - Munin plugin to monitor docker container CPU usage.
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Should work on any Linux system that has docker support.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
Root privilege required to execute docker command.
|
||||
|
||||
1. Create a new file named "docker" inside the folder /etc/munin/plugin-conf.d/
|
||||
2. Docker file content:
|
||||
|
||||
[docker_cpu]
|
||||
user root
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
v.0.1
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2015 Samuel Cantero.
|
||||
Email: scanterog at gmail dot com
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv3
|
||||
|
||||
=cut
|
||||
|
||||
my $docker=`which docker`;
|
||||
|
||||
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) {
|
||||
if ($docker) {
|
||||
print "yes\n";
|
||||
exit 0;
|
||||
}
|
||||
else{
|
||||
print "no (Docker has not been found)\n";
|
||||
exit 0;
|
||||
}
|
||||
}
|
||||
|
||||
$docker =~ s/\s+$//;
|
||||
|
||||
my @containers = split "\n" , `$docker ps --no-trunc=true`;
|
||||
my $result;
|
||||
|
||||
for my $i (1 .. $#containers)
|
||||
{
|
||||
my @fields = split / +/, $containers[$i];
|
||||
my $id = $fields[0];
|
||||
my $name = $fields[$#fields];
|
||||
# manage container name containing arithmetic operators and dots. E.g, my-container.
|
||||
$name =~ s/[-\+*\/\.]/_/g;
|
||||
# truncate container name with "," character.
|
||||
$name =~ s/,.*//g;
|
||||
if (open(my $file, '<', "/sys/fs/cgroup/cpuacct/docker/$id/cpuacct.usage"))
|
||||
{
|
||||
my $total_cpu_ns = <$file>;
|
||||
$total_cpu_ns =~ s/\s+$//;
|
||||
close $file;
|
||||
if (open($file, '<', "/sys/fs/cgroup/cpuacct/docker/$id/cpuacct.usage_percpu"))
|
||||
{
|
||||
my @ncpu = split / /, <$file>;
|
||||
close $file;
|
||||
push @result, {'name'=>$name, 'total_cpu_ns'=>$total_cpu_ns, 'ncpu'=>$#ncpu};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq "config")
|
||||
{
|
||||
my $nanoSecondsInSecond=1000000000;
|
||||
my $graphlimit = $result[0]{'ncpu'};
|
||||
foreach(@result){
|
||||
if ($$_{'ncpu'} > $graphlimit){
|
||||
$graphlimit = $$_{'ncpu'};
|
||||
}
|
||||
}
|
||||
$graphlimit = $graphlimit * 100;
|
||||
print "graph_title Docker container CPU usage\n";
|
||||
print "graph_args --base 1000 -r --lower-limit 0 --upper-limit $graphlimit\n";
|
||||
print "graph_vlabel %\n";
|
||||
print "graph_scale no\n";
|
||||
print "graph_period second\n";
|
||||
print "graph_category Docker\n";
|
||||
print "graph_info This graph shows docker container CPU usage.\n";
|
||||
|
||||
foreach(@result)
|
||||
{
|
||||
print "$$_{'name'}.label $$_{'name'}\n";
|
||||
print "$$_{'name'}.draw LINE2\n";
|
||||
print "$$_{'name'}.min 0\n";
|
||||
print "$$_{'name'}.type DERIVE\n";
|
||||
print "$$_{'name'}.cdef $$_{'name'},$nanoSecondsInSecond,/\n";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
# Note: Counters/derive need to report integer values.
|
||||
|
||||
foreach(@result)
|
||||
{
|
||||
$tcpu = ($$_{'total_cpu_ns'}*100); #to percentage
|
||||
print "$$_{'name'}.value $tcpu\n";
|
||||
}
|
||||
|
||||
# vim:syntax=perl
|
98
plugins/docker/docker_memory
Executable file
98
plugins/docker/docker_memory
Executable file
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/perl -w
|
||||
# -*- perl -*-
|
||||
|
||||
=head1 NAME
|
||||
|
||||
docker_memory - Munin plugin to monitor docker container memory usage.
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Should work on any Linux system that has docker support.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
Root privilege required to execute docker command.
|
||||
|
||||
1. Create a new file named "docker" inside the folder /etc/munin/plugin-conf.d/
|
||||
2. Docker file content:
|
||||
|
||||
[docker_memory]
|
||||
user root
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
v.0.1
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2015 Samuel Cantero.
|
||||
Email: scanterog at gmail dot com
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv3
|
||||
|
||||
=cut
|
||||
|
||||
my $docker=`which docker`;
|
||||
|
||||
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) {
|
||||
if ($docker) {
|
||||
print "yes\n";
|
||||
exit 0;
|
||||
}
|
||||
else{
|
||||
print "no (Docker has not been found)\n";
|
||||
exit 0;
|
||||
}
|
||||
}
|
||||
|
||||
$docker =~ s/\s+$//;
|
||||
|
||||
my @containers = split "\n" , `$docker ps --no-trunc=true`;
|
||||
my $result;
|
||||
|
||||
for my $i (1 .. $#containers)
|
||||
{
|
||||
my @fields = split / +/, $containers[$i];
|
||||
my $id = $fields[0];
|
||||
my $name = $fields[$#fields];
|
||||
# manage container name containing arithmetic operators and dots. E.g, my-container.
|
||||
$name =~ s/[-\+*\/\.]/_/g;
|
||||
# truncate container name with "," character.
|
||||
$name =~ s/,.*//g;
|
||||
if (open(my $file, '<', "/sys/fs/cgroup/memory/docker/$id/memory.usage_in_bytes"))
|
||||
{
|
||||
my $memory_bytes = <$file>;
|
||||
$memory_bytes =~ s/\s+$//;
|
||||
push @result, {'name'=>$name, 'memory_bytes'=>$memory_bytes};
|
||||
}
|
||||
}
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq "config")
|
||||
{
|
||||
print "graph_title Docker container memory usage\n";
|
||||
print "graph_args --base 1024 -l 0\n";
|
||||
print "graph_vlabel Bytes\n";
|
||||
print "graph_category Docker\n";
|
||||
print "graph_info This graph shows docker container memory usage.\n";
|
||||
|
||||
foreach(@result)
|
||||
{
|
||||
print "$$_{'name'}.label $$_{'name'}\n";
|
||||
print "$$_{'name'}.draw LINE2\n";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
foreach(@result)
|
||||
{
|
||||
print "$$_{'name'}.value $$_{'memory_bytes'}\n";
|
||||
}
|
||||
|
||||
# vim:syntax=perl
|
BIN
plugins/docker/example_graphs/docker_cpu_usage.png
Normal file
BIN
plugins/docker/example_graphs/docker_cpu_usage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 84 KiB |
BIN
plugins/docker/example_graphs/docker_memory_usage.png
Normal file
BIN
plugins/docker/example_graphs/docker_memory_usage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
|
@ -20,7 +20,7 @@ mktempfile () {
|
|||
mktemp -t $1
|
||||
}
|
||||
|
||||
LOGFILE=${logfile:-/var/log/xferlog}
|
||||
LOGFILE=${logfile:-/var/log/proftpd/xferlog}
|
||||
LOGTAIL=${logtail:-`which logtail`}
|
||||
STATEFILE=/var/lib/munin/plugin-state/xferlog-bytes.offset
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ mktempfile () {
|
|||
mktemp -t $1
|
||||
}
|
||||
|
||||
LOGFILE=${logfile:-/var/log/xferlog}
|
||||
LOGFILE=${logfile:-/var/log/proftpd/xferlog}
|
||||
LOGTAIL=${logtail:-`which logtail`}
|
||||
STATEFILE=/var/lib/munin/plugin-state/xferlog-count.offset
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
"""
|
||||
|
||||
import sys, os
|
||||
import sys, os, re
|
||||
from subprocess import check_output
|
||||
|
||||
# set path to your gunicorn pid
|
||||
|
@ -44,11 +44,9 @@ class GunicornMemoryStatus():
|
|||
except:
|
||||
raise Exception("Couldn't read gunicorn pid information")
|
||||
|
||||
|
||||
def print_total_memory(self):
|
||||
print ('total_memory.value %d' % self._get_total_memory())
|
||||
|
||||
|
||||
def _get_master_pid(self):
|
||||
master_pid_file = open(GUNICORN_PID_PATH)
|
||||
self.master_pid = master_pid_file.read().rstrip()
|
||||
|
@ -74,7 +72,18 @@ class GunicornMemoryStatus():
|
|||
return worker_memory_usage
|
||||
|
||||
def print_config():
|
||||
print "graph_title Gunicorn - Memory Usage"
|
||||
instance = None
|
||||
name = os.path.basename(sys.argv[0])
|
||||
if name != "gunicorn_memory_status":
|
||||
for r in ("^gunicorn_(.*?)_memory_status$", "^gunicorn_memory_status_(.*?)$"):
|
||||
m = re.match(r, name, re.IGNORECASE)
|
||||
if m:
|
||||
instance = m.group(1)
|
||||
break
|
||||
graph_title = "graph_title Gunicorn - Memory Usage"
|
||||
if instance:
|
||||
graph_title = "%s - %s" % (graph_title, instance)
|
||||
print graph_title
|
||||
print "graph_args --base 1024 -l 0"
|
||||
print "graph_vlabel Megabytes"
|
||||
print "graph_category gunicorn"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
"""
|
||||
|
||||
import sys, os
|
||||
import sys, os, re
|
||||
from subprocess import check_output
|
||||
from time import sleep
|
||||
|
||||
|
@ -87,7 +87,18 @@ class GunicornStatus():
|
|||
return user_time + kernel_time
|
||||
|
||||
def print_config():
|
||||
print "graph_title Gunicorn - Status"
|
||||
instance = None
|
||||
name = os.path.basename(sys.argv[0])
|
||||
if name != "gunicorn_status":
|
||||
for r in ("^gunicorn_(.*?)_status$", "^gunicorn_status_(.*?)$"):
|
||||
m = re.match(r, name, re.IGNORECASE)
|
||||
if m:
|
||||
instance = m.group(1)
|
||||
break
|
||||
graph_title = "graph_title Gunicorn - Status"
|
||||
if instance:
|
||||
graph_title = "%s - %s" % (graph_title, instance)
|
||||
print graph_title
|
||||
print "graph_args -l 0"
|
||||
print "graph_vlabel Number of workers"
|
||||
print "graph_category gunicorn"
|
||||
|
|
|
@ -40,7 +40,7 @@ server {
|
|||
=head2 APACHE 2.2 CONFIG
|
||||
|
||||
FastCgiExternalServer /var/run/hhvm_admin.fcgi -host 127.0.0.1:8080
|
||||
Listen 127.0.0.1:8081
|
||||
Listen 127.0.0.1:8081
|
||||
<VirtualHost 127.0.0.1:8081>
|
||||
Alias /check-health /var/run/hhvm_admin.fcgi
|
||||
Alias /status.json /var/run/hhvm_admin.fcgi
|
||||
|
@ -107,8 +107,6 @@ tc-profsize.label TC Profiling Size
|
|||
tc-profsize.info Translation Cache Profiling Size
|
||||
tc-coldsize.label TC Cold Size
|
||||
tc-coldsize.info Translation Cache Cold Size
|
||||
tc-trampolinessize.label TC Trampoline Size
|
||||
tc-trampolinessize.info Translation Cache Trampoline Size
|
||||
tc-frozensize.label TC Frozen Size
|
||||
tc-frozensize.info Translation Cache Frozen Size
|
||||
rds.label RDS Used Bytes
|
||||
|
@ -121,7 +119,7 @@ EOF
|
|||
my $status = getJson( sprintf( '%s/status.json', $url ) );
|
||||
|
||||
printf( "multigraph hhvm_%s_threads\n", $graphName );
|
||||
printf( "threads.value %d\n", int( @{ $status->{'status'}->{'threads'} } ) );
|
||||
printf( "threads.value %d\n", int( @{ $status->{'status'}->{'threads'} } ) );
|
||||
printf( "load.value %d\n", $health->{'load'} );
|
||||
printf( "queued.value %d\n", $health->{'queued'} );
|
||||
print "\n";
|
||||
|
@ -131,7 +129,6 @@ EOF
|
|||
printf( "tc-size.value %d\n", $health->{'tc-size'} );
|
||||
printf( "tc-profsize.value %d\n", $health->{'tc-profsize'} );
|
||||
printf( "tc-coldsize.value %d\n", $health->{'tc-coldsize'} );
|
||||
printf( "tc-trampolinessize.value %d\n", $health->{'tc-trampolinessize'} );
|
||||
printf( "tc-frozensize.value %d\n", $health->{'tc-frozensize'} );
|
||||
printf( "rds.value %d\n", $health->{'rds'} );
|
||||
printf( "units.value %d\n", $health->{'units'} );
|
||||
|
@ -151,4 +148,4 @@ sub getJson( $ ) {
|
|||
die( sprintf( "Could not decode json from '%s'.", $url ) );
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,8 +66,20 @@ my $wgetBin = "/usr/bin/wget";
|
|||
my $type = basename($0);
|
||||
$type =~ s/jenkins_//;
|
||||
|
||||
my %states = ('blue' =>'stable', 'blue_anime' =>'stable', 'yellow'=>'unstable', 'yellow_anime'=>'unstable', 'red'=>'failing', 'red_anime'=>'failing', 'disabled'=>'disabled', 'notbuilt_anime' =>'disabled', 'aborted'=>'failing', 'aborted_anime'=>'failing' );
|
||||
my %counts = ('blue' => 0, 'yellow'=>0, 'red'=>0, 'disabled'=>0);
|
||||
my %states = (
|
||||
'blue' =>'stable',
|
||||
'blue_anime' =>'stable',
|
||||
'yellow'=>'unstable',
|
||||
'yellow_anime'=>'unstable',
|
||||
'red'=>'failing',
|
||||
'red_anime'=>'failing',
|
||||
'disabled'=>'disabled',
|
||||
'notbuilt' => 'disabled',
|
||||
'notbuilt_anime' =>'disabled',
|
||||
'aborted'=>'failing',
|
||||
'aborted_anime'=>'failing'
|
||||
);
|
||||
my %counts = ('stable' => 0, 'unstable'=>0, 'failing'=>0, 'disabled'=>0);
|
||||
|
||||
if ( exists $ARGV[0] and $ARGV[0] eq "config" ) {
|
||||
if( $type eq "results" ) {
|
||||
|
@ -123,11 +135,15 @@ if ( exists $ARGV[0] and $ARGV[0] eq "config" ) {
|
|||
my $result = `$cmd/api/json`;
|
||||
my $parsed = decode_json($result);
|
||||
foreach my $cur(@{$parsed->{'jobs'}}) {
|
||||
$counts{$cur->{'color'}} += 1;
|
||||
if (defined $states{$cur->{'color'}}) {
|
||||
$counts{$states{$cur->{'color'}}} += 1;
|
||||
} else {
|
||||
warn "Ignoring unknown color " . $cur->{'color'} . "\n"
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $status (keys %counts) {
|
||||
print "build_$states{$status}.value $counts{$status}\n";
|
||||
print "build_$status.value $counts{$status}\n";
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
|
48
plugins/lxd/lxd_disk
Executable file
48
plugins/lxd/lxd_disk
Executable file
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
|
||||
errors=[]
|
||||
|
||||
HAS_LIB=True
|
||||
try:
|
||||
from pylxd import api
|
||||
except:
|
||||
HAS_LIB=False
|
||||
errors.append("no pylxd module")
|
||||
|
||||
c=None
|
||||
HAS_ACCESS=True
|
||||
try:
|
||||
c=api.API()
|
||||
c.container_list()
|
||||
except:
|
||||
HAS_ACCESS=False
|
||||
errors.append("no socket access")
|
||||
|
||||
if len(sys.argv) == 2 and sys.argv[1]=="autoconf":
|
||||
if HAS_LIB and HAS_ACCESS:
|
||||
print("yes")
|
||||
else:
|
||||
print("no ("+" and ".join(errors)+")")
|
||||
sys.exit(0)
|
||||
|
||||
if not (HAS_LIB and HAS_ACCESS):
|
||||
# pylxd not installed or lxd socket not accessible
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) == 2 and sys.argv[1]=="config":
|
||||
print("graph_title LXD container disk usage")
|
||||
print("graph_args --base 1000 --lower-limit 0")
|
||||
print("graph_vlabel Bytes")
|
||||
print("graph_category lxd")
|
||||
print("graph_info This shows the disk usage of storage in containers. Make sure to install pylxd in python3.")
|
||||
for name in c.container_list():
|
||||
for disk in c.container_info(name)['disk']:
|
||||
print(name+"-"+disk+".label "+name)
|
||||
print(name+"-"+disk+".draw LINE2")
|
||||
sys.exit(0)
|
||||
|
||||
for name in c.container_list():
|
||||
for disk in c.container_info(name)['disk']:
|
||||
print(name+"-"+disk+".value "+str(c.container_info(name)['disk'][disk]['usage']))
|
46
plugins/lxd/lxd_mem
Executable file
46
plugins/lxd/lxd_mem
Executable file
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
|
||||
errors=[]
|
||||
|
||||
HAS_LIB=True
|
||||
try:
|
||||
from pylxd import api
|
||||
except:
|
||||
HAS_LIB=False
|
||||
errors.append("no pylxd module")
|
||||
|
||||
c=None
|
||||
HAS_ACCESS=True
|
||||
try:
|
||||
c=api.API()
|
||||
c.container_list()
|
||||
except:
|
||||
HAS_ACCESS=False
|
||||
errors.append("no socket access")
|
||||
|
||||
if len(sys.argv) == 2 and sys.argv[1]=="autoconf":
|
||||
if HAS_LIB and HAS_ACCESS:
|
||||
print("yes")
|
||||
else:
|
||||
print("no ("+" and ".join(errors)+")")
|
||||
sys.exit(0)
|
||||
|
||||
if not (HAS_LIB and HAS_ACCESS):
|
||||
# pylxd not installed or lxd socket not accessible
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) == 2 and sys.argv[1]=="config":
|
||||
print("graph_title LXD container memory")
|
||||
print("graph_args --base 1024 --lower-limit 0")
|
||||
print("graph_vlabel Bytes")
|
||||
print("graph_category lxd")
|
||||
print("graph_info This shows the memory usage of each container. Make sure to install pylxd in python3.")
|
||||
for name in c.container_list():
|
||||
print(name+".label "+name)
|
||||
print(name+".draw AREASTACK")
|
||||
sys.exit(0)
|
||||
|
||||
for name in c.container_list():
|
||||
print(name+".value "+str(c.container_info(name)['memory']['usage']))
|
88
plugins/mail/policyd-spf-python
Executable file
88
plugins/mail/policyd-spf-python
Executable file
|
@ -0,0 +1,88 @@
|
|||
#! /bin/bash
|
||||
#
|
||||
# Munin plugin to monitor postfix-policyd-spf-python results
|
||||
# Contributed by Alexander Koch <lynix47@gmail.com>
|
||||
#
|
||||
# This plugin is published under the terms of the MIT License.
|
||||
#
|
||||
# Parameters understood:
|
||||
# config (required)
|
||||
# autoconf (optional - used by munin-config)
|
||||
#
|
||||
# Config variables:
|
||||
# logfile - Where to find the postfix log (mail.log)
|
||||
#
|
||||
# Add the following line to a file in /etc/munin/plugin-conf.d:
|
||||
# env.logfile /var/log/your/mail.log
|
||||
#
|
||||
# Magic markers (optional - used by munin-config and installation scripts):
|
||||
#
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
|
||||
|
||||
#
|
||||
# Configuration
|
||||
#
|
||||
|
||||
STAT_FILE=${STAT_FILE:-/var/lib/munin/plugin-state/plugin-plcyd-spf-python.state}
|
||||
LOGFILE=${logfile:-/var/log/mail.log}
|
||||
|
||||
if [ "$1" = "autoconf" ]; then
|
||||
echo yes
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "config" ]; then
|
||||
echo 'graph_title SPF Check Results'
|
||||
echo 'graph_category postfix'
|
||||
echo 'graph_args --base 1000 -l 0'
|
||||
echo 'graph_vlabel Count/s'
|
||||
|
||||
echo 'count_pass.label Pass'
|
||||
echo 'count_pass.type DERIVE'
|
||||
echo 'count_pass.min 0'
|
||||
echo 'count_pass.colour 00cc00'
|
||||
echo 'count_fail.label Fail'
|
||||
echo 'count_fail.type DERIVE'
|
||||
echo 'count_fail.min 0'
|
||||
echo 'count_fail.colour cc0000'
|
||||
echo 'count_none.label None'
|
||||
echo 'count_none.type DERIVE'
|
||||
echo 'count_none.min 0'
|
||||
echo 'count_none.colour 0066b3'
|
||||
echo 'count_temperror.label Temperror'
|
||||
echo 'count_temperror.type DERIVE'
|
||||
echo 'count_temperror.min 0'
|
||||
echo 'count_temperror.colour ff8000'
|
||||
echo 'count_neutral.label Neutral'
|
||||
echo 'count_neutral.type DERIVE'
|
||||
echo 'count_neutral.min 0'
|
||||
echo 'count_neutral.colour ffcc00'
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# Log parsing
|
||||
#
|
||||
|
||||
function get_log_count() {
|
||||
egrep "policyd-spf\[[0-9]+\]: $1;" "$LOGFILE" | grep "$(date '+%b %e')" | wc -l
|
||||
}
|
||||
|
||||
PASS=$(get_log_count "Pass")
|
||||
FAIL=$(get_log_count "Fail")
|
||||
NONE=$(get_log_count "None")
|
||||
TEMPERR=$(get_log_count "Temperror")
|
||||
NEUTRAL=$(get_log_count "Neutral")
|
||||
|
||||
echo "count_pass.value $PASS"
|
||||
echo "count_fail.value $FAIL"
|
||||
echo "count_none.value $NONE"
|
||||
echo "count_temperror.value $TEMPERR"
|
||||
echo "count_neutral.value $NEUTRAL"
|
||||
|
||||
|
||||
exit 0
|
57
plugins/memcached_ext/memcached_ext_bytes_
Executable file
57
plugins/memcached_ext/memcached_ext_bytes_
Executable file
|
@ -0,0 +1,57 @@
|
|||
#!/usr/bin/env perl
|
||||
# ex:ts=4
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cache::Memcached;
|
||||
|
||||
# Based on original plugin, extended to unix socket use
|
||||
# https://github.com/western, westroads@gmail.com
|
||||
|
||||
=head1 example config for /plugin-conf.d/munin-node
|
||||
|
||||
[memcached_bytes_1]
|
||||
env.server 127.0.0.1:11211
|
||||
env.label "first local server"
|
||||
|
||||
[memcached_bytes_2]
|
||||
env.server /var/run/memcached/memcached.sock
|
||||
env.label "second local server"
|
||||
|
||||
=cut
|
||||
|
||||
my $label = exists $ENV{'label'} ? $ENV{'label'} : '';
|
||||
unless( $label ){
|
||||
|
||||
if( $0 =~ /memcached_ext_bytes_([\d\w]+)$/ ){
|
||||
$label = $1;
|
||||
}
|
||||
}
|
||||
|
||||
my $cmd = shift || '';
|
||||
if ($cmd eq 'config') {
|
||||
print "graph_title Memcached bytes used on $label\n";
|
||||
print "graph_args --base 1024 -l 0\n";
|
||||
print "graph_vlabel bytes\n";
|
||||
print "graph_category memcached\n";
|
||||
print "graph_info This graph monitors the size of the memcached cache.\n";
|
||||
print "bytes.label bytes used\n";
|
||||
print "bytes.info Number of bytes currently used\n";
|
||||
print "bytes.min 0\n";
|
||||
print "bytes.draw AREA\n";
|
||||
print "maxbytes.label maximum available\n";
|
||||
print "maxbytes.info The configured cache size\n";
|
||||
print "maxbytes.min 0\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
|
||||
my $server = exists $ENV{'server'} ? $ENV{'server'} : '127.0.0.1:11211';
|
||||
|
||||
my $memd = new Cache::Memcached { 'servers' => [$server] };
|
||||
my $memstats = $memd->stats(['misc']);
|
||||
|
||||
print "bytes.value " . $memstats->{hosts}->{$server}->{misc}->{bytes} . "\n";
|
||||
print "maxbytes.value " .
|
||||
$memstats->{hosts}->{$server}->{misc}->{limit_maxbytes} . "\n";
|
53
plugins/memcached_ext/memcached_ext_connections_
Executable file
53
plugins/memcached_ext/memcached_ext_connections_
Executable file
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env perl
|
||||
# ex:ts=4
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cache::Memcached;
|
||||
|
||||
# Based on original plugin, extended to unix socket use
|
||||
# https://github.com/western, westroads@gmail.com
|
||||
|
||||
=head1 example config for /plugin-conf.d/munin-node
|
||||
|
||||
[memcached_connections_1]
|
||||
env.server 127.0.0.1:11211
|
||||
env.label "first local server"
|
||||
|
||||
[memcached_connections_2]
|
||||
env.server /var/run/memcached/memcached.sock
|
||||
env.label "second local server"
|
||||
|
||||
=cut
|
||||
|
||||
my $label = exists $ENV{'label'} ? $ENV{'label'} : '';
|
||||
unless( $label ){
|
||||
|
||||
if( $0 =~ /memcached_ext_connections_([\w\d]+)$/ ){
|
||||
$label = $1;
|
||||
}
|
||||
}
|
||||
|
||||
my $cmd = shift || '';
|
||||
if ($cmd eq 'config') {
|
||||
print "graph_title Memcached connections on $label\n";
|
||||
print "graph_args --base 1000 -l 0\n";
|
||||
print "graph_vlabel connections\n";
|
||||
print "graph_category memcached\n";
|
||||
print "graph_info This graph monitors the connections to the memcached server.\n";
|
||||
print "connections.label connections\n";
|
||||
print "connections.info Number of connections to memcached\n";
|
||||
print "connections.min 0\n";
|
||||
print "connections.draw AREA\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
|
||||
my $server = exists $ENV{'server'} ? $ENV{'server'} : '127.0.0.1:11211';
|
||||
|
||||
my $memd = new Cache::Memcached { 'servers' => [$server] };
|
||||
my $memstats = $memd->stats(['misc']);
|
||||
|
||||
print "connections.value " .
|
||||
$memstats->{hosts}->{$server}->{misc}->{curr_connections} . "\n";
|
60
plugins/memcached_ext/memcached_ext_hits_
Executable file
60
plugins/memcached_ext/memcached_ext_hits_
Executable file
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/env perl
|
||||
# ex:ts=4
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cache::Memcached;
|
||||
|
||||
# Based on original plugin, extended to unix socket use
|
||||
# https://github.com/western, westroads@gmail.com
|
||||
|
||||
=head1 example config for /plugin-conf.d/munin-node
|
||||
|
||||
[memcached_hits_1]
|
||||
env.server 127.0.0.1:11211
|
||||
env.label "first local server"
|
||||
|
||||
[memcached_hits_2]
|
||||
env.server /var/run/memcached/memcached.sock
|
||||
env.label "second local server"
|
||||
|
||||
=cut
|
||||
|
||||
my $label = exists $ENV{'label'} ? $ENV{'label'} : '';
|
||||
unless( $label ){
|
||||
|
||||
if( $0 =~ /memcached_ext_hits_([\w\d]+)$/ ){
|
||||
$label = $1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
my $cmd = shift || '';
|
||||
if ($cmd eq 'config') {
|
||||
print "graph_title Memcached cache hits and misses on $label\n";
|
||||
print "graph_args --base 1000 -l 0\n";
|
||||
print "graph_vlabel requests\n";
|
||||
print "graph_category memcached\n";
|
||||
print "graph_info This graph monitors the number of cache hits and misses.\n";
|
||||
print "hits.label hits\n";
|
||||
print "hits.info Number of cache hits\n";
|
||||
print "hits.min 0\n";
|
||||
print "hits.type DERIVE\n";
|
||||
print "misses.label misses\n";
|
||||
print "misses.info Number of cache misses\n";
|
||||
print "misses.min 0\n";
|
||||
print "misses.type DERIVE\n";
|
||||
print "misses.draw AREA\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $server = exists $ENV{'server'} ? $ENV{'server'} : '127.0.0.1:11211';
|
||||
|
||||
my $memd = new Cache::Memcached { 'servers' => [$server] };
|
||||
my $memstats = $memd->stats(['misc']);
|
||||
|
||||
print "hits.value " . $memstats->{hosts}->{$server}->{misc}->{get_hits} . "\n";
|
||||
print "misses.value " .
|
||||
$memstats->{hosts}->{$server}->{misc}->{get_misses} . "\n";
|
53
plugins/memcached_ext/memcached_ext_items_
Executable file
53
plugins/memcached_ext/memcached_ext_items_
Executable file
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env perl
|
||||
# ex:ts=4
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cache::Memcached;
|
||||
|
||||
# Based on original plugin, extended to unix socket use
|
||||
# https://github.com/western, westroads@gmail.com
|
||||
|
||||
=head1 example config for /plugin-conf.d/munin-node
|
||||
|
||||
[memcached_items_1]
|
||||
env.server 127.0.0.1:11211
|
||||
env.label "first local server"
|
||||
|
||||
[memcached_items_2]
|
||||
env.server /var/run/memcached/memcached.sock
|
||||
env.label "second local server"
|
||||
|
||||
=cut
|
||||
|
||||
my $label = exists $ENV{'label'} ? $ENV{'label'} : '';
|
||||
unless( $label ){
|
||||
|
||||
if( $0 =~ /memcached_ext_items_([\w\d]+)$/ ){
|
||||
$label = $1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $cmd = shift || '';
|
||||
if ($cmd eq 'config') {
|
||||
print "graph_title Memcached cached items on $label\n";
|
||||
print "graph_args --base 1000 -l 0\n";
|
||||
print "graph_vlabel items\n";
|
||||
print "graph_category memcached\n";
|
||||
print "graph_info This graph monitors the number of items stored by the memcached server.\n";
|
||||
print "items.label items\n";
|
||||
print "items.info Number of cached items\n";
|
||||
print "items.min 0\n";
|
||||
print "items.draw AREA\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $server = exists $ENV{'server'} ? $ENV{'server'} : '127.0.0.1:11211';
|
||||
|
||||
my $memd = new Cache::Memcached { 'servers' => [$server] };
|
||||
my $memstats = $memd->stats(['misc']);
|
||||
|
||||
print "items.value " .
|
||||
$memstats->{hosts}->{$server}->{misc}->{curr_items} . "\n";
|
59
plugins/memcached_ext/memcached_ext_requests_
Executable file
59
plugins/memcached_ext/memcached_ext_requests_
Executable file
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env perl
|
||||
# ex:ts=4
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cache::Memcached;
|
||||
|
||||
# Based on original plugin, extended to unix socket use
|
||||
# https://github.com/western, westroads@gmail.com
|
||||
|
||||
=head1 example config for /plugin-conf.d/munin-node
|
||||
|
||||
[memcached_requests_1]
|
||||
env.server 127.0.0.1:11211
|
||||
env.label "first local server"
|
||||
|
||||
[memcached_requests_2]
|
||||
env.server /var/run/memcached/memcached.sock
|
||||
env.label "second local server"
|
||||
|
||||
=cut
|
||||
|
||||
my $label = exists $ENV{'label'} ? $ENV{'label'} : '';
|
||||
unless( $label ){
|
||||
|
||||
if( $0 =~ /memcached_ext_requests_([\w\d]+)$/ ){
|
||||
$label = $1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $cmd = shift || '';
|
||||
if ($cmd eq 'config') {
|
||||
print "graph_title Memcached requests on $label\n";
|
||||
print "graph_args --base 1000 -l 0\n";
|
||||
print "graph_vlabel requests\n";
|
||||
print "graph_category memcached\n";
|
||||
print "graph_info This graph monitors the number of get and set requests.\n";
|
||||
print "gets.label gets\n";
|
||||
print "gets.info Number of get requests\n";
|
||||
print "gets.min 0\n";
|
||||
print "gets.type DERIVE\n";
|
||||
print "gets.draw AREA\n";
|
||||
print "sets.label sets\n";
|
||||
print "sets.info Number of set requests\n";
|
||||
print "sets.min 0\n";
|
||||
print "sets.type DERIVE\n";
|
||||
print "sets.draw STACK\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $server = exists $ENV{'server'} ? $ENV{'server'} : '127.0.0.1:11211';
|
||||
|
||||
my $memd = new Cache::Memcached { 'servers' => [$server] };
|
||||
my $memstats = $memd->stats(['misc']);
|
||||
|
||||
print "gets.value " . $memstats->{hosts}->{$server}->{misc}->{cmd_get} . "\n";
|
||||
print "sets.value " . $memstats->{hosts}->{$server}->{misc}->{cmd_set} . "\n";
|
60
plugins/memcached_ext/memcached_ext_traffic_
Executable file
60
plugins/memcached_ext/memcached_ext_traffic_
Executable file
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/env perl
|
||||
# ex:ts=4
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Cache::Memcached;
|
||||
|
||||
# Based on original plugin, extended to unix socket use
|
||||
# https://github.com/western, westroads@gmail.com
|
||||
|
||||
=head1 example config for /plugin-conf.d/munin-node
|
||||
|
||||
[memcached_traffic_1]
|
||||
env.server 127.0.0.1:11211
|
||||
env.label "first local server"
|
||||
|
||||
[memcached_traffic_2]
|
||||
env.server /var/run/memcached/memcached.sock
|
||||
env.label "second local server"
|
||||
|
||||
=cut
|
||||
|
||||
my $label = exists $ENV{'label'} ? $ENV{'label'} : '';
|
||||
unless( $label ){
|
||||
|
||||
if( $0 =~ /memcached_ext_traffic_([\w\d]+)$/ ){
|
||||
$label = $1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $cmd = shift || '';
|
||||
if ($cmd eq 'config') {
|
||||
print "graph_title Memcached network traffic on $label\n";
|
||||
print "graph_args --base 1000 -l 0\n";
|
||||
print "graph_vlabel bits per \${graph_period}\n";
|
||||
print "graph_category memcached\n";
|
||||
print "graph_info This graph monitors the network traffic of the memcached server.\n";
|
||||
print "up.label bits in\n";
|
||||
print "up.info Traffic received by memcached\n";
|
||||
print "up.min 0\n";
|
||||
print "up.cdef up,8,*\n";
|
||||
print "up.type COUNTER\n";
|
||||
print "up.draw AREA\n";
|
||||
print "down.label bits out\n";
|
||||
print "down.info Traffic sent by memcached\n";
|
||||
print "down.min 0\n";
|
||||
print "down.cdef down,8,*\n";
|
||||
print "down.type COUNTER\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $server = exists $ENV{'server'} ? $ENV{'server'} : '127.0.0.1:11211';
|
||||
|
||||
my $memd = new Cache::Memcached { 'servers' => [$server] };
|
||||
my $memstats = $memd->stats(['misc']);
|
||||
|
||||
print "up.value " . $memstats->{hosts}->{$server}->{misc}->{bytes_read} . "\n";
|
||||
print "down.value " . $memstats->{hosts}->{$server}->{misc}->{bytes_written} . "\n";
|
|
@ -54,6 +54,8 @@ if len(sys.argv) > 1 and sys.argv[1] == 'config':
|
|||
for process in procs:
|
||||
for stat in procs[process]:
|
||||
print "monit_%s_%s.label %s.%s" % (process, stat, process, stat)
|
||||
if stat == 'total_memory':
|
||||
print "monit_%s_%s.warning 1:" % (process, stat)
|
||||
sys.exit(0)
|
||||
|
||||
for process in procs:
|
||||
|
|
|
@ -81,7 +81,6 @@ if (count($argv) === 2 && $argv[1] === 'config') {
|
|||
echo "graph_args --base 1024 --lower-limit 0\n";
|
||||
echo "graph_vlabel size\n";
|
||||
echo "graph_category Moodle\n";
|
||||
echo "graph_scale no\n";
|
||||
echo "graph_total total\n";
|
||||
echo "graph_info Displays the total size of moodle users files and repartition by type\n";
|
||||
|
||||
|
@ -119,7 +118,6 @@ echo "graph_title Moodle Files Size\n";
|
|||
echo "graph_args --base 1024 --lower-limit 0\n";
|
||||
echo "graph_vlabel size\n";
|
||||
echo "graph_category Moodle\n";
|
||||
echo "graph_scale yes\n";
|
||||
echo "graph_total total\n";
|
||||
echo "graph_info Displays the total size of moodle users files and repartition by type\n";
|
||||
|
||||
|
|
54
plugins/network/arp_bsd_
Normal file
54
plugins/network/arp_bsd_
Normal file
|
@ -0,0 +1,54 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Wildcard-plugin to monitor arp on interfaces. To monitor an
|
||||
# interface, link arp_bsd_<interface> to this file. E.g.
|
||||
#
|
||||
# ln -s /usr/local/share/munin/plugins/arp_bsd_ /usr/local/etc/munin/plugins/arp_bsd_vlanX
|
||||
#
|
||||
# ...will monitor arp on interface vlanX.
|
||||
#
|
||||
# Any device found in /sbin/ifconfig can be monitored.
|
||||
#
|
||||
# Bugs : This plugins has been tested extensively on FreeBSD only
|
||||
#
|
||||
# Author : Luc Duchosal <luc.duchosal (at) arcantel (dot) ch>
|
||||
#
|
||||
# Magic markers (optional - used by munin-config and some installation
|
||||
# scripts):
|
||||
#
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf suggest
|
||||
|
||||
|
||||
INTERFACE=`basename $0 | sed 's/^arp_bsd_//g'`
|
||||
|
||||
if [ "$1" = "autoconf" ]; then
|
||||
if [ -x /sbin/ifconfig ]; then
|
||||
echo yes
|
||||
exit 0
|
||||
else
|
||||
echo "no (/sbin/ifconfig not found)"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "suggest" ]; then
|
||||
if [ -x /sbin/ifconfig ]; then
|
||||
/sbin/ifconfig -a | /usr/bin/grep -E '^[a-z]' | /usr/bin/awk -F\: '{print $1;}'
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "config" ]; then
|
||||
|
||||
echo "graph_title $INTERFACE arp"
|
||||
echo 'graph_args --base 1000'
|
||||
echo 'graph_vlabel arp per ${graph_period}'
|
||||
echo 'graph_category network'
|
||||
echo 'arp.label arp'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
/usr/sbin/arp -an | /usr/bin/grep $INTERFACE | /usr/bin/wc -l | /usr/bin/awk '{ print "arp.value", $1;}'
|
|
@ -1,15 +1,11 @@
|
|||
#! /bin/sh
|
||||
# Currently the plugin does *not* autostart
|
||||
#
|
||||
# It has to be launched via rc.d :
|
||||
# munin-run if1sec_eth0 acquire
|
||||
|
||||
pluginfull="$0" # full name of plugin
|
||||
plugin="${0##*/}" # name of plugin
|
||||
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
|
||||
IFACE="${0##*/if1sec_}" # interface
|
||||
|
||||
if [ ! -r "/sys/class/net/$IFACE/statistics/tx_bytes" ]
|
||||
then
|
||||
|
@ -19,44 +15,86 @@ 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
|
||||
(
|
||||
exec <&- >&- 2>&-
|
||||
while sleep 1
|
||||
do
|
||||
read tx < /sys/class/net/$IFACE/statistics/tx_bytes
|
||||
read rx < /sys/class/net/$IFACE/statistics/rx_bytes
|
||||
echo "$tx $rx"
|
||||
done | awk "{
|
||||
now = systime()
|
||||
print \"${IFACE}_tx.value \" now \":\" \$1
|
||||
print \"${IFACE}_rx.value \" now \":\" \$2
|
||||
system(\"\")
|
||||
}" >> $cache
|
||||
) &
|
||||
echo $! > $pidfile
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
if [ "$1" = "config" ]
|
||||
then
|
||||
cat <<EOF
|
||||
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
|
||||
graph_category network
|
||||
graph_data_size custom 1d, 10s for 1w, 1m for 1t, 5m for 450d
|
||||
graph_vlabel bits/sec
|
||||
update_rate 1
|
||||
${IFACE}_tx.label ${IFACE} TX bytes
|
||||
${IFACE}_tx.label ${IFACE} TX bits
|
||||
${IFACE}_tx.cdef ${IFACE}_tx,8,*
|
||||
${IFACE}_tx.type DERIVE
|
||||
${IFACE}_tx.min 0
|
||||
${IFACE}_rx.label ${IFACE} RX bytes
|
||||
${IFACE}_rx.label ${IFACE} RX bits
|
||||
${IFACE}_rx.cdef ${IFACE}_rx,8,*
|
||||
${IFACE}_rx.type DERIVE
|
||||
${IFACE}_rx.min 0
|
||||
EOF
|
||||
exit 0
|
||||
# If max speed is easily available, report it. More complex
|
||||
# code could be copied from "if_".
|
||||
if [ -r /sys/class/net/$IFACE/speed ]
|
||||
then
|
||||
SPEED=$(cat /sys/class/net/$IFACE/speed)
|
||||
echo "${IFACE}_rx.max" $((SPEED / 8 * 1000000))
|
||||
echo "${IFACE}_tx.max" $((SPEED / 8 * 1000000))
|
||||
echo "${IFACE}_rx.info Received traffic on the $IFACE interface. Maximum speed is ${SPEED} Mbps."
|
||||
echo "${IFACE}_tx.info Transmitted traffic on the $IFACE interface. Maximum speed ${SPEED} Mbps."
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# values
|
||||
# Autorun logic
|
||||
running=true
|
||||
if [ ! -e ${cache} ]
|
||||
then
|
||||
# no cache file
|
||||
running=false
|
||||
elif [ ! -s ${cache} ]
|
||||
then
|
||||
# empty cache file
|
||||
if [ -s ${pidfile} ]
|
||||
then
|
||||
# kill -0 will return success if this user is allowed to send
|
||||
# a signal to the process. This means the PID exists and
|
||||
# belongs to the plugin user, which should have few false
|
||||
# positives.
|
||||
if ! kill -0 $(cat ${pidfile})
|
||||
then
|
||||
running=false
|
||||
fi
|
||||
else
|
||||
running=false
|
||||
fi
|
||||
fi
|
||||
if ! $running
|
||||
then
|
||||
$0 acquire &
|
||||
# wait a little so we have some data to report
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
# Finally: Print collected values, truncate to mark spot.
|
||||
cat ${cache}
|
||||
> ${cache}
|
||||
|
||||
|
|
252
plugins/network/pf_tables_
Normal file
252
plugins/network/pf_tables_
Normal file
|
@ -0,0 +1,252 @@
|
|||
#!/usr/bin/perl -w
|
||||
# -*- perl -*-
|
||||
|
||||
=head1 NAME
|
||||
|
||||
pf_tables : Munin plugin to monitor pf tables.
|
||||
Inout: bandwidth usage for table
|
||||
Addresses: number of entries in table
|
||||
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Should work on any BSD that has pf(4).
|
||||
|
||||
Examples:
|
||||
|
||||
=over
|
||||
|
||||
=item pf_tables_inout_tablename
|
||||
|
||||
=item pf_tables_addresses_authenticated
|
||||
|
||||
=item pf_tables_addresses_badboys
|
||||
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
[pf_tables_*]
|
||||
user root
|
||||
|
||||
=head1 INTERPRETATION
|
||||
|
||||
The plugin simply runs the pfctl -sTables -vvv command and counts the number of
|
||||
Addresses and InBytes/OutBytes in each table.
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
Only tested extensively on FreeBSD.
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf suggest
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
$Id$
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2015.
|
||||
|
||||
Original version by Luc Duchosal (at) arcantel (dot) ch.
|
||||
Created by Luc Duchosal, 2015
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
BSD
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
use strict;
|
||||
use Munin::Plugin;
|
||||
|
||||
$0 =~ /pf_tables_(addresses|inout)_(.+)$/;
|
||||
my $name = $2;
|
||||
my $operation = $1;
|
||||
|
||||
if ( defined($ARGV[0])) {
|
||||
if ($ARGV[0] eq 'autoconf') {
|
||||
print "yes\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if ($ARGV[0] eq "config") {
|
||||
|
||||
if (!defined($name)) {
|
||||
print "Unknown table\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if (!defined($operation)) {
|
||||
print "Unknown operation\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if ($operation =~ m/addresses/) {
|
||||
|
||||
print "graph_title Connected users ($name)\n";
|
||||
print "graph_args --base 1000 -l 0\n";
|
||||
print "graph_vlabel Users\n";
|
||||
print "graph_scale no\n";
|
||||
print "graph_category pf\n";
|
||||
print "graph_printf %3.0lf\n";
|
||||
|
||||
print "users.label users\n";
|
||||
print "users.draw AREASTACK\n";
|
||||
print "users.colour 00C000\n";
|
||||
foreach my $field (qw(users)) {
|
||||
print_thresholds($field);
|
||||
}
|
||||
}
|
||||
|
||||
if ($operation =~ m/inout/) {
|
||||
|
||||
print "graph_title Network bandwidth ($name)\n";
|
||||
print "graph_args --base 1024 -l 0\n";
|
||||
print "graph_vlabel Bandwidth\n";
|
||||
print "graph_scale yes\n";
|
||||
print "graph_category pf\n";
|
||||
# print "graph_printf %3.0lf\n";
|
||||
|
||||
print "in.label in\n";
|
||||
print "in.type DERIVE\n";
|
||||
print "in.draw AREASTACK\n";
|
||||
print "in.colour C00000\n";
|
||||
print "in.cdef in,8,*\n";
|
||||
print "in.min 0\n";
|
||||
print "in.graph no\n";
|
||||
print "out.label out\n";
|
||||
print "out.type DERIVE\n";
|
||||
print "out.negative in\n";
|
||||
print "out.draw AREASTACK\n";
|
||||
print "out.colour 0000C0\n";
|
||||
print "out.cdef out,8,*\n";
|
||||
print "out.min 0\n";
|
||||
print "out.graph no\n";
|
||||
|
||||
foreach my $field (qw(in out)) {
|
||||
print_thresholds($field);
|
||||
}
|
||||
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if ($ARGV[0] eq "suggest") {
|
||||
my %tables = &tables();
|
||||
foreach my $key (keys(%tables)) {
|
||||
print "addresses_$key\n";
|
||||
print "inout_$key\n";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!defined($name)) {
|
||||
print "Usage: pf_tables_addresses_tablename or pf_tables_inout_tablename\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my %tables = &tables();
|
||||
if (!exists $tables{$name}) {
|
||||
print "Unknown table name $name\n";
|
||||
exit 2;
|
||||
}
|
||||
|
||||
if ($operation =~ m/addresses/) {
|
||||
my $users = $tables{$name}->{"addresses"};
|
||||
print "users.value $users\n";
|
||||
}
|
||||
|
||||
if ($operation =~ m/inout/) {
|
||||
my $in = $tables{$name}->{"inpassbytes"};
|
||||
my $out = $tables{$name}->{"outpassbytes"};
|
||||
print "in.value $in\n";
|
||||
print "out.value $out\n";
|
||||
}
|
||||
|
||||
|
||||
sub tables {
|
||||
|
||||
# # pfctl -s Tables -vv
|
||||
# -pa-r-- auth
|
||||
# Addresses: 0
|
||||
# Cleared: Fri Sep 18 17:34:42 2015
|
||||
# References: [ Anchors: 0 Rules: 14 ]
|
||||
# Evaluations: [ NoMatch: 43624 Match: 788 ]
|
||||
# In/Block: [ Packets: 0 Bytes: 0 ]
|
||||
# In/Pass: [ Packets: 30908 Bytes: 2704516 ]
|
||||
# In/XPass: [ Packets: 124 Bytes: 7897 ]
|
||||
# Out/Block: [ Packets: 0 Bytes: 0 ]
|
||||
# Out/Pass: [ Packets: 30288 Bytes: 26313114 ]
|
||||
# Out/XPass: [ Packets: 89 Bytes: 21166 ]
|
||||
|
||||
my $output = `/sbin/pfctl -s Tables -vv 2> /dev/null`;
|
||||
my %tables;
|
||||
my $name;
|
||||
|
||||
foreach (split(/\n/, $output)) {
|
||||
|
||||
if (m|^[cpairhC\-]{7}\s+(\w+)$|) {
|
||||
$name = $1;
|
||||
$tables{$name}->{"name"} = $1;
|
||||
next;
|
||||
}
|
||||
|
||||
if (m|Addresses:\s+([0-9]+)$|) {
|
||||
$tables{$name}->{"addresses"} = $1;
|
||||
next;
|
||||
}
|
||||
|
||||
if (m|Cleared:\s+(.+)$|) {
|
||||
$tables{$name}->{"cleared"} = $1;
|
||||
next;
|
||||
}
|
||||
|
||||
if (m|In/Block:\s+\[\s+Packets:\s+([0-9]+)\s+Bytes:\s+([0-9]+)\s+\]$|) {
|
||||
$tables{$name}->{"inblockpackets"} = $1;
|
||||
$tables{$name}->{"inblockbytes"} = $2;
|
||||
next;
|
||||
}
|
||||
|
||||
if (m|In/Pass:\s+\[\s+Packets:\s+([0-9]+)\s+Bytes:\s+([0-9]+)\s+\]$|) {
|
||||
$tables{$name}->{"inpasspackets"} = $1;
|
||||
$tables{$name}->{"inpassbytes"} = $2;
|
||||
next;
|
||||
}
|
||||
|
||||
if (m|In/XPass:\s+\[\s+Packets:\s+([0-9]+)\s+Bytes:\s+([0-9]+)\s+\]$|) {
|
||||
$tables{$name}->{"inxpasspackets"} = $1;
|
||||
$tables{$name}->{"inxpassbytes"} = $2;
|
||||
next;
|
||||
}
|
||||
|
||||
if (m|Out/Block:\s+\[\s+Packets:\s+([0-9]+)\s+Bytes:\s+([0-9]+)\s+\]$|) {
|
||||
$tables{$name}->{"outblockpackets"} = $1;
|
||||
$tables{$name}->{"outblockbytes"} = $2;
|
||||
next;
|
||||
}
|
||||
|
||||
if (m|Out/Pass:\s+\[\s+Packets:\s+([0-9]+)\s+Bytes:\s+([0-9]+)\s+\]$|) {
|
||||
$tables{$name}->{"outpasspackets"} = $1;
|
||||
$tables{$name}->{"outpassbytes"} = $2;
|
||||
next;
|
||||
}
|
||||
|
||||
if (m|Out/XPass:\s+\[\s+Packets:\s+([0-9]+)\s+Bytes:\s+([0-9]+)\s+\]$|) {
|
||||
$tables{$name}->{"outxpasspackets"} = $1;
|
||||
$tables{$name}->{"outxpassbytes"} = $2;
|
||||
next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return %tables;
|
||||
|
||||
}
|
||||
|
||||
# vim:syntax=perl
|
|
@ -1,155 +1,140 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
/*
|
||||
Plugin: radio
|
||||
Author: Philipp Giebel (spam@stimpyrama.org)
|
||||
Version: 0.1
|
||||
|
||||
Munin (http://munin.projects.linpro.no/) Plugin for counting
|
||||
listeners to both shout- and icecast streams.
|
||||
|
||||
Requirements: * PHP (jap, I know that sucks.. ;) )
|
||||
Plugin: radio
|
||||
Author: Philipp Giebel (spam@stimpyrama.org)
|
||||
Version: 0.2
|
||||
Munin (http://munin-monitoring.org/) Plugin for counting
|
||||
listeners to both shout- and icecast streams.
|
||||
Get the latest version at:
|
||||
http://munin-monitoring.org/log/munin-contrib/plugins/network/radio
|
||||
Requirements: * PHP (jap, I know that sucks.. ;) )
|
||||
CHANGELOG
|
||||
v0.1 - Quick & Dirty proof of concept
|
||||
v0.2 - Updated to match output of current versions of ice- and shoutcast.
|
||||
*/
|
||||
|
||||
// -------------- CONFIGURATION START ---------------------------------------------------------------
|
||||
|
||||
$cfg = array(
|
||||
// SERVER #1
|
||||
array( "type" => "ice", // server-type (ice/shout)
|
||||
"host" => "192.168.1.5", // server hostname or ip
|
||||
"port" => 8000, // server port
|
||||
"mountpoint" => "eclectix.mp3", // mountpoint to check (icecast only)
|
||||
"name" => "IceCast" // name for use in munin graphs
|
||||
),
|
||||
// SERVER #2
|
||||
array( "type" => "shout", // server-type
|
||||
"host" => "radio.eclectix.de", // server hostname or ip
|
||||
"port" => 8000, // server port
|
||||
"name" => "ShoutCast" // name for use in munin graphs
|
||||
)
|
||||
);
|
||||
|
||||
// -------------- CONFIGURATION END ----------------------------------------------------------------
|
||||
|
||||
function getIce( $host, $port, $mount, $name ) {
|
||||
$error = false;
|
||||
$fp = fsockopen( $host, $port, $errno, $errstr, 10 );
|
||||
if ( !$fp ) {
|
||||
$error = $errstr ."(". $errno .")";
|
||||
} else {
|
||||
fputs( $fp, "GET /status HTTP/1.1\r\n" );
|
||||
fputs( $fp, "Host: ". $host ."\r\n" );
|
||||
fputs($fp, "User-Agent: Mozilla\r\n");
|
||||
fputs( $fp, "Connection: close\r\n\r\n" );
|
||||
|
||||
$xml = "";
|
||||
|
||||
while ( !feof( $fp ) ) {
|
||||
$xml .= fgets( $fp, 512 );
|
||||
}
|
||||
|
||||
fclose($fp);
|
||||
|
||||
if ( stristr( $xml, "HTTP/1.0 200 OK" ) == true ) {
|
||||
$xml = trim( substr( $xml, 42 ) );
|
||||
} else {
|
||||
$error = "Bad login";
|
||||
}
|
||||
if ( !$error ) {
|
||||
$res = array( "found" => true );
|
||||
|
||||
$mount = str_replace( ".", "\.", $mount );
|
||||
preg_match_all( "/Mount Point : \(\/(". $mount .")\).*?\<tr\>\<td\>Current Listeners:\<\/td\>\<td class=\"streamdata\"\>(\d*?)\<\/td\>\<\/tr\><tr>\<td\>Peak Listeners:\<\/td\>\<td class=\"streamdata\"\>(\d*?)\<\/td\>\<\/tr\>/s", $xml, $parser );
|
||||
|
||||
$res["mount"] = $parser[1][0];
|
||||
$res["listeners"] = $parser[2][0];
|
||||
$res["listeners_peak"] = $parser[3][0];
|
||||
$res["name"] = $name;
|
||||
} else {
|
||||
$res = $error;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
function getShout( $host, $port, $name ) {
|
||||
$error = false;
|
||||
$fp = fsockopen( $host, $port, $errno, $errstr, 10 );
|
||||
if ( !$fp ) {
|
||||
$error = $errstr ."(". $errno .")";
|
||||
} else {
|
||||
fputs( $fp, "GET / HTTP/1.0\r\n" );
|
||||
fputs($fp, "User-Agent: Mozilla\r\n");
|
||||
fputs( $fp, "Connection: close\r\n\r\n" );
|
||||
|
||||
$xml = "";
|
||||
|
||||
while ( !feof( $fp ) ) {
|
||||
$xml .= fgets($fp, 512);
|
||||
}
|
||||
fclose( $fp );
|
||||
|
||||
if ( stristr( $xml, "HTTP/1.0 200 OK" ) == true ) {
|
||||
$xml = trim( substr( $xml, 42 ) );
|
||||
} else {
|
||||
$error = "Bad login";
|
||||
}
|
||||
if ( !$error ) {
|
||||
$res = array( "found" => true );
|
||||
|
||||
preg_match_all( "/.*?Stream Status: \<\/font\>\<\/td\>\<td\>\<font class=default\>\<b\>Stream is up at \d*? kbps with \<B\>(\d*?) of \d*? listeners \(\d*? unique\)\<\/b\>\<\/b\>/s", $xml, $parser );
|
||||
|
||||
$res["listeners"] = $parser[1][0];
|
||||
$res["name"] = $name;
|
||||
|
||||
} else {
|
||||
$res = $error;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
// -------------- CONFIGURATION START ---------------------------------------
|
||||
$cfg = array(
|
||||
// SERVER #1
|
||||
array( "name" => "IceCast", // name for munin
|
||||
"type" => "ice", // server-type (ice/shout)
|
||||
"host" => "ice.example.com", // server hostname or ip
|
||||
"port" => 8000, // server port
|
||||
"mountpoint" => "live" // mountpoint to check
|
||||
// (icecast only)
|
||||
),
|
||||
// SERVER #2
|
||||
array( "name" => "ShoutCast", // name for munin
|
||||
"type" => "shout", // server-type
|
||||
"host" => "127.0.0.1", // server hostname or ip
|
||||
"port" => 8000 // server port
|
||||
)
|
||||
);
|
||||
// -------------- CONFIGURATION END -----------------------------------------
|
||||
error_reporting(E_ERROR);
|
||||
function getIce( $host, $port, $mount, $name ) {
|
||||
$error = false;
|
||||
if ( !$fp = fsockopen( $host, $port, $errno, $errstr, 10 ) ) {
|
||||
$error = $errstr ."(". $errno .")";
|
||||
} else {
|
||||
fputs( $fp, "GET /status.xsl HTTP/1.1\r\n" );
|
||||
fputs( $fp, "Host: ". $host ."\r\n" );
|
||||
fputs( $fp, "User-Agent: Mozilla\r\n" );
|
||||
fputs( $fp, "Connection: close\r\n\r\n" );
|
||||
$xml = "";
|
||||
while ( !feof( $fp ) ) {
|
||||
$xml .= fgets( $fp, 512 );
|
||||
}
|
||||
fclose( $fp );
|
||||
if ( stristr( $xml, "HTTP/1.0 200 OK" ) == true ) {
|
||||
$xml = trim( substr( $xml, 42 ) );
|
||||
} else {
|
||||
$error = "Bad login";
|
||||
}
|
||||
if ( !$error ) {
|
||||
$res = array( "found" => true );
|
||||
$mount = str_replace( ".", "\.", $mount );
|
||||
preg_match_all( "/Mount Point \/(". $mount .").*?\<tr\>\<td\>Current Listeners:\<\/td\>\<td class=\"streamdata\"\>(\d*?)\<\/td\>\<\/tr\><tr>\<td\>Peak Listeners:\<\/td\>\<td class=\"streamdata\"\>(\d*?)\<\/td\>\<\/tr\>/s", $xml, $parser );
|
||||
$res["mount"] = $parser[1][0];
|
||||
$res["listeners"] = intval( $parser[2][0] );
|
||||
$res["listeners_peak"] = intval( $parser[3][0] );
|
||||
$res["name"] = $name;
|
||||
} else {
|
||||
$res = $error;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
function getShout( $host, $port, $name ) {
|
||||
$error = false;
|
||||
if ( !$fp = fsockopen( $host, $port, $errno, $errstr, 10 ) ) {
|
||||
$error = $errstr ."(". $errno .")";
|
||||
} else {
|
||||
fputs( $fp, "GET /index.html?sid=1 HTTP/1.0\r\n" );
|
||||
fputs( $fp, "User-Agent: Mozilla\r\n" );
|
||||
fputs( $fp, "Connection: close\r\n\r\n" );
|
||||
$xml = "";
|
||||
while ( !feof( $fp ) ) {
|
||||
$xml .= fgets( $fp, 512 );
|
||||
}
|
||||
fclose( $fp );
|
||||
if ( stristr( $xml, "HTTP/1.1 200 OK" ) == true ) {
|
||||
$xml = trim( substr( $xml, 42 ) );
|
||||
} else {
|
||||
$error = "Bad login";
|
||||
}
|
||||
if ( !$error ) {
|
||||
$res = array( "found" => true );
|
||||
preg_match_all( "/.*?Stream Status: <\/td\>\<td\><b\>Stream is up at \d*? kbps with (\d*?) of \d*? listeners/s", $xml, $parser );
|
||||
$res["listeners"] = intval( $parser[1][0] );
|
||||
$res["name"] = $name;
|
||||
} else {
|
||||
$res = $error;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
if ( !isset( $argv[1] ) ) $argv[1] = '';
|
||||
switch( $argv[1] ) {
|
||||
case "config":
|
||||
echo "graph_title Stream Listeners\n";
|
||||
echo "graph_category Network\n";
|
||||
echo "graph_vlabel listeners\n";
|
||||
echo "graph_hlabel listeners\n";
|
||||
echo "graph_args --base 1000 -l 0\n";
|
||||
echo "graph_scale no\n";
|
||||
echo "graph_info Number of listeners to shout- and / or icecast streams\n";
|
||||
echo "complete.info Complete listeners\n";
|
||||
echo "complete.label complete\n";
|
||||
echo "graph_order";
|
||||
foreach ( $cfg as $c ) {
|
||||
echo " ". strtolower( $c["name"] );
|
||||
}
|
||||
echo " complete\n";
|
||||
foreach ( $cfg as $c ) {
|
||||
echo strtolower( $c["name"] ) .".info ". $c["name"] ." listeners\n";
|
||||
echo strtolower( $c["name"] ) .".label ". strtolower( $c["name"] ) ."\n";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$complete = 0;
|
||||
foreach ( $cfg as $c ) {
|
||||
switch ( $c["type"] ) {
|
||||
case "ice":
|
||||
$res = getIce( $c["host"], $c["port"], $c["mountpoint"], $c["name"] );
|
||||
break;
|
||||
case "shout":
|
||||
$res = getShout( $c["host"], $c["port"], $c["name"] );
|
||||
break;
|
||||
}
|
||||
|
||||
switch( $argv[1] ) {
|
||||
case "config":
|
||||
echo "graph_title Stream Listeners\n";
|
||||
echo "graph_category Network\n";
|
||||
echo "graph_vlabel listeners\n";
|
||||
echo "graph_hlabel listeners\n";
|
||||
echo "graph_args --base 1000 -l 0\n";
|
||||
echo "graph_scale no\n";
|
||||
echo "graph_order";
|
||||
foreach ( $cfg as $c ) {
|
||||
echo " ". strtolower( $c["name"] );
|
||||
}
|
||||
echo " complete\n";
|
||||
// echo "\n";
|
||||
echo "graph_info Number of listeners to shout- and / or icecast streams\n";
|
||||
foreach ( $cfg as $c ) {
|
||||
echo strtolower( $c["name"] ) .".info ". $c["name"] ." listeners\n";
|
||||
echo strtolower( $c["name"] ) .".label ". strtolower( $c["name"] ) ."\n";
|
||||
}
|
||||
echo "complete.info Complete listeners\n";
|
||||
echo "complete.label complete\n";
|
||||
break;
|
||||
default:
|
||||
$complete = 0;
|
||||
|
||||
foreach ( $cfg as $c ) {
|
||||
switch ( $c["type"] ) {
|
||||
case "ice":
|
||||
$res = getIce( $c["host"], $c["port"], $c["mountpoint"], $c["name"] );
|
||||
$complete += $res["listeners"];
|
||||
break;
|
||||
case "shout":
|
||||
$res = getShout( $c["host"], $c["port"], $c["name"] );
|
||||
$complete += $res["listeners"];
|
||||
break;
|
||||
}
|
||||
echo strtolower($c["name"]) .".value ". $res["listeners"] ."\n";
|
||||
}
|
||||
|
||||
echo "complete.value ". $complete ."\n";
|
||||
break;
|
||||
}
|
||||
if ( is_array( $res ) ) {
|
||||
echo strtolower($c["name"]) .".value ". $res["listeners"] ."\n";
|
||||
$complete += $res["listeners"];
|
||||
} else {
|
||||
echo strtolower($c["name"]) .".value 0\n";
|
||||
}
|
||||
}
|
||||
echo "complete.value ". $complete ."\n";
|
||||
break;
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -25,9 +25,12 @@
|
|||
# Use it in your site configuration (/etc/nginx/sites-enabled/anything.conf):
|
||||
# access_log /var/log/nginx/upstream.log upstream;
|
||||
#
|
||||
# Attention! Because munin-node does not have read permission for nginx log files we need to run it as root.
|
||||
#
|
||||
# And specify some options in /etc/munin/plugin-conf.d/munin-node:
|
||||
#
|
||||
# [nginx_upstream_multi_upstream]
|
||||
# user root
|
||||
# env.graphs cache http time request
|
||||
# env.log /var/log/nginx/upstream.log
|
||||
# env.upstream 10.0.0.1:80 10.0.0.2:8080 unix:/tmp/upstream3
|
||||
|
@ -199,8 +202,8 @@ else:
|
|||
|
||||
try:
|
||||
logHandle = open(logPath, "r")
|
||||
except Exception:
|
||||
print "Log file %s not readable" % logPath
|
||||
except Exception as e:
|
||||
print "Log file %s not readable: %s" % (logPath, e.strerror)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
|
@ -278,7 +281,8 @@ else:
|
|||
lastByteHandle = open(lastBytePath, "w")
|
||||
lastByteHandle.write(str(logHandle.tell()))
|
||||
lastByteHandle.close()
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
print e.strerror
|
||||
sys.exit(1)
|
||||
|
||||
logHandle.close()
|
||||
|
|
44
plugins/openntpd/openntp_offset
Executable file
44
plugins/openntpd/openntp_offset
Executable file
|
@ -0,0 +1,44 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Plugin to measure OpenNTPd offset, delay and jitter for the active peer.
|
||||
#
|
||||
# Usage: Place it in the munin plugins directory (/usr/local/etc/munin/plugins/
|
||||
# or /etc/munin/plugins/). Might require running as root in order to access the
|
||||
# ntpctl socket.
|
||||
#
|
||||
# AUTHOR: Vladimir Krstulja <info@acheronmedia.com>
|
||||
# LICENSE: GPLv2
|
||||
#
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
|
||||
NTPCTL=`which ntpctl`
|
||||
|
||||
# Config
|
||||
if [ "$1" = "autoconf" ] ; then
|
||||
if [ -f "$NTPCTL" ]; then
|
||||
echo 'yes'
|
||||
else
|
||||
echo 'no (no ntpctl)'
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Autoconf
|
||||
if [ "$1" = "config" ] ; then
|
||||
echo "graph_title OpenNTP offset statistics for active peer"
|
||||
echo "graph_args --base 1000 --vertical-label seconds --lower-limit 0"
|
||||
echo "graph_category time"
|
||||
echo "graph_info Current status: `$NTPCTL -s status`"
|
||||
echo "delay.label Delay"
|
||||
echo "delay.cdef delay,1000,/"
|
||||
echo "offset.label Offset"
|
||||
echo "offset.cdef offset,1000,/"
|
||||
echo "jitter.label Jitter"
|
||||
echo "jitter.cdef jitter,1000,/"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Main plugin function
|
||||
$NTPCTL -s all | awk '/\*/{printf("offset.value %.3f\ndelay.value %.3f\njitter.value %.3f\n",$7,$8,$9)}'
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Plugin to monitor error.log from apache server.
|
||||
# Revision 0.1 2011/06/17 12:00:00 Ulrich Lusseau
|
||||
# Initial revision
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# config (required)
|
||||
# autoconf (optional - used by munin-config)
|
||||
#
|
||||
# Magick markers (optional):
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
# config example for /etc/munin/plugin-conf.d/munin-node
|
||||
#[apache_log]
|
||||
#user root
|
||||
#env.logfile /home/newsite/logs/errors.log
|
||||
#
|
||||
|
||||
|
||||
LOG=${logfile:-/var/log/apache2/error.log}
|
||||
|
||||
|
||||
if [ "$1" = "autoconf" ]; then
|
||||
if [ -r "$LOG" ]; then
|
||||
echo yes
|
||||
exit 0
|
||||
else
|
||||
echo no
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$1" = "config" ]; then
|
||||
|
||||
echo 'graph_title PHP Errors from ' $LOG
|
||||
echo 'graph_args --base 1000 -l 0'
|
||||
echo 'graph_vlabel Errors'
|
||||
echo 'LogWarning.label PHP Warning errors'
|
||||
echo 'LogNotice.label PHP Notice errors'
|
||||
echo 'LogFatal.label PHP Fatal errors'
|
||||
echo 'LogFile.label File does not exist errors'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
awk 'BEGIN{c["LogWarning"]=0;c["LogNotice"]=0;c["LogFatal"]=0;c["LogFile"]=0; }
|
||||
/PHP Warning/{c["LogWarning"]++}
|
||||
/PHP Notice/{c["LogNotice"]++}
|
||||
/PHP Fatal error/{c["LogFatal"]++}
|
||||
/File does not exist/{c["LogFile"]++}
|
||||
END{for(i in c){print i".value " c[i]} }' < $LOG
|
66
plugins/php/php_errors_
Normal file
66
plugins/php/php_errors_
Normal file
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash
|
||||
|
||||
: << =cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Plugin to monitor error.log from apache server
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
[php_errors_newsite]
|
||||
user www-data
|
||||
env.logfile /home/newsite/logs/errors.log /var/log/php/otherlog.log
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Raphaël Droz <raphael.droz+floss@gmail.com>
|
||||
|
||||
Revision 0.2 2016/03/23 22:00:00 Raphaël Droz
|
||||
Revision 0.1 2011/06/17 12:00:00 Ulrich Lusseau
|
||||
|
||||
=head1 MAGICK MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
. $MUNIN_LIBDIR/plugins/plugin.sh
|
||||
|
||||
LOGS=${logfile:-/var/log/apache2/error.log}
|
||||
|
||||
|
||||
if [[ $1 == autoconf ]]; then
|
||||
for LOG in $LOGS; do
|
||||
if [[ ! -r $LOGS ]]; then
|
||||
echo no
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo yes
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ $1 == config ]]; then
|
||||
echo 'graph_title PHP Errors from ' $LOGS
|
||||
echo 'graph_args --base 1000 -l 0'
|
||||
echo 'graph_vlabel Errors'
|
||||
echo 'LogWarning.label PHP Warning errors'
|
||||
echo 'LogNotice.label PHP Notice errors'
|
||||
echo 'LogFatal.label PHP Fatal errors'
|
||||
echo 'LogFile.label File does not exist errors'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
awk -f - $LOGS <<EOF
|
||||
BEGIN { c["LogWarning"]=0; c["LogNotice"]=0; c["LogFatal"]=0; c["LogFile"]=0; }
|
||||
/PHP Warning/{ c["LogWarning"]++ }
|
||||
/PHP Notice/{ c["LogNotice"]++ }
|
||||
/PHP Fatal error/{ c["LogFatal"]++ }
|
||||
/File does not exist/{ c["LogFile"]++ }
|
||||
|
||||
END{ for(i in c) { print i".value " c[i] } }
|
||||
EOF
|
|
@ -10,23 +10,23 @@ Inspirated by php5-fpm_status plugin by Daniel Caillibaud
|
|||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Any php-fpm host
|
||||
You will need the perl fastcgi::client on your host
|
||||
Any php-fpm host
|
||||
You will need the perl fastcgi::client on your host
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
You have to put this in your plugin.conf.d folder
|
||||
You have to put this in your plugin.conf.d folder
|
||||
|
||||
# If your php process is listening on TCP
|
||||
# If your php process is listening on TCP
|
||||
[php_fpm_process]
|
||||
env.serveraddr 127.0.0.1
|
||||
env.port 9000
|
||||
env.path /status
|
||||
env.path /status
|
||||
|
||||
# If your php process is listening on Unix Socket
|
||||
[php_fpm_process]
|
||||
env.sock /var/run/php5-fpm.sock
|
||||
env.path /status
|
||||
env.path /status
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
|
@ -35,11 +35,11 @@ You have to put this in your plugin.conf.d folder
|
|||
|
||||
=head1 VERSION
|
||||
|
||||
v1.0
|
||||
v1.0
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Minitux
|
||||
Minitux
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
|
@ -47,6 +47,7 @@ GNU General Public License, version 3
|
|||
|
||||
=cut
|
||||
|
||||
use File::Basename;
|
||||
use FCGI::Client;
|
||||
|
||||
my $ish = 1;
|
||||
|
@ -55,6 +56,8 @@ my $body = "";
|
|||
my $IDLE = 0;
|
||||
my $ACTIVE = 0;
|
||||
my $TOTAL = 0;
|
||||
my $SLOW_REQUESTS = 0;
|
||||
my $PLUGIN_NAME = basename($0);
|
||||
|
||||
my $SERVERADDR = $ENV{'serveraddr'} || "127.0.0.1";
|
||||
my $PORT = $ENV{'port'} || "9000";
|
||||
|
@ -68,7 +71,7 @@ if ($UNIX_SOCK) {
|
|||
$sock = IO::Socket::UNIX->new(
|
||||
Peer => $UNIX_SOCK,
|
||||
);
|
||||
if (!$sock) {
|
||||
if (!$sock) {
|
||||
print "Server maybe down, unabled to connect to $UNIX_SOCK";
|
||||
exit 2;
|
||||
}
|
||||
|
@ -78,7 +81,7 @@ if ($UNIX_SOCK) {
|
|||
PeerAddr => $SERVERADDR,
|
||||
PeerPort => $PORT,
|
||||
);
|
||||
if (!$sock) {
|
||||
if (!$sock) {
|
||||
print "Server maybe down, unabled to connect to $SERVERADDR:$PORT";
|
||||
exit 2;
|
||||
}
|
||||
|
@ -86,7 +89,7 @@ if ($UNIX_SOCK) {
|
|||
|
||||
my $client = FCGI::Client::Connection->new( sock => $sock );
|
||||
|
||||
my ( $stdout, $stderr, $appstatus ) = $client->request(
|
||||
my ( $stdout, $stderr, $appstatus ) = $client->request(
|
||||
+{
|
||||
REQUEST_METHOD => 'GET',
|
||||
SCRIPT_FILENAME => '',
|
||||
|
@ -112,33 +115,53 @@ while($stdout =~ /([^\n]*)\n?/g) {
|
|||
|
||||
if ( defined $ARGV[0] and $ARGV[0] eq "config" )
|
||||
{
|
||||
|
||||
|
||||
if($body =~ m/pool:\s+(.*?)\n/) {
|
||||
$pool = $1;
|
||||
}
|
||||
|
||||
print "graph_title php5-fpm status $pool\n";
|
||||
print "graph_args --base 1000 -l 0\n";
|
||||
print "graph_vlabel Processes\n";
|
||||
print "graph_scale yes\n";
|
||||
print "graph_category php-fpm\n";
|
||||
print "graph_info This graph shows the php5-fpm process manager status from pool: $pool\n";
|
||||
print "active.label Active processes\n";
|
||||
print "active.type GAUGE\n";
|
||||
print "active.draw AREA\n";
|
||||
print "active.info The number of active processes\n";
|
||||
print "idle.label Idle processes\n";
|
||||
print "idle.type GAUGE\n";
|
||||
print "idle.draw STACK\n";
|
||||
print "idle.info The number of idle processes\n";
|
||||
print "total.label Total processes\n";
|
||||
print "total.type GAUGE\n";
|
||||
print "total.draw LINE2\n";
|
||||
print "total.info The number of idle + active processes\n";
|
||||
exit 0
|
||||
}
|
||||
print <<"EOF";
|
||||
multigraph ${PLUGIN_NAME}_process
|
||||
graph_title php5-fpm processes for $pool
|
||||
graph_args --base 1000 -l 0
|
||||
graph_vlabel Processes
|
||||
graph_scale yes
|
||||
graph_category php-fpm
|
||||
graph_info This graph shows the php5-fpm process manager status from pool: $pool
|
||||
active.label Active processes
|
||||
active.type GAUGE
|
||||
active.draw AREA
|
||||
active.info The number of active processes
|
||||
idle.label Idle processes
|
||||
idle.type GAUGE
|
||||
idle.draw STACK
|
||||
idle.info The number of idle processes
|
||||
total.label Total processes
|
||||
total.type GAUGE
|
||||
total.draw LINE2
|
||||
total.info The number of idle + active processes
|
||||
|
||||
print $body;
|
||||
multigraph ${PLUGIN_NAME}_slowrequests
|
||||
graph_title php5-fpm slow requests $pool
|
||||
graph_args --base 1000 -l 0
|
||||
graph_vlabel Slow requests
|
||||
graph_scale yes
|
||||
graph_category php-fpm
|
||||
graph_info This graph shows the php5-fpm slow request from pool: $pool
|
||||
slow_requests.label Slow requests
|
||||
slow_requests.type DERIVE
|
||||
slow_requests.draw LINE2
|
||||
slow_requests.min 0
|
||||
slow_requests.info evolution of slow requests
|
||||
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
# print $body;
|
||||
|
||||
print "multigraph ${PLUGIN_NAME}_process\n";
|
||||
|
||||
if($body =~ m/idle processes: (.*?)\n/) {
|
||||
$IDLE = $1;
|
||||
|
@ -152,3 +175,10 @@ if($body =~ m/total processes: (.*?)\n/) {
|
|||
$TOTAL = $1;
|
||||
print "total.value ".$TOTAL."\n";
|
||||
}
|
||||
|
||||
if($body =~ m/slow requests: (.*?)\n/) {
|
||||
$SLOW_REQUESTS = $1;
|
||||
print "\n";
|
||||
print "multigraph ${PLUGIN_NAME}_slowrequests\n";
|
||||
print "slow_requests.value ".$SLOW_REQUESTS."\n";
|
||||
}
|
||||
|
|
|
@ -114,6 +114,12 @@ maildrop.label maildrop
|
|||
incoming.label incoming
|
||||
corrupt.label corrupt
|
||||
hold.label held
|
||||
active.draw AREA
|
||||
deferred.draw STACK
|
||||
maildrop.draw STACK
|
||||
incoming.draw STACK
|
||||
corrupt.draw STACK
|
||||
hold.draw STACK
|
||||
EOF
|
||||
for field in active deferred maildrop incoming corrupt hold; do
|
||||
print_warning $field
|
||||
|
|
|
@ -67,9 +67,6 @@ if (exists $ARGV[0]) {
|
|||
my (undef, undef, $dbname) = split (/_/, $0, 3);
|
||||
die "No dbname configured (did you make the proper symlink?)" unless $dbname;
|
||||
|
||||
my @datasources = DBI->data_sources ('Pg')
|
||||
or die ("Can't read any possible data sources: $?");
|
||||
|
||||
my $dsn = "DBI:Pg:dbname=$dbname";
|
||||
$dsn .= ";host=$dbhost" if $dbhost;
|
||||
print "#$dsn\n" if $debug;
|
||||
|
|
|
@ -25,7 +25,7 @@ import os
|
|||
import telnetlib
|
||||
import re
|
||||
|
||||
def main():
|
||||
def main():
|
||||
try:
|
||||
mode = sys.argv[1]
|
||||
except IndexError:
|
||||
|
@ -33,7 +33,7 @@ def main():
|
|||
wildcard = sys.argv[0].split("prosody_")[1].split("_")[0]
|
||||
host = os.environ.get('host', 'localhost')
|
||||
port = int(os.environ.get('port', 5582))
|
||||
|
||||
|
||||
if mode == "suggest":
|
||||
print "c2s"
|
||||
print "s2s"
|
||||
|
@ -47,7 +47,7 @@ def main():
|
|||
print "graph_title Prosody C2S Connections"
|
||||
print "graph_vlabel users"
|
||||
print "graph_category Prosody"
|
||||
|
||||
|
||||
print "all_client_connections.label client connections"
|
||||
print "secure_client_connections.label secure client connections"
|
||||
print "insecure_client_connections.label insecure client " \
|
||||
|
@ -64,7 +64,7 @@ def main():
|
|||
secure_client_connections = int(parsed_info[0])
|
||||
print "secure_client_connections.value %s" % \
|
||||
(secure_client_connections)
|
||||
|
||||
|
||||
telnet.write("c2s:show_insecure()\n")
|
||||
telnet_response = telnet.read_until("insecure client connections",
|
||||
5)
|
||||
|
@ -75,19 +75,19 @@ def main():
|
|||
all_client_connections = secure_client_connections + \
|
||||
insecure_client_connections
|
||||
print "all_client_connections.value %s" % (all_client_connections)
|
||||
telnet.write("quit")
|
||||
|
||||
telnet.write("quit\n")
|
||||
|
||||
elif wildcard == "s2s":
|
||||
if mode == "config":
|
||||
print "graph_title Prosody S2S Connections"
|
||||
print "graph_vlabel servers"
|
||||
print "graph_category Prosody"
|
||||
|
||||
|
||||
print "outgoing_connections.label outgoing connections"
|
||||
print "incoming_connections.label incoming connections"
|
||||
sys.exit(0)
|
||||
|
||||
else:
|
||||
|
||||
else:
|
||||
server_connections_re = re.compile(r"(\d+) outgoing, (\d+)")
|
||||
telnet = telnetlib.Telnet(host, port)
|
||||
telnet.write("s2s:show()\n")
|
||||
|
@ -95,8 +95,8 @@ def main():
|
|||
parsed_info = server_connections_re.findall(telnet_response)
|
||||
print "outgoing_connections.value %s" % (parsed_info[0][0])
|
||||
print "incoming_connections.value %s" % (parsed_info[0][1])
|
||||
telnet.write("quit")
|
||||
|
||||
telnet.write("quit\n")
|
||||
|
||||
elif wildcard == "presence":
|
||||
if mode == "config":
|
||||
print "graph_title Prosody Client Presence"
|
||||
|
@ -110,8 +110,8 @@ def main():
|
|||
print "dnd.label Do Not Disturb Clients"
|
||||
sys.exit(0)
|
||||
|
||||
else:
|
||||
client_presence_re = re.compile(r"- (.*?)\(\d+\)")
|
||||
else:
|
||||
client_presence_re = re.compile(r"[-\]] (.*?)\(\d+\)")
|
||||
telnet = telnetlib.Telnet(host, port)
|
||||
telnet.write("c2s:show()\n")
|
||||
telnet_response = telnet.read_until("clients", 5)
|
||||
|
@ -121,7 +121,7 @@ def main():
|
|||
print "away.value %s" % (parsed_info.count("away"))
|
||||
print "xa.value %s" % (parsed_info.count("xa"))
|
||||
print "dnd.value %s" % (parsed_info.count("dnd"))
|
||||
telnet.write("quit")
|
||||
telnet.write("quit\n")
|
||||
|
||||
elif wildcard == "uptime":
|
||||
if mode == "config":
|
||||
|
@ -147,7 +147,7 @@ def main():
|
|||
uptime_value = float(parsed_info[0]) + float(parsed_info[1])/24 +\
|
||||
float(parsed_info[2])/60/24
|
||||
print "uptime.value %s" % (uptime_value)
|
||||
telnet.write("quit")
|
||||
telnet.write("quit\n")
|
||||
|
||||
elif wildcard == "users":
|
||||
if mode == "config":
|
||||
|
|
|
@ -35,9 +35,11 @@
|
|||
|
||||
use strict;
|
||||
use IO::Socket::INET;
|
||||
use IO::Socket::UNIX;
|
||||
use Switch;
|
||||
|
||||
my $HOST = exists $ENV{'host'} ? $ENV{'host'} : "127.0.0.1";
|
||||
my $UNIX_SOCKET = exists $ENV{'unixsocket'} ? $ENV{'unixsocket'} : ''; # path to Redis Unix sock file
|
||||
my $PORT = exists $ENV{'port'} ? $ENV{'port'} : 6379;
|
||||
my $PASSWORD = exists $ENV{'password'} ? $ENV{'password'} : undef;
|
||||
my $TITLE_PREFIX = exists $ENV{'title_prefix'} ? $ENV{'title_prefix'} . ": " : "";
|
||||
|
@ -208,12 +210,26 @@ switch ($0) {
|
|||
close ($sock);
|
||||
|
||||
sub get_conn {
|
||||
my $sock = IO::Socket::INET->new(
|
||||
PeerAddr => $HOST,
|
||||
PeerPort => $PORT,
|
||||
Timeout => 10,
|
||||
Proto => 'tcp'
|
||||
);
|
||||
|
||||
my $sock;
|
||||
|
||||
if( $UNIX_SOCKET && -S $UNIX_SOCKET ){
|
||||
|
||||
$sock = IO::Socket::UNIX->new(
|
||||
Type => SOCK_STREAM(),
|
||||
Peer => $UNIX_SOCKET,
|
||||
);
|
||||
|
||||
}else{
|
||||
|
||||
$sock = IO::Socket::INET->new(
|
||||
PeerAddr => $HOST,
|
||||
PeerPort => $PORT,
|
||||
Timeout => 10,
|
||||
Proto => 'tcp'
|
||||
);
|
||||
}
|
||||
|
||||
if ( defined( $PASSWORD ) ) {
|
||||
print $sock "AUTH ", $PASSWORD, "\r\n";
|
||||
my $result = <$sock> || die "can't read socket: $!";
|
||||
|
|
68
plugins/sensors/battery_
Executable file
68
plugins/sensors/battery_
Executable file
|
@ -0,0 +1,68 @@
|
|||
#! /bin/sh
|
||||
# Plugin to monitor the battery status via the uevent API
|
||||
#
|
||||
# (c) 2015 - GPLv2 - steve.schnepp@pwkf.org
|
||||
#
|
||||
# It is a wildcard plugin, symlink it with the battery directory
|
||||
# default is to display charge as mAh, but you can also use percentage if you
|
||||
# prefer, by setting the env var "percent" to "yes".
|
||||
#
|
||||
# [battery_*]
|
||||
# env.percent no
|
||||
#
|
||||
|
||||
battery_name=${0##*_}
|
||||
percent=${percent:-"no"}
|
||||
|
||||
if [ "$1" = "config" ]
|
||||
then
|
||||
echo "graph_title Battery $battery_name"
|
||||
if [ "$percent" = "yes" ]
|
||||
then
|
||||
echo "graph_vlabel %"
|
||||
else
|
||||
echo "graph_vlabel mAh"
|
||||
fi
|
||||
|
||||
echo "charge_design.label Design charge"
|
||||
echo "charge_design.draw AREA"
|
||||
[ "$percent" = "yes" ] && echo "charge_design.cdef charge_design,charge_design,/,100,*"
|
||||
|
||||
echo "charge_full.label Full charge"
|
||||
echo "charge_full.draw AREA"
|
||||
[ "$percent" = "yes" ] && echo "charge_full.cdef charge_full,charge_design,/,100,*"
|
||||
echo "charge_now.label Current charge"
|
||||
echo "charge_now.draw AREA"
|
||||
[ "$percent" = "yes" ] && echo "charge_now.cdef charge_now,charge_design,/,100,*"
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Crudely read all the vars into the current namespace
|
||||
. /sys/class/power_supply/$battery_name/uevent
|
||||
|
||||
echo "charge_design.value $(( $POWER_SUPPLY_CHARGE_FULL_DESIGN / 1000 )) "
|
||||
echo "charge_full.value $(( $POWER_SUPPLY_CHARGE_FULL / 1000 ))"
|
||||
echo "charge_now.value $(( $POWER_SUPPLY_CHARGE_NOW / 1000 ))"
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
:<< DATA
|
||||
cat /sys/class/power_supply/$1/uevent
|
||||
POWER_SUPPLY_NAME=CMB1
|
||||
POWER_SUPPLY_STATUS=Charging
|
||||
POWER_SUPPLY_PRESENT=1
|
||||
POWER_SUPPLY_TECHNOLOGY=Li-ion
|
||||
POWER_SUPPLY_CYCLE_COUNT=0
|
||||
POWER_SUPPLY_VOLTAGE_MIN_DESIGN=10800000
|
||||
POWER_SUPPLY_VOLTAGE_NOW=11418000
|
||||
POWER_SUPPLY_CURRENT_NOW=2668000
|
||||
POWER_SUPPLY_CHARGE_FULL_DESIGN=5200000
|
||||
POWER_SUPPLY_CHARGE_FULL=5000000
|
||||
POWER_SUPPLY_CHARGE_NOW=100000
|
||||
POWER_SUPPLY_CAPACITY=2
|
||||
POWER_SUPPLY_CAPACITY_LEVEL=Normal
|
||||
POWER_SUPPLY_MODEL_NAME=CP293570
|
||||
POWER_SUPPLY_MANUFACTURER=Fujitsu
|
||||
DATA
|
90
plugins/snmp/snmp__cisco_sbs_cpu
Normal file
90
plugins/snmp/snmp__cisco_sbs_cpu
Normal file
|
@ -0,0 +1,90 @@
|
|||
#!/usr/bin/perl -w
|
||||
# -*- perl -*-
|
||||
# vim: ft=perl
|
||||
|
||||
=head1 NAME
|
||||
|
||||
snmp__cisco_sbs_cpu - Munin plugin to monitor CPU Usage on Cisco Small Business Switches.
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Cisco Small Business Switches (SBXXXX devices)
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
As a rule SNMP plugins need site specific configuration. The default
|
||||
configuration (shown here) will only work on insecure sites/devices.
|
||||
|
||||
[snmp_*]
|
||||
env.version 2
|
||||
env.community public
|
||||
|
||||
In general SNMP is not very secure at all unless you use SNMP version
|
||||
3 which supports authentication and privacy (encryption). But in any
|
||||
case the community string for your devices should not be "public".
|
||||
|
||||
Please see 'perldoc Munin::Plugin::SNMP' for further configuration
|
||||
information.
|
||||
|
||||
=head1 INTERPRETATION
|
||||
|
||||
CPU Percentage gives an idea of utilization of the device. High CPU
|
||||
can indicate a configuration problem or overutilization of the device.
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=snmpauto
|
||||
#%# capabilities=snmpconf
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
$Id$
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None known.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2015 James DeVincentis
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv3.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use Munin::Plugin::SNMP;
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq 'snmpconf') {
|
||||
print "require 1.3.6.1.4.1.9.6.1.101.1.7.0 [0-9]\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq "config") {
|
||||
my ($host) = Munin::Plugin::SNMP->config_session();
|
||||
|
||||
print "host_name $host\n" unless $host eq 'localhost';
|
||||
print <<"EOF";
|
||||
graph_title CPU Utilization
|
||||
graph_args --base 1000 -l 0 -u 100
|
||||
graph_vlabel CPU %
|
||||
graph_category system
|
||||
graph_info This graph shows the percentage of CPU used at different intervals. High CPU Utilization can indicate a configuration problem or overutilization of the device.
|
||||
load5sec.label 5s
|
||||
load5sec.info 5 Second CPU Utilization Average
|
||||
load5sec.draw LINE1
|
||||
load1min.label 1m
|
||||
load1min.info 1 Minute CPU Utilization Average
|
||||
load1min.draw LINE1
|
||||
load5min.label 5m
|
||||
load5min.info 5 Minute CPU Utilization Average
|
||||
EOF
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $session = Munin::Plugin::SNMP->session();
|
||||
print "load5sec.value ", $session->get_single('1.3.6.1.4.1.9.6.1.101.1.7.0'), "\n";
|
||||
print "load1min.value ", $session->get_single('1.3.6.1.4.1.9.6.1.101.1.8.0'), "\n";
|
||||
print "load5min.value ", $session->get_single('1.3.6.1.4.1.9.6.1.101.1.9.0'), "\n";
|
109
plugins/snmp/snmp__synology_hddtemp
Normal file
109
plugins/snmp/snmp__synology_hddtemp
Normal file
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/perl -w
|
||||
# -*- perl -*-
|
||||
# vim: ft=perl
|
||||
|
||||
=head1 NAME
|
||||
|
||||
snmp__syno_hddtemp - Munin plugin to monitor the temperature of
|
||||
harddisks in an Synology NAS.
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Any Synology NAS device which provides the synoDisk MIB.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
As a rule SNMP plugins need site specific configuration. The default
|
||||
configuration (shown here) will only work on insecure sites/devices.
|
||||
|
||||
[snmp_*]
|
||||
env.version 2
|
||||
env.community public
|
||||
|
||||
In general SNMP is not very secure at all unless you use SNMP version
|
||||
3 which supports authentication and privacy (encryption). But in any
|
||||
case the community string for your devices should not be "public".
|
||||
|
||||
Please see 'perldoc Munin::Plugin::SNMP' for further configuration
|
||||
information.
|
||||
|
||||
=head1 INTERPRETATION
|
||||
|
||||
The temperature of each disk installed in °C.
|
||||
|
||||
=head1 MIB INFORMATION
|
||||
|
||||
This plugin requires support for the synoDisk. It reports
|
||||
the temperature of the installed disks.
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=snmpauto
|
||||
#%# capabilities=snmpconf
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
$Id$
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None known.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2015 Thomas Arthofer
|
||||
|
||||
This plugin was derived from snmp__netstat by Lars Strand with updates
|
||||
by Matthew Boyle.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use Munin::Plugin::SNMP;
|
||||
|
||||
my $oid_drives = '1.3.6.1.4.1.6574.2.1.1';
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq 'snmpconf') {
|
||||
print "require ${oid_drives}. [0-9]\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my ($session, $error) = Munin::Plugin::SNMP->session();
|
||||
|
||||
my $table = $session->get_hash(
|
||||
-baseoid => $oid_drives, # IF-MIB
|
||||
-cols => {
|
||||
2 => 'name',
|
||||
3 => 'type',
|
||||
6 => 'temp',
|
||||
}
|
||||
);
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq 'config') {
|
||||
my ($host) = Munin::Plugin::SNMP->config_session();
|
||||
|
||||
print "host_name $host\n" unless $host eq 'localhost';
|
||||
print "graph_title HDD temperature\n";
|
||||
print "graph_category sensors\n";
|
||||
print "graph_vlabel Degrees Celsius\n";
|
||||
print "graph_info This graph shows the temperature of all HDDs in the Diskstation.\n";
|
||||
|
||||
foreach my $key ( sort keys %$table )
|
||||
{
|
||||
print "temp$key.label $table->{$key}->{'name'}\n";
|
||||
print "temp$key.info Temperature of $table->{$key}->{'name'} ($table->{$key}->{'type'})\n";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
|
||||
my $names = $session->get_entries(-columns => [ $oid_drives ]);
|
||||
|
||||
foreach my $key ( sort keys %$table )
|
||||
{
|
||||
print "temp$key.value $table->{$key}->{'temp'}\n";
|
||||
}
|
91
plugins/snmp/snmp__synology_temperature
Normal file
91
plugins/snmp/snmp__synology_temperature
Normal file
|
@ -0,0 +1,91 @@
|
|||
#!/usr/bin/perl -w
|
||||
# -*- cperl -*-
|
||||
# vim: ft=perl
|
||||
|
||||
=head1 NAME
|
||||
|
||||
snmp__syno_temperature - Munin plugin to retrieve current temperature from a
|
||||
Synology NAS.
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Any Synology NAS device which provides the synoSystem MIB.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
As a rule SNMP plugins need site specific configuration. The default
|
||||
configuration (shown here) will only work on insecure sites/devices.
|
||||
|
||||
[snmp_*]
|
||||
env.version 2
|
||||
env.community public
|
||||
|
||||
In general SNMP is not very secure at all unless you use SNMP version
|
||||
3 which supports authentication and privacy (encryption). But in any
|
||||
case the community string for your devices should not be "public".
|
||||
|
||||
Please see 'perldoc Munin::Plugin::SNMP' for further configuration
|
||||
information.
|
||||
|
||||
=head1 INTERPRETATION
|
||||
|
||||
This plugin queries the current temperature of the NAS.
|
||||
|
||||
=head1 MIB INFORMATION
|
||||
|
||||
This plugin requires support for the synoSystem MIB by Synology.
|
||||
It reports the contents of the temperature OID.
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=snmpauto
|
||||
#%# capabilities=snmpconf
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
$Id$
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None known.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2015 Thomas Arthofer
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2 or (at your option) any later version.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use Munin::Plugin::SNMP;
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq "snmpconf") {
|
||||
print "require 1.3.6.1.4.1.6574.1.2.0 [0-9]\n"; # Number
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq "config") {
|
||||
my ($host) = Munin::Plugin::SNMP->config_session();
|
||||
print "host_name $host\n" unless $host eq 'localhost';
|
||||
print "graph_title Temperatures
|
||||
graph_args --base 1000 -l 0
|
||||
graph_vlabel Degrees Celsius
|
||||
graph_category sensors
|
||||
graph_info This graph shows the temperature of the diskstation.
|
||||
temp.label CPU
|
||||
temp.info The temperature of the onboard CPU.
|
||||
";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $session = Munin::Plugin::SNMP->session(-translate =>
|
||||
[ -timeticks => 0x0 ]);
|
||||
|
||||
my $temp = $session->get_single (".1.3.6.1.4.1.6574.1.2.0") || 'ERROR';
|
||||
|
||||
print "Retrived uptime is '$temp'\n" if $Munin::Plugin::SNMP::DEBUG;
|
||||
|
||||
print "temp.value ", $temp, "\n";
|
102
plugins/snmp/snmp__synology_ups
Normal file
102
plugins/snmp/snmp__synology_ups
Normal file
|
@ -0,0 +1,102 @@
|
|||
#!/usr/bin/perl -w
|
||||
# -*- cperl -*-
|
||||
# vim: ft=perl
|
||||
|
||||
=head1 NAME
|
||||
|
||||
snmp__syno_ups - Munin plugin to retrieve various information of the
|
||||
UPS attached to a Synology NAS.
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Any Synology NAS device which provides the synoUPS MIB.
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
As a rule SNMP plugins need site specific configuration. The default
|
||||
configuration (shown here) will only work on insecure sites/devices.
|
||||
|
||||
[snmp_*]
|
||||
env.version 2
|
||||
env.community public
|
||||
|
||||
In general SNMP is not very secure at all unless you use SNMP version
|
||||
3 which supports authentication and privacy (encryption). But in any
|
||||
case the community string for your devices should not be "public".
|
||||
|
||||
Please see 'perldoc Munin::Plugin::SNMP' for further configuration
|
||||
information.
|
||||
|
||||
=head1 INTERPRETATION
|
||||
|
||||
The plugin reports the following stats about the UPS attached:
|
||||
- Load in %
|
||||
- Charge in %
|
||||
|
||||
=head1 MIB INFORMATION
|
||||
|
||||
This plugin requires support for the synoUPS MIB by Synology.
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=snmpauto
|
||||
#%# capabilities=snmpconf
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
$Id$
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
None known.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Copyright (C) 2015 Thomas Arthofer
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2 or (at your option) any later version.
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use Munin::Plugin::SNMP;
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq "snmpconf") {
|
||||
print "require 1.3.6.1.4.1.6574.4.3.1.1.0 [0-9]\n"; # Charge
|
||||
print "require 1.3.6.1.4.1.6574.4.2.12.1.0 [0-9]\n"; # Load
|
||||
exit 0;
|
||||
}
|
||||
|
||||
if (defined $ARGV[0] and $ARGV[0] eq "config") {
|
||||
my ($host) = Munin::Plugin::SNMP->config_session();
|
||||
print "host_name $host\n" unless $host eq 'localhost';
|
||||
print "graph_title UPS
|
||||
graph_args --base 1000 -l 0
|
||||
graph_vlabel Status of UPS
|
||||
graph_category system
|
||||
graph_info This graph shows the status of the attached UPS.
|
||||
charge.label Charge
|
||||
charge.info Charge status of battery.
|
||||
charge.draw LINE2
|
||||
load.label Load
|
||||
load.info Load on the UPS
|
||||
";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my $session = Munin::Plugin::SNMP->session(-translate =>
|
||||
[ -timeticks => 0x0 ]);
|
||||
|
||||
my $charge = $session->get_single (".1.3.6.1.4.1.6574.4.3.1.1.0") || 'ERROR';
|
||||
$charge = unpack "f", reverse pack "H*", $charge;
|
||||
|
||||
my $load = $session->get_single (".1.3.6.1.4.1.6574.4.2.12.1.0") || 'ERROR';
|
||||
$load = unpack "f", reverse pack "H*", $load;
|
||||
|
||||
print "Retrived charge '$charge'\n" if $Munin::Plugin::SNMP::DEBUG;
|
||||
print "Retrived load '$load'\n" if $Munin::Plugin::SNMP::DEBUG;
|
||||
|
||||
print "charge.value ", $charge, "\n";
|
||||
print "load.value ", $load, "\n";
|
182
plugins/streaming/icecast2_stats_
Executable file
182
plugins/streaming/icecast2_stats_
Executable file
|
@ -0,0 +1,182 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# This plugin shows the statistics of every source currently connected to the Icecast2 server.
|
||||
# See the Icecast2_ plugin for collecting data of specific mountpoints.
|
||||
#
|
||||
# An icecast server v2.4 or later is required for this module since it uses the status-json.xsl
|
||||
# output (see http://www.icecast.org/docs/icecast-2.4.1/server-stats.html).
|
||||
#
|
||||
# The following data for each source is available:
|
||||
# * listeners: current count of listeners
|
||||
# * duration: the age of the stream/source
|
||||
#
|
||||
# Additionally the Icecast service uptime is available.
|
||||
#
|
||||
# This plugin requires Python 3 (e.g. for urllib instead of urllib2).
|
||||
#
|
||||
#
|
||||
# Environment variables:
|
||||
# * status_url: defaults to "http://localhost:8000/status-json.xsl"
|
||||
#
|
||||
#
|
||||
# Copyright (C) 2015 Lars Kruse <devel@sumpfralle.de>
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
#
|
||||
# Magic markers
|
||||
#%# capabilities=autoconf suggest
|
||||
#%# family=auto
|
||||
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import urllib.request
|
||||
import sys
|
||||
|
||||
|
||||
status_url = os.getenv("status_url", "http://localhost:8000/status-json.xsl")
|
||||
PLUGIN_SCOPES = ("sources_listeners", "sources_duration", "service_uptime")
|
||||
PLUGIN_NAME_PREFIX = "icecast2_stats_"
|
||||
|
||||
|
||||
def clean_fieldname(name):
|
||||
""" see http://munin-monitoring.org/wiki/notes_on_datasource_names
|
||||
|
||||
This function is a bit clumsy as it tries to avoid using a regular
|
||||
expression for the sake of micropython compatibility.
|
||||
"""
|
||||
def get_valid(char, position):
|
||||
if char == '_':
|
||||
return '_'
|
||||
elif 'a' <= char.lower() <= 'z':
|
||||
return char
|
||||
elif (position > 0) and ('0' <= char <= '9'):
|
||||
return char
|
||||
else:
|
||||
return '_'
|
||||
return "".join([get_valid(char, position) for position, char in enumerate(name)])
|
||||
|
||||
|
||||
def parse_iso8601(datestring):
|
||||
""" try to avoid using an external library for parsing an ISO8601 date string """
|
||||
if datestring.endswith("Z"):
|
||||
timestamp_string = datestring[:-1]
|
||||
time_delta = datetime.timedelta(minutes=0)
|
||||
else:
|
||||
# the "offset_text" is something like "+0500" or "-0130"
|
||||
timestamp_string, offset_text = datestring[:-5], datestring[-5:]
|
||||
offset_minutes = int(offset_text[1:3]) * 60 + int(offset_text[3:])
|
||||
if offset_text.startswith("+"):
|
||||
pass
|
||||
elif offset_text.startswith("-"):
|
||||
offset_minutes *= -1
|
||||
else:
|
||||
# invalid format
|
||||
return None
|
||||
time_delta = datetime.timedelta(minutes=offset_minutes)
|
||||
local_time = datetime.datetime.strptime(timestamp_string, "%Y-%m-%dT%H:%M:%S")
|
||||
return local_time + time_delta
|
||||
|
||||
|
||||
def get_iso8601_age_days(datestring):
|
||||
now = datetime.datetime.now()
|
||||
timestamp = parse_iso8601(datestring)
|
||||
if timestamp:
|
||||
return (now - timestamp).total_seconds() / (24 * 60 * 60)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def _get_json_statistics():
|
||||
with urllib.request.urlopen(status_url) as conn:
|
||||
json_body = conn.read()
|
||||
return json.loads(json_body.decode("utf-8"))
|
||||
|
||||
|
||||
def get_sources():
|
||||
sources = []
|
||||
for source in _get_json_statistics()["icestats"]["source"]:
|
||||
path_name = source["listenurl"].split("/")[-1]
|
||||
sources.append({"name": path_name,
|
||||
"fieldname": clean_fieldname(path_name),
|
||||
"listeners": source["listeners"],
|
||||
"duration_days": get_iso8601_age_days(source["stream_start_iso8601"])})
|
||||
sources.sort(key=lambda item: item["name"])
|
||||
return sources
|
||||
|
||||
|
||||
def get_server_uptime_days():
|
||||
return get_iso8601_age_days(_get_json_statistics()["icestats"]["server_start_iso8601"])
|
||||
|
||||
|
||||
def get_scope():
|
||||
called_name = os.path.basename(sys.argv[0])
|
||||
if called_name.startswith(PLUGIN_NAME_PREFIX):
|
||||
scope = called_name[len(PLUGIN_NAME_PREFIX):]
|
||||
if not scope in PLUGIN_SCOPES:
|
||||
print("Invalid scope requested: {0} (expected: {1})".format(scope, "/".join(PLUGIN_SCOPES)), file=sys.stderr)
|
||||
sys.exit(2)
|
||||
else:
|
||||
print("Invalid filename - failed to discover plugin scope", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
return scope
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
action = sys.argv[1] if (len(sys.argv) > 1) else None
|
||||
if action == "autoconf":
|
||||
try:
|
||||
get_sources()
|
||||
print("yes")
|
||||
except OSError:
|
||||
print("no")
|
||||
elif action == "suggest":
|
||||
for scope in PLUGIN_SCOPES:
|
||||
print(scope)
|
||||
elif action == "config":
|
||||
scope = get_scope()
|
||||
if scope == "sources_listeners":
|
||||
print("graph_title Total number of listeners")
|
||||
print("graph_vlabel listeners")
|
||||
print("graph_category Icecast")
|
||||
for index, source in enumerate(get_sources()):
|
||||
print("{0}.label {1}".format(source["fieldname"], source["name"]))
|
||||
print("{0}.draw {1}".format(source["fieldname"], ("AREA" if (index == 0) else "STACK")))
|
||||
elif scope == "sources_duration":
|
||||
print("graph_title Duration of sources")
|
||||
print("graph_vlabel duration in days")
|
||||
print("graph_category Icecast")
|
||||
for source in get_sources():
|
||||
print("{0}.label {1}".format(source["fieldname"], source["name"]))
|
||||
elif scope == "service_uptime":
|
||||
print("graph_title Icecast service uptime")
|
||||
print("graph_vlabel uptime in days")
|
||||
print("graph_category Icecast")
|
||||
print("uptime.label service uptime")
|
||||
elif action is None:
|
||||
scope = get_scope()
|
||||
if scope == "sources_listeners":
|
||||
for source in get_sources():
|
||||
print("{0}.value {1}".format(source["fieldname"], source["listeners"]))
|
||||
elif scope == "sources_duration":
|
||||
for source in get_sources():
|
||||
print("{0}.value {1}".format(source["fieldname"], source["duration_days"] or 0))
|
||||
elif scope == "service_uptime":
|
||||
print("uptime.value {0}".format(get_server_uptime_days()))
|
||||
else:
|
||||
print("Invalid argument given: {0}".format(action), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
273
plugins/system/1sec/if1sec-c.c
Normal file
273
plugins/system/1sec/if1sec-c.c
Normal file
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* if1sec C plugin
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/file.h>
|
||||
|
||||
#define PROC_STAT "/proc/net/dev"
|
||||
#define PLUGIN_NAME "if1sec-c"
|
||||
|
||||
int fail(char* msg) {
|
||||
perror(msg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns the ifname from a /proc/net/dev line
|
||||
* It will return an inside pointer to line, and modifiy the end with a \0
|
||||
*/
|
||||
char* get_ifname_from_procstatline(char* line) {
|
||||
char *ifname;
|
||||
for (ifname = line; (*ifname) == ' '; ifname ++);
|
||||
|
||||
char *ifname_end;
|
||||
for (ifname_end = ifname; (*ifname_end) != ':'; ifname_end ++);
|
||||
(*ifname_end) = '\0';
|
||||
|
||||
return ifname;
|
||||
}
|
||||
|
||||
int config() {
|
||||
/* Get the number of if */
|
||||
int f;
|
||||
if ( !(f=open(PROC_STAT, O_RDONLY)) ) {
|
||||
return fail("cannot open " PROC_STAT);
|
||||
}
|
||||
|
||||
// Starting with -2, since the 2 lines on top are header lines
|
||||
int nif = -2;
|
||||
|
||||
const int buffer_size = 64 * 1024;
|
||||
char buffer[buffer_size];
|
||||
|
||||
// whole /proc/stat can be read in 1 syscall
|
||||
if (read(f, buffer, buffer_size) <= 0) {
|
||||
return fail("cannot read " PROC_STAT);
|
||||
}
|
||||
|
||||
// tokenization per-line
|
||||
char* line; char *saveptr;
|
||||
char* newl = "\n";
|
||||
for (line = strtok_r(buffer, newl, &saveptr); line; line = strtok_r(NULL, newl, &saveptr)) {
|
||||
// Skip the header lines
|
||||
if (nif ++ < 0) { continue; }
|
||||
|
||||
char* if_name = get_ifname_from_procstatline(line);
|
||||
printf(
|
||||
"multigraph if_%s_1sec" "\n"
|
||||
"graph_order down up" "\n"
|
||||
"graph_title %s traffic" "\n"
|
||||
"graph_category system::1sec" "\n"
|
||||
"graph_vlabel bits in (-) / out (+) per ${graph_period}" "\n"
|
||||
"graph_data_size custom 1d, 10s for 1w, 1m for 1t, 5m for 1y" "\n"
|
||||
, if_name, if_name
|
||||
);
|
||||
|
||||
printf(
|
||||
"down.label -" "\n"
|
||||
"down.type DERIVE" "\n"
|
||||
"down.graph no" "\n"
|
||||
"down.cdef down,8,*" "\n"
|
||||
"down.min 0" "\n"
|
||||
|
||||
"up.label bps" "\n"
|
||||
"up.type DERIVE" "\n"
|
||||
"up.negative down" "\n"
|
||||
"up.cdef down,8,*" "\n"
|
||||
"up.min 0" "\n"
|
||||
);
|
||||
}
|
||||
|
||||
close(f);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* pid_filename;
|
||||
char* cache_filename;
|
||||
|
||||
/* Wait until the next second, and return the EPOCH */
|
||||
time_t wait_until_next_second() {
|
||||
struct timespec tp;
|
||||
clock_gettime(CLOCK_REALTIME, &tp);
|
||||
|
||||
time_t current_epoch = tp.tv_sec;
|
||||
long nsec_to_sleep = 1000*1000*1000 - tp.tv_nsec;
|
||||
|
||||
|
||||
/* Only sleep if needed */
|
||||
if (nsec_to_sleep > 0) {
|
||||
tp.tv_sec = 0;
|
||||
tp.tv_nsec = nsec_to_sleep;
|
||||
nanosleep(&tp, NULL);
|
||||
}
|
||||
|
||||
return current_epoch + 1;
|
||||
}
|
||||
|
||||
int acquire() {
|
||||
|
||||
/* fork ourselves if not asked otherwise */
|
||||
char* no_fork = getenv("no_fork");
|
||||
if (! no_fork || strcmp("1", no_fork)) {
|
||||
if (fork()) return;
|
||||
// we are the child, complete the daemonization
|
||||
|
||||
/* Close standard IO */
|
||||
fclose(stdin);
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
|
||||
/* create new session and process group */
|
||||
setsid();
|
||||
}
|
||||
|
||||
/* write the pid */
|
||||
FILE* pid_file = fopen(pid_filename, "w");
|
||||
fprintf(pid_file, "%d\n", getpid());
|
||||
fclose(pid_file);
|
||||
|
||||
/* Reading /proc/stat */
|
||||
int f = open(PROC_STAT, O_RDONLY);
|
||||
|
||||
/* open the spoolfile */
|
||||
int cache_file = open(cache_filename, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
|
||||
/* loop each second */
|
||||
while (1) {
|
||||
/* wait until next second */
|
||||
time_t epoch = wait_until_next_second();
|
||||
|
||||
const int buffer_size = 64 * 1024;
|
||||
char buffer[buffer_size];
|
||||
|
||||
if (lseek(f, 0, SEEK_SET) < 0) {
|
||||
return fail("cannot seek " PROC_STAT);
|
||||
}
|
||||
|
||||
// whole PROC file can be read in 1 syscall
|
||||
if (read(f, buffer, buffer_size) <= 0) {
|
||||
return fail("cannot read " PROC_STAT);
|
||||
}
|
||||
|
||||
// ignore the 1rst line
|
||||
char* line; char *saveptr;
|
||||
const char* newl = "\n";
|
||||
|
||||
/* lock */
|
||||
flock(cache_file, LOCK_EX);
|
||||
|
||||
int nif = -2;
|
||||
for (line = strtok_r(buffer, newl, &saveptr); line; line = strtok_r(NULL, newl, &saveptr)) {
|
||||
// Skip the header lines
|
||||
if (nif ++ < 0) { continue; }
|
||||
|
||||
char if_id[64];
|
||||
uint_fast64_t r_bytes, r_packets, r_errs, r_drop, r_fifo, r_frame, r_compressed, r_multicast;
|
||||
uint_fast64_t t_bytes, t_packets, t_errs, t_drop, t_fifo, t_frame, t_compressed, t_multicast;
|
||||
sscanf(line, "%s"
|
||||
" "
|
||||
"%llu %llu %llu %llu %llu %llu %llu %llu"
|
||||
" "
|
||||
"%llu %llu %llu %llu %llu %llu %llu %llu"
|
||||
, if_id
|
||||
, &r_bytes, &r_packets, &r_errs, &r_drop, &r_fifo, &r_frame, &r_compressed, &r_multicast
|
||||
, &t_bytes, &t_packets, &t_errs, &t_drop, &t_fifo, &t_frame, &t_compressed, &t_multicast
|
||||
);
|
||||
|
||||
// Remove trailing ':' of if_id
|
||||
if_id[strlen(if_id) - 1] = '\0';
|
||||
|
||||
char out_buffer[1024];
|
||||
sprintf(out_buffer,
|
||||
"multigraph if_%s_1sec" "\n"
|
||||
"up.value %ld:%llu" "\n"
|
||||
"down.value %ld:%llu" "\n"
|
||||
, if_id
|
||||
, epoch, r_bytes
|
||||
, epoch, t_bytes
|
||||
);
|
||||
|
||||
write(cache_file, out_buffer, strlen(out_buffer));
|
||||
}
|
||||
|
||||
/* unlock */
|
||||
flock(cache_file, LOCK_UN);
|
||||
}
|
||||
|
||||
close(cache_file);
|
||||
close(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fetch() {
|
||||
FILE* cache_file = fopen(cache_filename, "r+");
|
||||
|
||||
/* lock */
|
||||
flock(fileno(cache_file), LOCK_EX);
|
||||
|
||||
/* cat the cache_file to stdout */
|
||||
char buffer[1024];
|
||||
while (fgets(buffer, 1024, cache_file)) {
|
||||
printf("%s", buffer);
|
||||
}
|
||||
|
||||
ftruncate(fileno(cache_file), 0);
|
||||
fclose(cache_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
/* resolve paths */
|
||||
char *MUNIN_PLUGSTATE = getenv("MUNIN_PLUGSTATE");
|
||||
|
||||
/* Default is current directory */
|
||||
if (! MUNIN_PLUGSTATE) MUNIN_PLUGSTATE = ".";
|
||||
|
||||
size_t MUNIN_PLUGSTATE_length = strlen(MUNIN_PLUGSTATE);
|
||||
|
||||
pid_filename = malloc(MUNIN_PLUGSTATE_length + strlen("/" PLUGIN_NAME ".") + strlen("pid") + 1); pid_filename[0] = '\0';
|
||||
cache_filename = malloc(MUNIN_PLUGSTATE_length + strlen("/" PLUGIN_NAME ".") + strlen("value") + 1); cache_filename[0] = '\0';
|
||||
|
||||
strcat(pid_filename, MUNIN_PLUGSTATE);
|
||||
strcat(pid_filename, "/" PLUGIN_NAME "." "pid");
|
||||
|
||||
strcat(cache_filename, MUNIN_PLUGSTATE);
|
||||
strcat(cache_filename, "/" PLUGIN_NAME "." "value");
|
||||
|
||||
if (argc > 1) {
|
||||
char* first_arg = argv[1];
|
||||
if (! strcmp(first_arg, "config")) {
|
||||
return config();
|
||||
}
|
||||
|
||||
if (! strcmp(first_arg, "acquire")) {
|
||||
return acquire();
|
||||
}
|
||||
}
|
||||
|
||||
return fetch();
|
||||
}
|
||||
|
||||
/***** DEMO
|
||||
|
||||
/proc/net/dev sample
|
||||
|
||||
Inter-| Receive | Transmit
|
||||
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
|
||||
lo: 4364 54 0 0 0 0 0 0 4364 54 0 0 0 0 0 0
|
||||
eth0: 3459461624 22016512 0 70 0 0 0 0 3670486138 18117144 0 0 0 0 0 0
|
||||
|
||||
*****/
|
4
plugins/system/multicpu1sec/.gitignore
vendored
Normal file
4
plugins/system/multicpu1sec/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/multicpu1sec-c
|
||||
/multicpu1sec.o
|
||||
/multicpu1sec.pid
|
||||
/multicpu1sec.value
|
|
@ -5,6 +5,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
@ -20,23 +21,30 @@ int fail(char* msg) {
|
|||
|
||||
int config() {
|
||||
/* Get the number of CPU */
|
||||
FILE* f;
|
||||
if ( !(f=fopen(PROC_STAT, "r")) ) {
|
||||
int f;
|
||||
if ( !(f=open(PROC_STAT, O_RDONLY)) ) {
|
||||
return fail("cannot open " PROC_STAT);
|
||||
}
|
||||
|
||||
// Starting with -1, since the first line is the "global cpu line"
|
||||
int ncpu = -1;
|
||||
while (! feof(f)) {
|
||||
char buffer[1024];
|
||||
if (fgets(buffer, 1024, f) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (! strncmp(buffer, "cpu", 3)) ncpu ++;
|
||||
const int buffer_size = 64 * 1024;
|
||||
char buffer[buffer_size];
|
||||
|
||||
// whole /proc/stat can be read in 1 syscall
|
||||
if (read(f, buffer, buffer_size) <= 0) {
|
||||
return fail("cannot read " PROC_STAT);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
// tokenization per-line
|
||||
char* line;
|
||||
char* newl = "\n";
|
||||
for (line = strtok(buffer, newl); line; line = strtok(NULL, newl)) {
|
||||
if (! strncmp(line, "cpu", 3)) ncpu ++;
|
||||
}
|
||||
|
||||
close(f);
|
||||
|
||||
printf(
|
||||
"graph_title multicpu1sec\n"
|
||||
|
@ -104,43 +112,62 @@ int acquire() {
|
|||
fprintf(pid_file, "%d\n", getpid());
|
||||
fclose(pid_file);
|
||||
|
||||
/* Reading /proc/stat */
|
||||
int f = open(PROC_STAT, O_RDONLY);
|
||||
|
||||
/* open the spoolfile */
|
||||
int cache_file = open(cache_filename, O_CREAT | O_APPEND | O_WRONLY);
|
||||
|
||||
/* loop each second */
|
||||
while (1) {
|
||||
/* wait until next second */
|
||||
time_t epoch = wait_until_next_second();
|
||||
|
||||
/* Reading /proc/stat */
|
||||
FILE* f = fopen(PROC_STAT, "r");
|
||||
// Read and ignore the 1rst line
|
||||
char buffer[1024];
|
||||
fgets(buffer, 1024, f);
|
||||
|
||||
/* open the spoolfile */
|
||||
FILE* cache_file = fopen(cache_filename, "a");
|
||||
const int buffer_size = 64 * 1024;
|
||||
char buffer[buffer_size];
|
||||
|
||||
if (lseek(f, 0, SEEK_SET) < 0) {
|
||||
return fail("cannot seek " PROC_STAT);
|
||||
}
|
||||
|
||||
// whole /proc/stat can be read in 1 syscall
|
||||
if (read(f, buffer, buffer_size) <= 0) {
|
||||
return fail("cannot read " PROC_STAT);
|
||||
}
|
||||
|
||||
// ignore the 1rst line
|
||||
char* line;
|
||||
const char* newl = "\n";
|
||||
line = strtok(buffer, newl);
|
||||
|
||||
/* lock */
|
||||
flock(fileno(cache_file), LOCK_EX);
|
||||
|
||||
while (! feof(f)) {
|
||||
if (fgets(buffer, 1024, f) == 0) {
|
||||
// EOF
|
||||
break;
|
||||
}
|
||||
flock(cache_file, LOCK_EX);
|
||||
|
||||
for (line = strtok(NULL, newl); line; line = strtok(NULL, newl)) {
|
||||
// Not on CPU lines anymore
|
||||
if (strncmp(buffer, "cpu", 3)) break;
|
||||
if (strncmp(line, "cpu", 3)) break;
|
||||
|
||||
char cpu_id[64];
|
||||
long usr, nice, sys, idle, iowait, irq, softirq;
|
||||
sscanf(buffer, "%s %ld %ld %ld %ld %ld %ld %ld", cpu_id, &usr, &nice, &sys, &idle, &iowait, &irq, &softirq);
|
||||
sscanf(line, "%s %ld %ld %ld %ld %ld %ld %ld", cpu_id, &usr, &nice, &sys, &idle, &iowait, &irq, &softirq);
|
||||
|
||||
long used = usr + nice + sys + iowait + irq + softirq;
|
||||
|
||||
fprintf(cache_file, "%s.value %ld:%ld\n", cpu_id, epoch, used);
|
||||
char out_buffer[1024];
|
||||
sprintf(out_buffer, "%s.value %ld:%ld\n", cpu_id, epoch, used);
|
||||
|
||||
write(cache_file, out_buffer, strlen(out_buffer));
|
||||
}
|
||||
|
||||
fclose(cache_file);
|
||||
fclose(f);
|
||||
/* unlock */
|
||||
flock(cache_file, LOCK_UN);
|
||||
}
|
||||
|
||||
close(cache_file);
|
||||
close(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fetch() {
|
||||
|
@ -157,6 +184,8 @@ int fetch() {
|
|||
|
||||
ftruncate(fileno(cache_file), 0);
|
||||
fclose(cache_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
|
|
@ -30,6 +30,7 @@ fi
|
|||
|
||||
if [ "$1" = "config" ]; then
|
||||
echo "graph_title NTP offset and delay to peer $PEER"
|
||||
echo "graph_category time"
|
||||
echo "graph_args --base 1000 --vertical-label msec"
|
||||
echo "offset.label Offset"
|
||||
echo "offset.draw LINE2"
|
||||
|
|
|
@ -1,33 +1,55 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# (c) Andreas Kreisl
|
||||
# (c) Andreas Kreisl extended by Tobias Schramm
|
||||
#
|
||||
# Link name will be used as title: apc_{$title}
|
||||
#
|
||||
# env.keys LOADPCT BCHARGE LINEV BATTV TIMELEFT
|
||||
# env.unit % or Volt or Minutes
|
||||
#
|
||||
|
||||
|
||||
if [ -z "$keys" ]; then
|
||||
keys="TIMELEFT"
|
||||
keys="LINEV LOADPCT BCHARGE NUMXFERS TIMELEFT"
|
||||
fi
|
||||
|
||||
apcinfo=`/sbin/apcaccess`
|
||||
|
||||
if [ "$1" = "config" ]; then
|
||||
title=`basename $0 | sed 's/^apc_//g' | awk '{ sub(/^./,toupper(substr($0,1,1))); print; }'`
|
||||
echo "graph_title APC Status - $title"
|
||||
echo 'graph_args --base 1000 -l 0 '
|
||||
echo "graph_vlabel $unit"
|
||||
echo 'graph_category sensors'
|
||||
echo 'multigraph apc_status'
|
||||
echo "graph_title UPS Status - $title"
|
||||
echo 'graph_args --base 1000'
|
||||
echo 'graph_category hardware'
|
||||
title=`/sbin/apcaccess | egrep "^MODEL" | awk '{print $3" "$4" "$5" "$6" "$7" "$8" "$9;}'`
|
||||
echo "graph_info $title"
|
||||
for key in $keys; do
|
||||
echo "$key.label $key"
|
||||
echo "$key.info Value of $key."
|
||||
echo "$key.draw LINE2"
|
||||
echo "$key.info Value of $key"
|
||||
echo "$key.draw LINE1"
|
||||
done
|
||||
for key in $keys; do
|
||||
key_lower=`echo "$key" | awk '{print tolower($0);}'`
|
||||
unit=`echo "$apcinfo" | egrep "^$key" | awk '{print $4;}'`
|
||||
echo "multigraph apc_status.$key_lower"
|
||||
echo "graph_title $key"
|
||||
echo 'graph_args --base 1000'
|
||||
if [ -n "$unit" ]; then
|
||||
echo "graph_vlabel $unit"
|
||||
fi
|
||||
echo 'graph_category hardware'
|
||||
echo "$key.label $key"
|
||||
echo "$key.info $key."
|
||||
echo "$key.draw LINE1"
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
searchkey=`echo "$keys" | tr " " "\|"`
|
||||
/sbin/apcaccess | egrep "$searchkey" | awk '{print $1".value "$3;}'
|
||||
echo 'multigraph apc_status'
|
||||
for key in $keys; do
|
||||
echo "$apcinfo" | egrep "^$key" | awk '{print $1".value "$3;}'
|
||||
done
|
||||
for key in $keys; do
|
||||
key_lower=`echo "$key" | awk '{print tolower($0)}'`
|
||||
echo "multigraph apc_status.$key_lower"
|
||||
echo "$apcinfo" | egrep "^$key" | awk '{print $1".value "$3;}'
|
||||
done
|
||||
|
||||
|
|
|
@ -19,9 +19,12 @@ your actual plugins directory.
|
|||
In your plugins.conf add
|
||||
```
|
||||
[varnish4_*]
|
||||
group varnish
|
||||
env.varnishstat varnishstat
|
||||
env.name
|
||||
```
|
||||
`group varnish` Since Varnish version 4.1, Varnish shared log utilities must be run in a context with *varnish* group membership.
|
||||
|
||||
`env.varnishstat` can be a full path to varnishstat if it's
|
||||
not in the path already.
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ The plugin needs to be able to execute varnishstat.
|
|||
|
||||
The configuration section shows the defaults
|
||||
[varnish4_*]
|
||||
group varnish
|
||||
env.varnishstat varnishstat
|
||||
env.name
|
||||
|
||||
|
@ -232,7 +233,7 @@ my %ASPECTS = (
|
|||
'order' => 'client_req cache_hit cache_miss '
|
||||
. 'cache_hitpass' ,
|
||||
'vlabel' => '%',
|
||||
'args' => '-u 100 --rigid',
|
||||
'args' => '-l 0 -u 100 --rigid',
|
||||
'scale' => 'no',
|
||||
'values' => {
|
||||
'client_req' => {
|
||||
|
@ -630,15 +631,15 @@ my %ASPECTS = (
|
|||
},
|
||||
'bans_tested' => {
|
||||
'type' => 'DERIVE',
|
||||
'min' => '0'
|
||||
'min' => '0'
|
||||
},
|
||||
'bans_obj_killed' => {
|
||||
'type' => 'DERIVE',
|
||||
'min' => '0'
|
||||
'min' => '0'
|
||||
},
|
||||
'bans_tests_tested' => {
|
||||
'type' => 'DERIVE',
|
||||
'min' => '0'
|
||||
'min' => '0'
|
||||
},
|
||||
'bans_dups' => {
|
||||
'type' => 'GAUGE'
|
||||
|
@ -750,6 +751,7 @@ my %ASPECTS = (
|
|||
},
|
||||
'sess_pipe_overflow' => {
|
||||
'type' => 'DERIVE'
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -778,9 +780,9 @@ my %ASPECTS = (
|
|||
sub translate_type
|
||||
{
|
||||
my $d = $_[0];
|
||||
if ($d eq "i") {
|
||||
if ($d eq "i" or $d eq "g") {
|
||||
$d = "GAUGE";
|
||||
} elsif ($d eq "a") {
|
||||
} elsif ($d eq "a" or $d eq "c") {
|
||||
$d = "DERIVE";
|
||||
}
|
||||
return $d;
|
||||
|
|
|
@ -68,14 +68,14 @@ def find_vm_names(pids):
|
|||
result = {}
|
||||
for pid in pids:
|
||||
cmdline = open("/proc/%s/cmdline" % pid, "r")
|
||||
result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_]*)\x00\-.*$",r"\1", cmdline.readline()))
|
||||
result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_-]*)\x00\-.*$",r"\1", cmdline.readline()))
|
||||
return result
|
||||
|
||||
def list_pids():
|
||||
''' Find the pid of kvm processes
|
||||
@return a list of pids from running kvm
|
||||
'''
|
||||
pid = Popen("pidof kvm", shell=True, stdout=PIPE)
|
||||
pid = Popen("pidof qemu-system-x86_64", shell=True, stdout=PIPE)
|
||||
return pid.communicate()[0].split()
|
||||
|
||||
def fetch(vms):
|
||||
|
|
|
@ -85,14 +85,14 @@ def find_vm_names(pids):
|
|||
result = {}
|
||||
for pid in pids:
|
||||
cmdline = open("/proc/%s/cmdline" % pid, "r")
|
||||
result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_]*)\x00\-.*$",r"\1", cmdline.readline()))
|
||||
result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_-]*)\x00\-.*$",r"\1", cmdline.readline()))
|
||||
return result
|
||||
|
||||
def list_pids():
|
||||
''' Find the pid of kvm processes
|
||||
@return a list of pids from running kvm
|
||||
'''
|
||||
pid = Popen("pidof kvm", shell=True, stdout=PIPE)
|
||||
pid = Popen("pidof qemu-system-x86_64", shell=True, stdout=PIPE)
|
||||
return pid.communicate()[0].split()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -82,14 +82,14 @@ def find_vm_names(pids):
|
|||
result = {}
|
||||
for pid in pids:
|
||||
cmdline = open("/proc/%s/cmdline" % pid, "r")
|
||||
result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_]*)\x00\-.*$",r"\1", cmdline.readline()))
|
||||
result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_-]*)\x00\-.*$",r"\1", cmdline.readline()))
|
||||
return result
|
||||
|
||||
def list_pids():
|
||||
''' Find the pid of kvm processes
|
||||
@return a list of pids from running kvm
|
||||
'''
|
||||
pid = Popen("pidof kvm", shell=True, stdout=PIPE)
|
||||
pid = Popen("pidof qemu-system-x86_64", shell=True, stdout=PIPE)
|
||||
return pid.communicate()[0].split()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -84,7 +84,7 @@ def find_vm_names(pids):
|
|||
result = {}
|
||||
for pid in pids:
|
||||
cmdline = open("/proc/%s/cmdline" % pid, "r")
|
||||
result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_]*)\x00\-.*$",r"\1", cmdline.readline()))
|
||||
result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_-]*)\x00\-.*$",r"\1", cmdline.readline()))
|
||||
return result
|
||||
|
||||
def get_vm_mac(pid):
|
||||
|
@ -100,7 +100,7 @@ def list_pids():
|
|||
''' Find the pid of kvm processes
|
||||
@return a list of pids from running kvm
|
||||
'''
|
||||
pid = Popen("pidof kvm", shell=True, stdout=PIPE)
|
||||
pid = Popen("pidof qemu-system-x86_64", shell=True, stdout=PIPE)
|
||||
return pid.communicate()[0].split()
|
||||
|
||||
def find_vms_tap():
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
# http://api.openweathermap.org/data/<api>/weather?<query_string>
|
||||
#
|
||||
|
||||
## From Oct 9 2015 OpenWeather needs you to register and get an APIKEY
|
||||
# include this key by setting 'env.apikey' in munin plugin config, i.e.:
|
||||
# [openweather_*]
|
||||
# env.apikey XYZ
|
||||
|
||||
query_string=$(printf '%s' "${0#*_}" | tr '_' '=')
|
||||
TMPFILE=$(mktemp)
|
||||
trap 'rm -f $TMPFILE' EXIT
|
||||
|
@ -20,7 +25,7 @@ trap 'rm -f $TMPFILE' EXIT
|
|||
# API returns temp in K, we have to convert it in C
|
||||
KELVIN_BIAS=273
|
||||
|
||||
curl -s "http://api.openweathermap.org/data/2.5/weather?mode=xml&${query_string}" > $TMPFILE
|
||||
curl -s "http://api.openweathermap.org/data/2.5/weather?mode=xml&${query_string}&APPID=${apikey}" > $TMPFILE
|
||||
|
||||
CITY=$(fgrep "<city id=" $TMPFILE | tr -sc '[:alnum:]' ' ' | cut -d " " -f 6)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/local/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Plugin to monitor a ZFS Filesystem
|
||||
#
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue