mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-25 18:38:30 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
54dee0ad42
14 changed files with 1204 additions and 46 deletions
|
@ -7,12 +7,15 @@
|
||||||
|
|
||||||
=head1 AUTHOR AND COPYRIGHT
|
=head1 AUTHOR AND COPYRIGHT
|
||||||
|
|
||||||
Copyright 2011-2012 Luc Didry <luc AT didry.org>
|
Copyright 2011-2014 Luc Didry <luc AT didry.org>
|
||||||
|
|
||||||
=head1 HOWTO CONFIGURE AND USE :
|
=head1 HOWTO CONFIGURE AND USE :
|
||||||
|
|
||||||
=over
|
=over
|
||||||
|
|
||||||
|
=item - /etc/munin/plugins/du
|
||||||
|
cp du /etc/munin/plugins/
|
||||||
|
|
||||||
=item - /etc/munin/plugin-conf.d/du_
|
=item - /etc/munin/plugin-conf.d/du_
|
||||||
|
|
||||||
[du]
|
[du]
|
||||||
|
@ -22,14 +25,9 @@
|
||||||
env.suppr /home/ # PLEASE USE \# INSTEAD OF #
|
env.suppr /home/ # PLEASE USE \# INSTEAD OF #
|
||||||
timeout 900 # 15 MINUTES IN SECONDS
|
timeout 900 # 15 MINUTES IN SECONDS
|
||||||
|
|
||||||
=item - /etc/munin/plugins-enabled
|
|
||||||
|
|
||||||
ln -svf ../plugins-available/site/du
|
|
||||||
|
|
||||||
|
|
||||||
=item - restart Munin node
|
=item - restart Munin node
|
||||||
|
|
||||||
sudo killall -TERM munin-node
|
/etc/init.d/munin-node restart
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
@ -73,7 +71,7 @@ my $TIMEFILE="$Munin::Plugin::pluginstatedir/du.time";
|
||||||
|
|
||||||
##### autoconf
|
##### autoconf
|
||||||
if( (defined $ARGV[0]) && ($ARGV[0] eq "autoconf") ) {
|
if( (defined $ARGV[0]) && ($ARGV[0] eq "autoconf") ) {
|
||||||
print "yes\n";
|
print "no\n";
|
||||||
## Done !
|
## Done !
|
||||||
munin_exit_done();
|
munin_exit_done();
|
||||||
}
|
}
|
||||||
|
|
78
plugins/disk/du_pattern
Executable file
78
plugins/disk/du_pattern
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# -*- sh -*-
|
||||||
|
# vim: ft=sh
|
||||||
|
|
||||||
|
: << =cut
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
du_pattern - plugin to monitor files size selected and grouped by a pattern
|
||||||
|
|
||||||
|
=head1 CONFIGURATION
|
||||||
|
|
||||||
|
[du_pattern]
|
||||||
|
env.DIR /var/log/apache/
|
||||||
|
env.PATTERN www.example.com www.sample.com
|
||||||
|
|
||||||
|
In PATTERN, all items will be expanded like this : www.example.com*
|
||||||
|
In this example, you will monitor the size of :
|
||||||
|
/var/log/apache/www.example.com*
|
||||||
|
/var/log/apache/www.sample.com*
|
||||||
|
|
||||||
|
It's useful if you want to graph the size of your sites' log archives for example,
|
||||||
|
one graph per site.
|
||||||
|
|
||||||
|
=head1 AUTHOR AND COPYRIGHT
|
||||||
|
|
||||||
|
Copyright 2013-2014 Luc Didry <luc AT didry.org>
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
NAME=${0##*/du_pattern_}
|
||||||
|
|
||||||
|
if [ "$1" = "config" ]; then
|
||||||
|
echo "multigraph du_pattern_${NAME}"
|
||||||
|
echo "graph_title Files size in ${DIR}"
|
||||||
|
echo "graph_vlabel size of files"
|
||||||
|
echo "graph_category disk"
|
||||||
|
echo "graph_total Total"
|
||||||
|
echo "graph_info This graph shows the size of files grouped by a pattern."
|
||||||
|
FIRST=1
|
||||||
|
for i in ${PATTERN}
|
||||||
|
do
|
||||||
|
CLEAN=${i//\./_}
|
||||||
|
echo "$CLEAN.label $CLEAN"
|
||||||
|
if [[ $FIRST -eq 1 ]]
|
||||||
|
then
|
||||||
|
echo "$CLEAN.draw AREA"
|
||||||
|
FIRST=0
|
||||||
|
else
|
||||||
|
echo "$CLEAN.draw STACK"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in ${PATTERN}
|
||||||
|
do
|
||||||
|
CLEAN=${i//\./_}
|
||||||
|
FILES="${DIR}/${i}*"
|
||||||
|
echo -n "$CLEAN.value "
|
||||||
|
echo $(du -cbs ${FILES} | grep total | cut -f 1)
|
||||||
|
done
|
||||||
|
exit 0
|
|
@ -14,6 +14,7 @@
|
||||||
# - connect to a running ejabberd node
|
# - connect to a running ejabberd node
|
||||||
#
|
#
|
||||||
# OS: *NIX
|
# OS: *NIX
|
||||||
|
# Requires lsof/fstat for open_files.
|
||||||
#
|
#
|
||||||
# Author: Artem Sheremet <dot.doom@gmail.com>
|
# Author: Artem Sheremet <dot.doom@gmail.com>
|
||||||
#
|
#
|
||||||
|
@ -120,7 +121,7 @@ code.info The total amount of memory currently allocated for Erlang code. This m
|
||||||
ets.info The total amount of memory currently allocated for ets tables. This memory is part of the memory presented as system memory.
|
ets.info The total amount of memory currently allocated for ets tables. This memory is part of the memory presented as system memory.
|
||||||
INFO_FROM_DOC
|
INFO_FROM_DOC
|
||||||
else
|
else
|
||||||
pid=$(<$EJABBERD_PID_PATH)
|
local pid=$(<$EJABBERD_PID_PATH)
|
||||||
for memory_type in rss vsz; do
|
for memory_type in rss vsz; do
|
||||||
memory_value=$(ps -p $pid -o $memory_type=)
|
memory_value=$(ps -p $pid -o $memory_type=)
|
||||||
let memory_value=$memory_value*1024
|
let memory_value=$memory_value*1024
|
||||||
|
@ -140,42 +141,69 @@ function ejabberd_report_ports() {
|
||||||
local limit=$(ejabberd_exec 'os:getenv("ERL_MAX_PORTS").' | tr '"' ' ')
|
local limit=$(ejabberd_exec 'os:getenv("ERL_MAX_PORTS").' | tr '"' ' ')
|
||||||
# string "false" indicates that this variable is not defined, thus a default of 1024
|
# string "false" indicates that this variable is not defined, thus a default of 1024
|
||||||
[ $limit = false ] && limit=1024
|
[ $limit = false ] && limit=1024
|
||||||
local os_limit=$(ejabberd_exec 'os:cmd("ulimit -n").' | tr '"\\n' ' ')
|
|
||||||
if [ $limit -gt $os_limit ]; then
|
|
||||||
local real_limit=$os_limit
|
|
||||||
else
|
|
||||||
local real_limit=$limit
|
|
||||||
fi
|
|
||||||
if [ "$1" = "config" ]; then
|
if [ "$1" = "config" ]; then
|
||||||
cat <<CONFIG
|
cat <<CONFIG
|
||||||
graph_vlabel ports
|
graph_vlabel ports
|
||||||
opened.draw LINE
|
open.draw LINE
|
||||||
opened.label opened
|
open.label open
|
||||||
opened.info length(erlang:ports())
|
open.info length(erlang:ports())
|
||||||
limit.draw LINE2
|
limit.draw LINE2
|
||||||
limit.label limit
|
limit.label limit
|
||||||
limit.info ERL_MAX_PORTS environment variable inside ejabberd
|
limit.info ERL_MAX_PORTS environment variable inside ejabberd
|
||||||
os_limit.draw LINE2
|
|
||||||
os_limit.label os limit
|
|
||||||
os_limit.info "ulimit -n" from inside of ejabberd
|
|
||||||
CONFIG
|
CONFIG
|
||||||
warning='80%' critical='90%' print_adjusted_thresholds opened $real_limit
|
warning='80%' critical='90%' print_adjusted_thresholds open $limit
|
||||||
[ -n "$ERL_MAX_PORTS" ] && cat <<CONFIG_CONFIGURED
|
[ -n "$ERL_MAX_PORTS" ] && cat <<CONFIG_CONFIGURED
|
||||||
configured.draw LINE
|
configured.draw LINE
|
||||||
configured.label configured
|
configured.label configured
|
||||||
configured.info Configuration file value ERL_MAX_PORTS
|
configured.info Configuration file value ERL_MAX_PORTS
|
||||||
CONFIG_CONFIGURED
|
CONFIG_CONFIGURED
|
||||||
else
|
else
|
||||||
local opened=$(ejabberd_exec 'length(erlang:ports()).')
|
local open=$(ejabberd_exec 'length(erlang:ports()).')
|
||||||
cat <<DATA
|
cat <<DATA
|
||||||
opened.value $opened
|
open.value $open
|
||||||
limit.value $limit
|
limit.value $limit
|
||||||
os_limit.value $os_limit
|
|
||||||
DATA
|
DATA
|
||||||
[ -n "$ERL_MAX_PORTS" ] && echo "configured.value $ERL_MAX_PORTS"
|
[ -n "$ERL_MAX_PORTS" ] && echo "configured.value $ERL_MAX_PORTS"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function open_files_counter_util() {
|
||||||
|
if hash lsof &>/dev/null; then
|
||||||
|
echo lsof
|
||||||
|
return 0
|
||||||
|
elif hash fstat &>/dev/null; then
|
||||||
|
echo fstat
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function open_files_number() {
|
||||||
|
echo $[$($(open_files_counter_util) -np $(<$EJABBERD_PID_PATH) | wc -l)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
function ejabberd_report_open_files() {
|
||||||
|
# this spawns a child process, but in most cases the open files limit is inherited
|
||||||
|
local limit=$(ejabberd_exec 'os:cmd("ulimit -n").' | tr '"\\n' ' ')
|
||||||
|
if [ "$1" = "config" ]; then
|
||||||
|
cat <<CONFIG
|
||||||
|
graph_vlabel open files
|
||||||
|
open.draw LINE
|
||||||
|
open.label open
|
||||||
|
open.info number of open files as reported by $(open_files_counter_util)
|
||||||
|
limit.draw LINE2
|
||||||
|
limit.label limit
|
||||||
|
limit.info "ulimit -n" from inside of ejabberd
|
||||||
|
CONFIG
|
||||||
|
warning='80%' critical='90%' print_adjusted_thresholds open $limit
|
||||||
|
else
|
||||||
|
cat <<DATA
|
||||||
|
open.value $(open_files_number)
|
||||||
|
limit.value $limit
|
||||||
|
DATA
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function ejabberd_report_processes() {
|
function ejabberd_report_processes() {
|
||||||
local limit=$(ejabberd_exec 'erlang:system_info(process_limit).')
|
local limit=$(ejabberd_exec 'erlang:system_info(process_limit).')
|
||||||
if [ "$1" = "config" ]; then
|
if [ "$1" = "config" ]; then
|
||||||
|
@ -217,6 +245,7 @@ ports
|
||||||
online_users
|
online_users
|
||||||
registered_users
|
registered_users
|
||||||
SUGGESTIONS
|
SUGGESTIONS
|
||||||
|
open_files_counter_util &>/dev/null && echo open_files
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
config)
|
config)
|
||||||
|
|
|
@ -9,17 +9,26 @@
|
||||||
# Symlink this file to hadoop_hdfs_block or hadoop_hdfs_capacity to get block
|
# Symlink this file to hadoop_hdfs_block or hadoop_hdfs_capacity to get block
|
||||||
# or capacity informations about the DFS.
|
# or capacity informations about the DFS.
|
||||||
#
|
#
|
||||||
|
#
|
||||||
|
# Needs following minimal configuration in plugin-conf.d/munin-node:
|
||||||
|
# [hadoop_hdfs_block]
|
||||||
|
# user hdfs
|
||||||
|
#
|
||||||
|
# [hadoop_hdfs_capacity]
|
||||||
|
# user hdfs
|
||||||
|
#
|
||||||
# Author: KARASZI Istvan <muninexchange@spam.raszi.hu>
|
# Author: KARASZI Istvan <muninexchange@spam.raszi.hu>
|
||||||
#
|
#
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use File::Basename qw(basename);
|
use File::Basename qw(basename);
|
||||||
|
use Munin::Plugin;
|
||||||
|
|
||||||
my $type = &getType($0);
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# main
|
# main
|
||||||
#
|
#
|
||||||
|
my $type = &getType($0);
|
||||||
if ($ARGV[0]) {
|
if ($ARGV[0]) {
|
||||||
if ($ARGV[0] eq "autoconf") {
|
if ($ARGV[0] eq "autoconf") {
|
||||||
print "yes\n";
|
print "yes\n";
|
||||||
|
@ -95,9 +104,12 @@ sub getCapacity {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getStatistics {
|
sub getStatistics {
|
||||||
open(DFSADMIN, "hadoop dfsadmin -report|") || die("Cannot open dfsadmin: $!");
|
open(DFSADMIN, "hdfs dfsadmin -report|") || die("Cannot open dfsadmin: $!");
|
||||||
while(defined(my $line = <DFSADMIN>)) {
|
while(defined(my $line = <DFSADMIN>)) {
|
||||||
chomp($line);
|
chomp($line);
|
||||||
|
if ($line =~ /-------------------------------------------------/) {
|
||||||
|
last
|
||||||
|
}
|
||||||
|
|
||||||
if ($type eq "block") {
|
if ($type eq "block") {
|
||||||
&getBlock($line);
|
&getBlock($line);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
if [ "$1" = "config" ]; then
|
if [ "$1" = "config" ]; then
|
||||||
echo "graph_title Mailman Queue"
|
echo "graph_title Mailman Queue"
|
||||||
|
echo "graph_category mailman"
|
||||||
echo "graph_args --base 1000 -l 0"
|
echo "graph_args --base 1000 -l 0"
|
||||||
echo "archive.label Archive"
|
echo "archive.label Archive"
|
||||||
echo "archive.draw LINE2"
|
echo "archive.draw LINE2"
|
269
plugins/mail/postfwd2
Executable file
269
plugins/mail/postfwd2
Executable file
|
@ -0,0 +1,269 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
# vim: set filetype=perl sw=4 tabstop=4 expandtab smartindent: #
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
postfwd2 - plugin to get stats from postfwd2
|
||||||
|
|
||||||
|
=head1 AUTHOR AND COPYRIGHT
|
||||||
|
|
||||||
|
Copyright 2013-2014 Luc Didry <luc AT didry.org>
|
||||||
|
|
||||||
|
=head1 HOWTO CONFIGURE AND USE :
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item - /etc/munin/plugin-conf.d/postfwd2
|
||||||
|
|
||||||
|
[postfwd2]
|
||||||
|
user root
|
||||||
|
env.path /usr/local/sbin/postfwd2 # OPTIONAL : looks for postfwd2 in /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin
|
||||||
|
env.include .*ISBAD #OPTIONAL
|
||||||
|
env.exclude .*ISGOOD #OPTIONAL
|
||||||
|
|
||||||
|
=item - env.include and env.exclude
|
||||||
|
|
||||||
|
This are perl regexp.
|
||||||
|
If env.include is set and env.exclude is not, only the policy which name
|
||||||
|
matchs will be used.
|
||||||
|
If env.exclude is set and env.include is not, only the policy which name NOT
|
||||||
|
matchs will be used.
|
||||||
|
If both are set, a policy which name matchs the both regex will be used, a
|
||||||
|
policy which matchs only the exclude regexp will NOT be used and a policy
|
||||||
|
which match not the exclude regex will be used, even if it not matchs the
|
||||||
|
include regexp.
|
||||||
|
if none are set, all the policy will be used.
|
||||||
|
|
||||||
|
|
||||||
|
=item - /etc/munin/plugins
|
||||||
|
|
||||||
|
cp postfwd2 /etc/munin/plugins
|
||||||
|
|
||||||
|
|
||||||
|
=item - restart Munin node
|
||||||
|
|
||||||
|
service munin-node restart
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation, either version 3 of the License, or 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/>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use Munin::Plugin;
|
||||||
|
|
||||||
|
need_multigraph();
|
||||||
|
|
||||||
|
my @keys =qw/cache_queries cache_stats policy_requests policy_timeout policy_matchs/;
|
||||||
|
my %graphs = (
|
||||||
|
cache_queries => {
|
||||||
|
title => 'Cache queries',
|
||||||
|
vlabel => 'Nb of cache queries',
|
||||||
|
series => {
|
||||||
|
cache_queries => {
|
||||||
|
label => 'Cache queries',
|
||||||
|
type => 'COUNTER'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cache_stats => {
|
||||||
|
title => 'Cache stats',
|
||||||
|
vlabel => 'percent',
|
||||||
|
series => {
|
||||||
|
cache_requests => {
|
||||||
|
label => 'Requests hitrate',
|
||||||
|
type => 'GAUGE'
|
||||||
|
},
|
||||||
|
cache_dns => {
|
||||||
|
label => 'Dns hitrate',
|
||||||
|
type => 'GAUGE'
|
||||||
|
},
|
||||||
|
cache_rates => {
|
||||||
|
label => 'Rates hitrate',
|
||||||
|
type => 'GAUGE'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
policy_requests => {
|
||||||
|
title => 'Policy requests',
|
||||||
|
vlabel => 'Nb of policy requests',
|
||||||
|
series => {
|
||||||
|
policy_requests => {
|
||||||
|
label => 'Policy requests',
|
||||||
|
type => 'COUNTER'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
policy_timeout => {
|
||||||
|
title => 'Policy timeout',
|
||||||
|
vlabel => 'Nb of policy timeout',
|
||||||
|
series => {
|
||||||
|
policy_timeout => {
|
||||||
|
label => 'Policy timeout',
|
||||||
|
type => 'COUNTER'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
policy_matchs => {
|
||||||
|
title => 'Policy matchs',
|
||||||
|
vlabel => 'Matchs percentage'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
my $PLUGIN_NAME = 'postfwd2';
|
||||||
|
my $CACHEFILE="$Munin::Plugin::pluginstatedir/postfwd2.cache";
|
||||||
|
|
||||||
|
my ($include, $exclude) = ($ENV{include}, $ENV{exclude});
|
||||||
|
if (defined($include) && (!defined($exclude))) {
|
||||||
|
$exclude = '.*';
|
||||||
|
}
|
||||||
|
|
||||||
|
##### Cache file, to continue to graph old policies which doesn't exist anymore
|
||||||
|
if (!(-f $CACHEFILE) || !(-e $CACHEFILE)) {
|
||||||
|
open (FILE, ">", $CACHEFILE) or munin_exit_fail();
|
||||||
|
close(FILE);
|
||||||
|
}
|
||||||
|
open (FILE, "<", $CACHEFILE) or munin_exit_fail();
|
||||||
|
my @policies = <FILE>;
|
||||||
|
close(FILE);
|
||||||
|
my %policies = map { $_, 1 } @policies;
|
||||||
|
foreach my $policy (keys %policies) {
|
||||||
|
chomp $policy;
|
||||||
|
$graphs{policy_matchs}->{series}->{$policy}->{type} = 'GAUGE';
|
||||||
|
$graphs{policy_matchs}->{series}->{$policy}->{label} = $policy;
|
||||||
|
$graphs{policy_matchs}->{series}->{$policy}->{value} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
##### Check postfwd2 path
|
||||||
|
if (!defined($ENV{path}) || !(-x $ENV{path})) {
|
||||||
|
foreach my $path (qw{/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin}) {
|
||||||
|
$ENV{path} = $path.'/postfwd2' if (!defined($ENV{path}) && -x $path.'/postfwd2');
|
||||||
|
last if (defined($ENV{path}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
munin_exit_fail() unless (defined($ENV{path}) && -x $ENV{path});
|
||||||
|
|
||||||
|
##### I have to parse the output BEFORE config, since policy matchs are dependant of the postfwd --dumpstats output
|
||||||
|
open(DATA, $ENV{path}.' --dumpstats |') or munin_exit_fail();
|
||||||
|
my $total_requests;
|
||||||
|
while(defined (my $data = <DATA>)) {
|
||||||
|
if ($data =~ m/^\[STATS\] postfwd2::cache .*: (\d+) queries since/) {
|
||||||
|
$graphs{cache_queries}->{series}->{cache_queries}->{value} = $1;
|
||||||
|
}
|
||||||
|
if ($data =~ m/^\[STATS\] Hitrates: ([\.\d]+)% requests, ([\.\d]+)% dns, ([\.\d]+)% rates$/) {
|
||||||
|
$graphs{cache_stats}->{series}->{cache_requests}->{value} = $1;
|
||||||
|
$graphs{cache_stats}->{series}->{cache_dns}->{value} = $2;
|
||||||
|
$graphs{cache_stats}->{series}->{cache_rates}->{value} = $3;
|
||||||
|
}
|
||||||
|
if ($data =~ m/^\[STATS\] postfwd2::policy .*: (\d+) requests since/) {
|
||||||
|
$graphs{policy_requests}->{series}->{policy_requests}->{value} = $1;
|
||||||
|
$total_requests = $1;
|
||||||
|
}
|
||||||
|
if ($data =~ m/^\[STATS\] Timeouts: .*% \((\d+) of \d+ dns queries\)$/) {
|
||||||
|
$graphs{policy_timeout}->{series}->{policy_timeout}->{value} = $1;
|
||||||
|
}
|
||||||
|
if ($data =~ m/^\[STATS\] +(\d+) matches for id: (.*)$/) {
|
||||||
|
my ($value, $label) = ($1, $2);
|
||||||
|
if ( ( !defined($exclude) ) || ( $label !~ m/$exclude/ || ( defined($include) && $label =~ m/$include/ ) ) ) {
|
||||||
|
if (!defined($policies{$label})) {
|
||||||
|
open (FILE, ">>", $CACHEFILE) or munin_exit_fail();
|
||||||
|
print FILE $label, "\n";
|
||||||
|
close(FILE);
|
||||||
|
$graphs{policy_matchs}->{series}->{$label}->{type} = 'GAUGE';
|
||||||
|
$graphs{policy_matchs}->{series}->{$label}->{label} = $label;
|
||||||
|
}
|
||||||
|
$graphs{policy_matchs}->{series}->{$label}->{value} = sprintf("%.2f", 100*$value/$total_requests);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(DATA);
|
||||||
|
|
||||||
|
##### config
|
||||||
|
if( (defined $ARGV[0]) && ($ARGV[0] eq 'config') ) {
|
||||||
|
foreach my $key (@keys) {
|
||||||
|
print 'multigraph postfwd2_', $key, "\n";
|
||||||
|
print 'graph_title Postfwd2 ', $graphs{$key}->{title}, "\n";
|
||||||
|
print 'graph_vlabel ', $graphs{$key}->{vlabel}, "\n";
|
||||||
|
my $args = ($key eq 'cache_stats') ? ' --upper-limit 100 --rigid' : '';
|
||||||
|
print 'graph_args --lower-limit 0', $args, "\n";
|
||||||
|
print 'graph_category mail', "\n";
|
||||||
|
if ($key eq 'policy_matchs') {
|
||||||
|
print 'graph_width 600', "\n";
|
||||||
|
my @pol_keys = sort { $graphs{$key}->{series}->{$b}->{value} <=> $graphs{$key}->{series}->{$a}->{value} } keys %{$graphs{$key}->{series}};
|
||||||
|
foreach my $label (@pol_keys) {
|
||||||
|
print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
|
||||||
|
print $label, '.draw LINE', "\n";
|
||||||
|
print $label, '.type ', $graphs{$key}->{series}->{$label}->{type}, "\n";
|
||||||
|
}
|
||||||
|
foreach my $label (@pol_keys) {
|
||||||
|
print 'multigraph postfwd2_', $key, '.', $label, "\n";
|
||||||
|
print 'graph_title Postfwd2 ', $label, "\n";
|
||||||
|
print 'graph_vlabel ', $graphs{$key}->{vlabel}, "\n";
|
||||||
|
print 'graph_width 600', "\n";
|
||||||
|
print 'graph_args --lower-limit 0 ', $args, "\n";
|
||||||
|
print 'graph_category others', "\n";
|
||||||
|
print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
|
||||||
|
print $label, '.draw LINE', "\n";
|
||||||
|
print $label, '.type GAUGE', "\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach my $label (keys %{$graphs{$key}->{series}}) {
|
||||||
|
print $label, '.label ', $graphs{$key}->{series}->{$label}->{label}, "\n";
|
||||||
|
print $label, '.draw AREASTACK', "\n";
|
||||||
|
print $label, '.type ', $graphs{$key}->{series}->{$label}->{type}, "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
munin_exit_done();
|
||||||
|
}
|
||||||
|
|
||||||
|
##### fetch
|
||||||
|
foreach my $key (@keys) {
|
||||||
|
print 'multigraph postfwd2_', $key, "\n";
|
||||||
|
if ($key eq 'policy_matchs') {
|
||||||
|
my @pol_keys = sort { $graphs{$key}->{series}->{$b}->{value} <=> $graphs{$key}->{series}->{$a}->{value} } keys %{$graphs{$key}->{series}};
|
||||||
|
foreach my $label (@pol_keys) {
|
||||||
|
print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
|
||||||
|
}
|
||||||
|
foreach my $label (@pol_keys) {
|
||||||
|
print 'multigraph postfwd2_', $key, '.', $label, "\n";
|
||||||
|
print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach my $label (keys %{$graphs{$key}->{series}}) {
|
||||||
|
print $label, '.value ', $graphs{$key}->{series}->{$label}->{value}, "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
munin_exit_done();
|
||||||
|
|
||||||
|
#
|
||||||
|
##
|
||||||
|
### INTERNALS FONCTIONS
|
||||||
|
###############################################################################
|
||||||
|
sub munin_exit_done {
|
||||||
|
munin_exit(0);
|
||||||
|
} ## sub munin_exit_done
|
||||||
|
|
||||||
|
sub munin_exit_fail {
|
||||||
|
munin_exit(1);
|
||||||
|
} ## sub munin_exit_fail
|
||||||
|
|
||||||
|
sub munin_exit {
|
||||||
|
my $exitcode = shift;
|
||||||
|
exit($exitcode) if(defined $exitcode);
|
||||||
|
exit(1);
|
||||||
|
} ## sub munin_exit
|
189
plugins/mysql/mysql_connections_per_user
Executable file
189
plugins/mysql/mysql_connections_per_user
Executable file
|
@ -0,0 +1,189 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
#
|
||||||
|
# Copyright (C) 2008 Rackspace US, Inc. <http://www.rackspace.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; 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, see http://www.gnu.org/licenses/gpl.txt
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# This plugin is based off of the Connection Usage
|
||||||
|
# section of the MySQL Connection Health Page
|
||||||
|
#
|
||||||
|
# http://dev.mysql.com/doc/administrator/en/mysql-administrator-health-connection-health.html
|
||||||
|
#
|
||||||
|
# To enable, link mysql_connections to this file. E.g.
|
||||||
|
#
|
||||||
|
# ln -s /usr/share/node/node/plugins/mysql_connections /etc/munin/plugins/mysql_connections
|
||||||
|
#
|
||||||
|
# Revision 1.0 2007/08/03
|
||||||
|
# Created by Justin Shepherd <galstrom21@gmail.com>
|
||||||
|
#
|
||||||
|
# Revision 2.0 2013/01/02
|
||||||
|
# Per user support by anarcat@koumbit.org
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
#
|
||||||
|
# config
|
||||||
|
# autoconf
|
||||||
|
#
|
||||||
|
# Configuration variables
|
||||||
|
#
|
||||||
|
# mysqlopts - Options to pass to mysql
|
||||||
|
# mysqladmin - Override location of mysqladmin
|
||||||
|
# numusers - Override maximum number of users to display
|
||||||
|
# warning - Override default warning limit
|
||||||
|
# critical - Override default critical limit
|
||||||
|
#
|
||||||
|
#%# family=auto
|
||||||
|
#%# capabilities=autoconf
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
# Define the mysqladmin paths, and commands
|
||||||
|
my $MYSQLADMIN = $ENV{mysqladmin} || "mysqladmin";
|
||||||
|
my $TEST_COMMAND = "$MYSQLADMIN $ENV{mysqlopts} processlist";
|
||||||
|
my $MYSQL_VARIABLES = "$MYSQLADMIN $ENV{mysqlopts} extended-status variables";
|
||||||
|
my $warning = $ENV{warning} || "80";
|
||||||
|
my $critical = $ENV{critical} || "90";
|
||||||
|
my $numusers = $ENV{numusers} || 10;
|
||||||
|
|
||||||
|
# Pull in any arguments
|
||||||
|
my $arg = shift();
|
||||||
|
|
||||||
|
# Check to see how the script was called
|
||||||
|
if ($arg eq 'config') {
|
||||||
|
print_graph_information();
|
||||||
|
} elsif ($arg eq 'autoconf') {
|
||||||
|
if (test_service()) { print "yes\n"; }
|
||||||
|
else { print "no\n"; }
|
||||||
|
} else {
|
||||||
|
print_graph_data();
|
||||||
|
}
|
||||||
|
exit;
|
||||||
|
|
||||||
|
sub print_graph_data() {
|
||||||
|
# Define the values that are returned to munin
|
||||||
|
|
||||||
|
# Return the values to Munin
|
||||||
|
my $counts = count_thread_users();
|
||||||
|
my %counts = %{$counts};
|
||||||
|
|
||||||
|
sub valsort {
|
||||||
|
return $counts{$a} <=> $counts{$b};
|
||||||
|
}
|
||||||
|
my $i = 0;
|
||||||
|
my $total = 0;
|
||||||
|
foreach my $user (sort valsort keys(%counts)) {
|
||||||
|
last if $i++ >= $numusers;
|
||||||
|
$total += $counts{$user};
|
||||||
|
print "$user.value $counts{$user}\n";
|
||||||
|
}
|
||||||
|
my $other = poll_variables($MYSQL_VARIABLES,"Threads_connected") - $total;
|
||||||
|
print "other.value $other\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub poll_variables {
|
||||||
|
my $command = shift;
|
||||||
|
my $expression = shift;
|
||||||
|
my $ret = 0;
|
||||||
|
open(SERVICE, "$command |")
|
||||||
|
or die("Coult not execute '$command': $!");
|
||||||
|
while (<SERVICE>) {
|
||||||
|
my ($field, $value) = (m/(\w+).*?(\d+(?:\.\d+)?)/);
|
||||||
|
next unless ($field);
|
||||||
|
if ($field eq $expression ) {
|
||||||
|
$ret = "$value";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(SERVICE);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub print_graph_information {
|
||||||
|
print <<EOM;
|
||||||
|
graph_title MySQL Connections per user
|
||||||
|
graph_args --base 1000 --lower-limit 0
|
||||||
|
graph_vlabel Connections
|
||||||
|
graph_info The number of current connexions per user.
|
||||||
|
graph_category mysql
|
||||||
|
graph_total Total
|
||||||
|
EOM
|
||||||
|
|
||||||
|
my $counts = count_thread_users();
|
||||||
|
my %counts = %{$counts};
|
||||||
|
my $stacked = 0;
|
||||||
|
|
||||||
|
sub valsort {
|
||||||
|
return $counts{$a} <=> $counts{$b};
|
||||||
|
}
|
||||||
|
my $i = 0;
|
||||||
|
foreach my $user (sort valsort keys(%counts)) {
|
||||||
|
last if $i++ >= $numusers;
|
||||||
|
print <<EOM;
|
||||||
|
$user.label $user
|
||||||
|
$user.info Number of connexions used by user $user
|
||||||
|
EOM
|
||||||
|
print "$user.draw ";
|
||||||
|
# if we already printed an entry, make the next ones stacked
|
||||||
|
if ($i > 1) {
|
||||||
|
print "STACK\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print "AREA\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print <<EOM;
|
||||||
|
other.label Others
|
||||||
|
other.draw STACK
|
||||||
|
other.info Other connected threads not in the top $numusers
|
||||||
|
EOM
|
||||||
|
}
|
||||||
|
|
||||||
|
sub count_thread_users {
|
||||||
|
my %counts = ();
|
||||||
|
my $command = 'mysql -N -B -e "SHOW PROCESSLIST;"';
|
||||||
|
open(SERVICE, "$command |")
|
||||||
|
or die("Could not execute '$command': $!");
|
||||||
|
while (<SERVICE>) {
|
||||||
|
my ($threadid, $user) = split "\t";
|
||||||
|
next unless ($threadid);
|
||||||
|
$counts{$user} = 0 unless defined($counts{$user});
|
||||||
|
$counts{$user}++;
|
||||||
|
}
|
||||||
|
return \%counts;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_service {
|
||||||
|
my $return = 1;
|
||||||
|
system ("$MYSQLADMIN --version >/dev/null 2>/dev/null");
|
||||||
|
if ($? == 0)
|
||||||
|
{
|
||||||
|
system ("$TEST_COMMAND >/dev/null 2>/dev/null");
|
||||||
|
if ($? == 0)
|
||||||
|
{
|
||||||
|
print "yes\n";
|
||||||
|
$return = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print "no (could not connect to mysql)\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print "no (mysqladmin not found)\n";
|
||||||
|
}
|
||||||
|
exit $return;
|
||||||
|
}
|
144
plugins/network/netatalk3
Executable file
144
plugins/network/netatalk3
Executable file
|
@ -0,0 +1,144 @@
|
||||||
|
#!/bin/bash -
|
||||||
|
#
|
||||||
|
#### Abstract ################################################################
|
||||||
|
#
|
||||||
|
# Munin contributed plugin to measure open, locked and files being hold by
|
||||||
|
# Netatalk version 3.*;
|
||||||
|
#
|
||||||
|
#### Author ##################################################################
|
||||||
|
#
|
||||||
|
# Otavio Fernandes <otaviof@gmail.com>
|
||||||
|
# Wednesday, 01/01/2014
|
||||||
|
#
|
||||||
|
|
||||||
|
#### Functions ###############################################################
|
||||||
|
#
|
||||||
|
|
||||||
|
function afpd_full_path () {
|
||||||
|
echo $(which afpd |head -n 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function afp_related_file_exists () {
|
||||||
|
local afp_file_path=$1
|
||||||
|
if [ -z "$afp_file_path" -o ! -f "$afp_file_path" ]; then
|
||||||
|
echo "ERROR: AFP related file not found: \"${afpd_bin_path}\";" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_netatalk_version_3 () {
|
||||||
|
local afpd_bin_path=$1
|
||||||
|
version_string="$(${afpd_bin_path} -version |head -n1 |grep '^afpd' |cut -d' ' -f2)"
|
||||||
|
if [[ $version_string != 3\.* ]]; then
|
||||||
|
cat <<EOM >&2
|
||||||
|
ERROR: Netatalk is not version 3.
|
||||||
|
Binary: ${afpd_bin_path};
|
||||||
|
Version: ${version_string};
|
||||||
|
EOM
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function count_running_procs () {
|
||||||
|
local afpd_bin_path=$1
|
||||||
|
echo $(ps ax --no-headers -o command |grep "^${afpd_bin_path}" |wc -l)
|
||||||
|
}
|
||||||
|
|
||||||
|
function count_connected_users () {
|
||||||
|
local afpd_bin_path=$1
|
||||||
|
afpd_procs=$(ps anx --no-headers -o uid,command |grep -E "\w+\d+*\s${afpd_bin_path}" |wc -l)
|
||||||
|
# one of those processess will be always from root user, so it's not being
|
||||||
|
# used to externaly connect volumes, therefor being disconsider.
|
||||||
|
echo $(echo "${afpd_procs} - 1" |bc)
|
||||||
|
}
|
||||||
|
|
||||||
|
function base_lsof () {
|
||||||
|
local afpd_bin_path=$1
|
||||||
|
process_name="$(basename ${afpd_bin_path})"
|
||||||
|
excluded_fds="^DEL,^err,^jld,^ltx,^Mxx,^m86,^mem,^mmap,^pd,^rtd,^tr,^txt,^v86"
|
||||||
|
echo "lsof -a -c ${process_name} -d ${excluded_fds}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function count_locked_files () {
|
||||||
|
local afpd_bin_path=$1
|
||||||
|
cmd_suffix="$(base_lsof "${afpd_bin_path}")"
|
||||||
|
echo "$(${cmd_suffix} -F -l |grep '^l[rRwWu]' |wc -l)"
|
||||||
|
}
|
||||||
|
|
||||||
|
function probe_afp_conf_file () {
|
||||||
|
local afpd_bin_path=$1
|
||||||
|
echo "$(${afpd_bin_path} -version 2>&1 |grep -E '^\s+afp.conf\:' |awk '{print $2}')"
|
||||||
|
}
|
||||||
|
|
||||||
|
function count_open_shares () {
|
||||||
|
local afpd_bin_path=$1
|
||||||
|
local afp_conf_path=$2
|
||||||
|
|
||||||
|
mounted=0
|
||||||
|
declare -a shares=($(grep '^path.*\=' ${afp_conf_path} |awk -F '=' '{print $2}' |sed -E 's/^\s+//g'))
|
||||||
|
if [ ! -z "$shares" ]; then
|
||||||
|
# narrowing lsof results to only list configured mount directories
|
||||||
|
cmd_lookup_prefix=$(echo ${shares[@]} |tr " " "|")
|
||||||
|
cmd_suffix="$(base_lsof "${afpd_bin_path}")"
|
||||||
|
mounted=$(${cmd_suffix} -F n |grep '^n' |egrep "(${cmd_lookup_prefix})" |wc -l)
|
||||||
|
fi
|
||||||
|
echo $mounted
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#### Main ####################################################################
|
||||||
|
# For all routines, holds the entry points dealing with the informed parameter
|
||||||
|
# or lack of it, meaning just print out collected data.
|
||||||
|
#
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
config)
|
||||||
|
# printing configuration for this plugin's produced data
|
||||||
|
cat <<EOM
|
||||||
|
graph_title Netatalk v3 Status
|
||||||
|
graph_title Netatalk status
|
||||||
|
graph_args --logarithmic --lower-limit 0.1
|
||||||
|
graph_vlabel Number
|
||||||
|
graph_category network
|
||||||
|
proc.label Running processes
|
||||||
|
proc.info Running AFPd processes
|
||||||
|
proc.min 0
|
||||||
|
user.label Connected users
|
||||||
|
user.info Connected users
|
||||||
|
user.min 0
|
||||||
|
lock.label Locked files
|
||||||
|
lock.info AFPd locked files
|
||||||
|
lock.min 0
|
||||||
|
share.label Open shares
|
||||||
|
share.info Netatalk open shares
|
||||||
|
share.min 0
|
||||||
|
EOM
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
#### Boilerplates ####################################################
|
||||||
|
# Locating AFP related files:
|
||||||
|
# * Binary: Using the first result of "which" command;
|
||||||
|
# * Config: Using "afpd" with paremeters to pring configuration file
|
||||||
|
# location;
|
||||||
|
#
|
||||||
|
|
||||||
|
AFPD_PATH="$(afpd_full_path)"
|
||||||
|
afp_related_file_exists "${AFPD_PATH}"
|
||||||
|
is_netatalk_version_3 "${AFPD_PATH}"
|
||||||
|
|
||||||
|
AFP_CONF_PATH="$(probe_afp_conf_file "${AFPD_PATH}")"
|
||||||
|
afp_related_file_exists "${AFP_CONF_PATH}"
|
||||||
|
|
||||||
|
#### Collecting Metrics ##############################################
|
||||||
|
#
|
||||||
|
echo "proc.value" $(count_running_procs "${AFPD_PATH}")
|
||||||
|
echo "user.value" $(count_connected_users "${AFPD_PATH}")
|
||||||
|
echo "lock.value" $(count_locked_files "${AFPD_PATH}")
|
||||||
|
echo "share.value" $(count_open_shares "${AFPD_PATH}" "${AFP_CONF_PATH}")
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# EOF
|
|
@ -25,7 +25,7 @@
|
||||||
# Use it in your site configuration (/etc/nginx/sites-enabled/anything.conf):
|
# Use it in your site configuration (/etc/nginx/sites-enabled/anything.conf):
|
||||||
# access_log /var/log/nginx/upstream.log upstream;
|
# access_log /var/log/nginx/upstream.log upstream;
|
||||||
#
|
#
|
||||||
# And specify some options in munin-node.conf:
|
# And specify some options in /etc/munin/plugin-conf.d/munin-node:
|
||||||
#
|
#
|
||||||
# [nginx_upstream_multi_upstream]
|
# [nginx_upstream_multi_upstream]
|
||||||
# env.graphs cache http time request
|
# env.graphs cache http time request
|
||||||
|
|
187
plugins/snmp/snmp__juniper
Executable file
187
plugins/snmp/snmp__juniper
Executable file
|
@ -0,0 +1,187 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright (C) 2014 Johann Schmitz <johann@j-schmitz.net>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Library General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 only
|
||||||
|
#
|
||||||
|
# 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 Library General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Library General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
snmp__juniper - Health monitoring plugin for Juniper firewalls.
|
||||||
|
|
||||||
|
=head1 CONFIGURATION
|
||||||
|
|
||||||
|
Make sure your Juniper device is accessible via SNMP (e.g. via snmpwalk) and the munin-node
|
||||||
|
has been configured correctly.
|
||||||
|
|
||||||
|
=head1 MAGIC MARKERS
|
||||||
|
|
||||||
|
#%# family=snmpauto
|
||||||
|
#%# capabilities=snmpconf
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
0.0.1
|
||||||
|
|
||||||
|
=head1 BUGS
|
||||||
|
|
||||||
|
Open a ticket at https://github.com/ercpe/contrib if you find one.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Johann Schmitz <johann@j-schmitz.net>
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
GPLv2
|
||||||
|
|
||||||
|
=cut
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from pysnmp.entity.rfc3413.oneliner import cmdgen
|
||||||
|
|
||||||
|
host = None
|
||||||
|
port = os.getenv('port', 161)
|
||||||
|
community = os.getenv('community', None)
|
||||||
|
|
||||||
|
debug = bool(os.getenv('MUNIN_DEBUG', os.getenv('DEBUG', 0)))
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-7s %(message)s')
|
||||||
|
|
||||||
|
try:
|
||||||
|
match = re.search("^(?:|.*\/)snmp_([^_]+)_juniper$", sys.argv[0])
|
||||||
|
host = match.group(1)
|
||||||
|
request = match.group(2)
|
||||||
|
match = re.search("^([^:]+):(\d+)$", host)
|
||||||
|
if match is not None:
|
||||||
|
host = match.group(1)
|
||||||
|
port = match.group(2)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
jnxOperatingTable = '1.3.6.1.4.1.2636.3.1.13.1.5'
|
||||||
|
|
||||||
|
jnxOperatingTemp = '1.3.6.1.4.1.2636.3.1.13.1.7'
|
||||||
|
jnxOperatingCPU = '1.3.6.1.4.1.2636.3.1.13.1.8'
|
||||||
|
jnxOperatingBuffer = '1.3.6.1.4.1.2636.3.1.13.1.11'
|
||||||
|
|
||||||
|
class JunOSSnmpClient(object):
|
||||||
|
def __init__(self, host, port, community):
|
||||||
|
self.hostname = host
|
||||||
|
self.transport = cmdgen.UdpTransportTarget((host, int(port)))
|
||||||
|
self.auth = cmdgen.CommunityData('test-agent', community)
|
||||||
|
self.gen = cmdgen.CommandGenerator()
|
||||||
|
|
||||||
|
def get_devices(self):
|
||||||
|
errorIndication, errorStatus, errorIndex, varBindTable = self.gen.bulkCmd(
|
||||||
|
self.auth,
|
||||||
|
self.transport,
|
||||||
|
0, 20,
|
||||||
|
jnxOperatingTable)
|
||||||
|
# ignoreNonIncreasingOids=True) # only available with pysnmp >= 4.2.4 (?)
|
||||||
|
|
||||||
|
if errorIndication:
|
||||||
|
logging.error("SNMP bulkCmd for devices failed: %s, %s, %s" % (errorIndication, errorStatus, errorIndex))
|
||||||
|
return {}
|
||||||
|
|
||||||
|
devices = {}
|
||||||
|
for row in varBindTable:
|
||||||
|
for name, value in row:
|
||||||
|
if not str(name).startswith(jnxOperatingTable):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# TODO: Find a better way to get the routing engines in a cluster
|
||||||
|
if str(value).endswith(' Routing Engine'):
|
||||||
|
devices[str(name)[len(jnxOperatingTable):]] = re.sub("[^\w]", '_', str(value).replace(' Routing Engine', ''))
|
||||||
|
return devices
|
||||||
|
|
||||||
|
def get_one(self, prefix_oid, suffix):
|
||||||
|
oid = prefix_oid + suffix
|
||||||
|
errorIndication, errorStatus, errorIndex, varBindTable = self.gen.getCmd(
|
||||||
|
self.auth,
|
||||||
|
self.transport,
|
||||||
|
oid)
|
||||||
|
|
||||||
|
if errorIndication:
|
||||||
|
logging.error("SNMP getCmd for %s failed: %s, %s, %s" % (oid, errorIndication, errorStatus, errorIndex))
|
||||||
|
return None
|
||||||
|
|
||||||
|
return int(varBindTable[0][1])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
devs = self.get_devices()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'temp': dict([(name, self.get_one(jnxOperatingTemp, suffix)) for suffix, name in devs.iteritems()]),
|
||||||
|
'cpu': dict([(name, self.get_one(jnxOperatingCPU, suffix)) for suffix, name in devs.iteritems()]),
|
||||||
|
'buffer': dict([(name, self.get_one(jnxOperatingBuffer, suffix)) for suffix, name in devs.iteritems()]),
|
||||||
|
}
|
||||||
|
|
||||||
|
def print_config(self):
|
||||||
|
devices = self.get_devices()
|
||||||
|
|
||||||
|
data_def = [
|
||||||
|
('temp', self.hostname, 'System temperature', '--base 1000', 'System temperature in C', 'system'),
|
||||||
|
('cpu', self.hostname, 'CPU usage', '--base 1000 -l 0 --upper-limit 100', 'CPU usage in %', 'system'),
|
||||||
|
('buffer', self.hostname, 'Buffer usage', '--base 1000 -l 0 --upper-limit 100', 'Buffer usage in %', 'system'),
|
||||||
|
]
|
||||||
|
|
||||||
|
for datarow, hostname, title, args, vlabel, category in data_def:
|
||||||
|
print """multigraph juniper_{datarow}
|
||||||
|
host_name {hostname}
|
||||||
|
graph_title {title}
|
||||||
|
graph_vlabel {vlabel}
|
||||||
|
graph_args {args}
|
||||||
|
graph_category {category}
|
||||||
|
graph_info {title}""".format(datarow=datarow, hostname=hostname, title=title, args=args, vlabel=vlabel, category=category)
|
||||||
|
|
||||||
|
for suffix, node in devices.iteritems():
|
||||||
|
ident = "%s_%s" % (datarow, node)
|
||||||
|
print """{label}.info {title} on {node}
|
||||||
|
{label}.label {node}
|
||||||
|
{label}.type GAUGE
|
||||||
|
{label}.min 0""".format(title=title, label=ident, node=node)
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
data = self.get_data()
|
||||||
|
|
||||||
|
for pre, values in data.iteritems():
|
||||||
|
print "multigraph juniper_%s" % pre
|
||||||
|
for node, value in values.iteritems():
|
||||||
|
print "%s_%s.value %s" % (pre, node, value)
|
||||||
|
|
||||||
|
c = JunOSSnmpClient(host, port, community)
|
||||||
|
|
||||||
|
if "snmpconf" in sys.argv[1:]:
|
||||||
|
print "require 1.3.6.1.4.1.2636.3.1.13.1.5"
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
if not (host and port and community):
|
||||||
|
print "# Bad configuration. Cannot run with Host=%s, port=%s and community=%s" % (host, port, community)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if "config" in sys.argv[1:]:
|
||||||
|
c.print_config()
|
||||||
|
else:
|
||||||
|
c.execute()
|
229
plugins/snmp/snmp__juniper_spu
Executable file
229
plugins/snmp/snmp__juniper_spu
Executable file
|
@ -0,0 +1,229 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright (C) 2014 Johann Schmitz <johann@j-schmitz.net>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Library General Public License as published by
|
||||||
|
# the Free Software Foundation; version 2 only
|
||||||
|
#
|
||||||
|
# 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 Library General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Library General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
snmp__juniper_spu - Network monitoring plugin for the SPU's in Juniper firewalls.
|
||||||
|
|
||||||
|
=head1 CONFIGURATION
|
||||||
|
|
||||||
|
Make sure your Juniper device is accessible via SNMP (e.g. via snmpwalk) and the munin-node
|
||||||
|
has been configured correctly.
|
||||||
|
|
||||||
|
=head1 MAGIC MARKERS
|
||||||
|
|
||||||
|
#%# family=snmpauto
|
||||||
|
#%# capabilities=snmpconf
|
||||||
|
|
||||||
|
=head1 VERSION
|
||||||
|
|
||||||
|
0.0.1
|
||||||
|
|
||||||
|
=head1 BUGS
|
||||||
|
|
||||||
|
Open a ticket at https://github.com/ercpe/contrib if you find one.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Johann Schmitz <johann@j-schmitz.net>
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
GPLv2
|
||||||
|
|
||||||
|
=cut
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from pysnmp.entity.rfc3413.oneliner import cmdgen
|
||||||
|
|
||||||
|
host = None
|
||||||
|
port = os.getenv('port', 161)
|
||||||
|
community = os.getenv('community', "public")
|
||||||
|
|
||||||
|
debug = bool(os.getenv('MUNIN_DEBUG', os.getenv('DEBUG', 0)))
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)-7s %(message)s')
|
||||||
|
|
||||||
|
try:
|
||||||
|
match = re.search("^(?:|.*\/)snmp_([^_]+)_juniper_spu$", sys.argv[0])
|
||||||
|
host = match.group(1)
|
||||||
|
request = match.group(2)
|
||||||
|
match = re.search("^([^:]+):(\d+)$", host)
|
||||||
|
if match is not None:
|
||||||
|
host = match.group(1)
|
||||||
|
port = match.group(2)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
jnxJsSPUMonitoringObjectsTable = '1.3.6.1.4.1.2636.3.39.1.12.1.1'
|
||||||
|
#jnxJsSPUMonitoringIndex = jnxJsSPUMonitoringObjectsTable + '.1.1'
|
||||||
|
#jnxJsSPUMonitoringFPCIndex = jnxJsSPUMonitoringObjectsTable + '.1.2'
|
||||||
|
#jnxJsSPUMonitoringSPUIndex = jnxJsSPUMonitoringObjectsTable + '.1.3'
|
||||||
|
#jnxJsSPUMonitoringCPUUsage = jnxJsSPUMonitoringObjectsTable + '.1.4'
|
||||||
|
#jnxJsSPUMonitoringMemoryUsage = jnxJsSPUMonitoringObjectsTable + '.1.5'
|
||||||
|
jnxJsSPUMonitoringCurrentFlowSession = jnxJsSPUMonitoringObjectsTable + '.1.6'
|
||||||
|
jnxJsSPUMonitoringMaxFlowSession = jnxJsSPUMonitoringObjectsTable + '.1.7'
|
||||||
|
jnxJsSPUMonitoringCurrentCPSession = jnxJsSPUMonitoringObjectsTable + '.1.8'
|
||||||
|
jnxJsSPUMonitoringMaxCPSession = jnxJsSPUMonitoringObjectsTable + '.1.9'
|
||||||
|
#jnxJsSPUMonitoringNodeIndex = jnxJsSPUMonitoringObjectsTable + '.1.10'
|
||||||
|
jnxJsSPUMonitoringNodeDescr = jnxJsSPUMonitoringObjectsTable + '.1.11'
|
||||||
|
jnxJsSPUMonitoringFlowSessIPv4 = jnxJsSPUMonitoringObjectsTable + '.1.12'
|
||||||
|
jnxJsSPUMonitoringFlowSessIPv6 = jnxJsSPUMonitoringObjectsTable + '.1.13'
|
||||||
|
jnxJsSPUMonitoringCPSessIPv4 = jnxJsSPUMonitoringObjectsTable + '.1.14'
|
||||||
|
jnxJsSPUMonitoringCPSessIPv6 = jnxJsSPUMonitoringObjectsTable + '.1.15'
|
||||||
|
|
||||||
|
class JunOSSnmpClient(object):
|
||||||
|
|
||||||
|
def __init__(self, host, port, community):
|
||||||
|
self.hostname = host
|
||||||
|
self.transport = cmdgen.UdpTransportTarget((host, int(port)))
|
||||||
|
self.auth = cmdgen.CommunityData('test-agent', community)
|
||||||
|
self.gen = cmdgen.CommandGenerator()
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
errorIndication, errorStatus, errorIndex, varBindTable = self.gen.bulkCmd(
|
||||||
|
self.auth,
|
||||||
|
self.transport,
|
||||||
|
0, 10,
|
||||||
|
jnxJsSPUMonitoringObjectsTable)
|
||||||
|
# ignoreNonIncreasingOids=True) # only available with pysnmp >= 4.2.4 (?) and broken anyway
|
||||||
|
|
||||||
|
if errorIndication:
|
||||||
|
logging.error("SNMP bulkCmd for devices failed: %s, %s, %s" % (errorIndication, errorStatus, errorIndex))
|
||||||
|
return {}
|
||||||
|
|
||||||
|
devices = {}
|
||||||
|
values = {}
|
||||||
|
for row in varBindTable:
|
||||||
|
for name, value in row:
|
||||||
|
if not str(name).startswith(jnxJsSPUMonitoringObjectsTable):
|
||||||
|
continue
|
||||||
|
|
||||||
|
oid = str(name)
|
||||||
|
|
||||||
|
nodeid = oid[oid.rindex('.'):]
|
||||||
|
|
||||||
|
idx = oid[len(jnxJsSPUMonitoringObjectsTable)+3:]
|
||||||
|
idx = idx[:idx.index('.')]
|
||||||
|
|
||||||
|
if oid.startswith(jnxJsSPUMonitoringNodeDescr):
|
||||||
|
devices[nodeid] = str(value)
|
||||||
|
continue
|
||||||
|
|
||||||
|
values[oid] = int(value)
|
||||||
|
return devices, values
|
||||||
|
|
||||||
|
def print_config(self):
|
||||||
|
devices, data = self.get_data()
|
||||||
|
|
||||||
|
data_def = [
|
||||||
|
('flow', self.hostname, 'Flow sessions', '--base 1000', '# of sessions', jnxJsSPUMonitoringMaxFlowSession),
|
||||||
|
('cp', self.hostname, 'Central point sessions', '--base 1000', '# of sessions', jnxJsSPUMonitoringMaxCPSession),
|
||||||
|
]
|
||||||
|
|
||||||
|
for datarow, hostname, title, args, vlabel, max_prefix in data_def:
|
||||||
|
print """multigraph juniper_{datarow}
|
||||||
|
host_name {hostname}
|
||||||
|
graph_title {title}
|
||||||
|
graph_vlabel {vlabel}
|
||||||
|
graph_args {args}
|
||||||
|
graph_category network
|
||||||
|
graph_info {title}""".format(datarow=datarow, hostname=hostname, title=title, args=args, vlabel=vlabel)
|
||||||
|
|
||||||
|
for suffix, node in devices.iteritems():
|
||||||
|
ident = "%s_%s" % (datarow, node)
|
||||||
|
print """{label}.info {title} on {node}
|
||||||
|
{label}.label {node}
|
||||||
|
{label}.type GAUGE
|
||||||
|
{label}.max {max}""".format(title=title, label=ident, node=node, max=data.get(max_prefix + suffix))
|
||||||
|
|
||||||
|
for suffix, node in devices.iteritems():
|
||||||
|
print """
|
||||||
|
multigraph juniper_{datarow}.{node}
|
||||||
|
host_name {hostname}
|
||||||
|
graph_title {title} on {node}
|
||||||
|
graph_vlabel {vlabel}
|
||||||
|
graph_args {args}
|
||||||
|
graph_category network
|
||||||
|
graph_info {title}
|
||||||
|
{datarow}V4.info Current IPv4 {datarow} sessions
|
||||||
|
{datarow}V4.label IPv4
|
||||||
|
{datarow}V4.draw AREASTACK
|
||||||
|
{datarow}V4.type GAUGE
|
||||||
|
{datarow}V6.info Current IPv6 {datarow} sessions
|
||||||
|
{datarow}V6.label IPv6
|
||||||
|
{datarow}V6.draw AREASTACK
|
||||||
|
{datarow}V6.type GAUGE
|
||||||
|
{datarow}Current.info Current total {datarow} sessions
|
||||||
|
{datarow}Current.label Total
|
||||||
|
{datarow}Current.draw LINE1
|
||||||
|
{datarow}Current.type GAUGE
|
||||||
|
{datarow}Current.colour 000000
|
||||||
|
{datarow}Max.info Max. {datarow} sessions supported by the device(s)
|
||||||
|
{datarow}Max.label Max
|
||||||
|
{datarow}Max.draw LINE0
|
||||||
|
{datarow}Max.type GAUGE
|
||||||
|
""".format(datarow=datarow, hostname=hostname, title=title, args=args, vlabel=vlabel, node=node)
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
devices, data = self.get_data()
|
||||||
|
|
||||||
|
print "multigraph juniper_flow"
|
||||||
|
for suffix, node in devices.iteritems():
|
||||||
|
print "flow_%s.value %s" % (node, data.get(jnxJsSPUMonitoringCurrentFlowSession + suffix, 0))
|
||||||
|
|
||||||
|
for suffix, node in devices.iteritems():
|
||||||
|
print "multigraph juniper_flow.%s" % node
|
||||||
|
print "flowV4.value %s" % data.get(jnxJsSPUMonitoringFlowSessIPv4 + suffix, 0)
|
||||||
|
print "flowV6.value %s" % data.get(jnxJsSPUMonitoringFlowSessIPv6 + suffix, 0)
|
||||||
|
print "flowCurrent.value %s" % data.get(jnxJsSPUMonitoringCurrentFlowSession + suffix, 0)
|
||||||
|
print "flowMax.value %s" % data.get(jnxJsSPUMonitoringMaxFlowSession + suffix, 0)
|
||||||
|
|
||||||
|
print "multigraph juniper_cp"
|
||||||
|
for suffix, node in devices.iteritems():
|
||||||
|
print "cp_%s.value %s" % (node, data.get(jnxJsSPUMonitoringCurrentCPSession + suffix, 0))
|
||||||
|
|
||||||
|
for suffix, node in devices.iteritems():
|
||||||
|
print "multigraph juniper_cp.%s" % node
|
||||||
|
print "cpV4.value %s" % data.get(jnxJsSPUMonitoringCPSessIPv4 + suffix, 0)
|
||||||
|
print "cpV6.value %s" % data.get(jnxJsSPUMonitoringCPSessIPv6 + suffix, 0)
|
||||||
|
print "cpCurrent.value %s" % data.get(jnxJsSPUMonitoringCurrentCPSession + suffix, 0)
|
||||||
|
print "cpMax.value %s" % data.get(jnxJsSPUMonitoringMaxCPSession + suffix, 0)
|
||||||
|
|
||||||
|
c = JunOSSnmpClient(host, port, community)
|
||||||
|
|
||||||
|
if "snmpconf" in sys.argv[1:]:
|
||||||
|
print "require %s" % (jnxJsSPUMonitoringObjectsTable, )
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
if not (host and port and community):
|
||||||
|
print "# Bad configuration. Cannot run with Host=%s, port=%s and community=%s" % (host, port, community)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if "config" in sys.argv[1:]:
|
||||||
|
c.print_config()
|
||||||
|
else:
|
||||||
|
c.execute()
|
|
@ -54,6 +54,9 @@ if (!file_exists($sTmpFilePath)) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
|
|
||||||
$toShow = (int) ($iCurrent - (int) $iOldCount);
|
$toShow = (int) ($iCurrent - (int) $iOldCount);
|
||||||
|
if ($toShow < 0) {
|
||||||
|
$toShow = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "current.value $toShow\n";
|
echo "current.value $toShow\n";
|
||||||
|
|
|
@ -54,6 +54,9 @@ if (!file_exists($sTmpFilePath)) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
|
|
||||||
$toShow = (int) ($iCurrent - (int) $iOldCount);
|
$toShow = (int) ($iCurrent - (int) $iOldCount);
|
||||||
|
if ($toShow < 0) {
|
||||||
|
$toShow = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "current.value $toShow\n";
|
echo "current.value $toShow\n";
|
||||||
|
|
|
@ -6,10 +6,12 @@
|
||||||
#%# capabilities=autoconf
|
#%# capabilities=autoconf
|
||||||
|
|
||||||
sysctl='/sbin/sysctl'
|
sysctl='/sbin/sysctl'
|
||||||
|
ostype=`uname -s`
|
||||||
|
procfile='/proc/spl/kstat/zfs/arcstats'
|
||||||
|
|
||||||
case $1 in
|
case $1 in
|
||||||
config)
|
config)
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
graph_title ZFS ARC efficiency
|
graph_title ZFS ARC efficiency
|
||||||
graph_vlabel %
|
graph_vlabel %
|
||||||
graph_scale no
|
graph_scale no
|
||||||
|
@ -209,23 +211,37 @@ EOF
|
||||||
# mru_ghost_hits_perc.cdef mru_ghost_hits,100,*,hits,/
|
# mru_ghost_hits_perc.cdef mru_ghost_hits,100,*,hits,/
|
||||||
# mru_ghost_hits_perc.label Most recently used ghost hits
|
# mru_ghost_hits_perc.label Most recently used ghost hits
|
||||||
# mru_ghost_hits_perc.graph no
|
# mru_ghost_hits_perc.graph no
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
autoconf)
|
autoconf)
|
||||||
if [ ! -x ${sysctl} ]; then
|
if [ ! -x ${sysctl} ]; then
|
||||||
echo "no (${sysctl} is not executable)"
|
echo "no (${sysctl} is not executable)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
ostype=`uname -s`
|
if [ ${ostype} = "FreeBSD" ]; then
|
||||||
if [ ${ostype} = "FreeBSD" ]; then
|
echo "yes"
|
||||||
echo "yes"
|
exit 0
|
||||||
exit 0
|
fi
|
||||||
fi
|
if [ ${ostype} = "Linux" ]; then
|
||||||
echo "no (You're OS is not supported by this plugin)"
|
if [ -f ${procfile} ]; then
|
||||||
exit 1
|
echo "yes"
|
||||||
;;
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "no (The statsfile does not exist: ${procfile})"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "no (You're OS is not supported by this plugin)"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
suggest)
|
suggest)
|
||||||
exit 0
|
exit 0
|
||||||
;;
|
;;
|
||||||
|
esac
|
||||||
|
case ${ostype} in
|
||||||
|
"FreeBSD")
|
||||||
|
$sysctl kstat.zfs.misc.arcstats | sed -e 's/^kstat.zfs.misc.arcstats.//' -e 's/:/.value/'
|
||||||
|
;;
|
||||||
|
"Linux")
|
||||||
|
cat ${procfile} | tail -n +3 | sed -e 's/ \+/ /g' | cut -f 1,3 -d ' ' | sed -e 's/ /.value /'
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
$sysctl kstat.zfs.misc.arcstats | sed -e 's/^kstat.zfs.misc.arcstats.//' -e 's/:/.value/'
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue