mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
More housecleaning.
Collapse some categories; remove duplicates; move plugins in where they belong, remove files that are not really plugins at all.
This commit is contained in:
parent
4e3ef5b93e
commit
0a1524f27f
@ -1,2 +0,0 @@
|
||||
Check http://aouyar.github.com/PyMunin/ to get the most recent versionof the
|
||||
PyMunin Multi graph Munin Plugins and documentation.
|
@ -1,702 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
# vim: sts=4 sw=4 ts=8
|
||||
|
||||
# Munin markers:
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf suggest
|
||||
|
||||
# Author: Michael Renner <michael.renner@amd.co.at>
|
||||
|
||||
# Version: 0.0.5, 2009-05-22
|
||||
|
||||
|
||||
|
||||
=head1 NAME
|
||||
|
||||
linux_diskstat_ - Munin plugin to monitor various values provided
|
||||
via C</proc/diskstats>
|
||||
|
||||
=head1 APPLICABLE SYSTEMS
|
||||
|
||||
Linux 2.6 systems with extended block device statistics enabled.
|
||||
|
||||
|
||||
=head1 INTERPRETATION
|
||||
|
||||
Among the more self-describing or well-known values like C<throughput>
|
||||
(Bytes per second) there are a few which might need further introduction.
|
||||
|
||||
|
||||
=head2 Device Utilization
|
||||
|
||||
Linux provides a counter which increments in a millisecond-interval for as long
|
||||
as there are outstanding I/O requests. If this counter is close to 1000msec
|
||||
in a given 1 second timeframe the device is nearly 100% saturated. This plugin
|
||||
provides values averaged over a 5 minute time frame per default, so it can't
|
||||
catch short-lived saturations, but it'll give a nice trend for semi-uniform
|
||||
load patterns as they're expected in most server or multi-user environments.
|
||||
|
||||
|
||||
=head2 Device IO Time
|
||||
|
||||
The C<Device IO Time> takes the counter described under C<Device Utilization>
|
||||
and divides it by the number of I/Os that happened in the given time frame,
|
||||
resulting in an average time per I/O on the block-device level.
|
||||
|
||||
This value can give you a good comparison base amongst different controllers,
|
||||
storage subsystems and disks for similiar workloads.
|
||||
|
||||
|
||||
=head2 Syscall Wait Time
|
||||
|
||||
These values describe the average time it takes between an application issuing
|
||||
a syscall resulting in a hit to a blockdevice to the syscall returning to the
|
||||
application.
|
||||
|
||||
The values are bound to be higher (at least for read requests) than the time
|
||||
it takes the device itself to fulfill the requests, since calling overhead,
|
||||
queuing times and probably a dozen other things are included in those times.
|
||||
|
||||
These are the values to watch out for when an user complains that C<the disks
|
||||
are too slow!>.
|
||||
|
||||
|
||||
=head3 What causes a block device hit?
|
||||
|
||||
A non-exhaustive list:
|
||||
|
||||
=over
|
||||
|
||||
=item * Reads from files when the given range is not in the page cache or the O_DIRECT
|
||||
flag is set.
|
||||
|
||||
=item * Writes to files if O_DIRECT or O_SYNC is set or sys.vm.dirty_(background_)ratio
|
||||
is exceeded.
|
||||
|
||||
=item * Filesystem metadata operations (stat(2), getdents(2), file creation,
|
||||
modification of any of the values returned by stat(2), etc.)
|
||||
|
||||
=item * The pdflush daemon writing out dirtied pages
|
||||
|
||||
=item * (f)sync
|
||||
|
||||
=item * Swapping
|
||||
|
||||
=item * raw device I/O (mkfs, dd, etc.)
|
||||
|
||||
=back
|
||||
|
||||
=head1 ACKNOWLEDGEMENTS
|
||||
|
||||
The core logic of this script is based on the B<iostat> tool of the B<sysstat>
|
||||
package written and maintained by Sebastien Godard.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
See C<Documentation/iostats.txt> in your Linux source tree for further information
|
||||
about the C<numbers> involved in this module.
|
||||
|
||||
L<http://www.westnet.com/~gsmith/content/linux-pdflush.htm> has a nice writeup
|
||||
about the pdflush daemon.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Michael Renner <michael.renner@amd.co.at>
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2
|
||||
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
use strict;
|
||||
|
||||
|
||||
use File::Basename;
|
||||
use Carp;
|
||||
use POSIX;
|
||||
|
||||
# We load our own version of save/restore_state if Munin::Plugin is unavailable.
|
||||
# Don't try this at home
|
||||
eval { require Munin::Plugin; Munin::Plugin->import; };
|
||||
|
||||
if ($@) {
|
||||
fake_munin_plugin();
|
||||
}
|
||||
|
||||
|
||||
# Sanity check to ensure that the script is called the correct name.
|
||||
|
||||
if (basename($0) !~ /^linux_diskstat_/) {
|
||||
die qq(Please ensure that the name of the script and it's symlinks starts with "linux_diskstat_"\n);
|
||||
}
|
||||
|
||||
|
||||
############
|
||||
# autoconf #
|
||||
############
|
||||
|
||||
if ( defined $ARGV[0] && $ARGV[0] eq 'autoconf' ) {
|
||||
my %stats;
|
||||
|
||||
# Capture any croaks on the way
|
||||
eval { %stats = parse_diskstats() };
|
||||
|
||||
if ( !$@ && keys %stats ) {
|
||||
|
||||
print "yes\n";
|
||||
exit 0;
|
||||
}
|
||||
else {
|
||||
print "no\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
###########
|
||||
# suggest #
|
||||
###########
|
||||
|
||||
if ( defined $ARGV[0] && $ARGV[0] eq 'suggest' ) {
|
||||
|
||||
my %diskstats = parse_diskstats();
|
||||
|
||||
my %suggested_devices;
|
||||
|
||||
DEVICE:
|
||||
for my $devname ( sort keys %diskstats ) {
|
||||
|
||||
# Skip devices without traffic
|
||||
next
|
||||
if ( $diskstats{$devname}->{'rd_ios'} == 0
|
||||
&& $diskstats{$devname}->{'wr_ios'} == 0 );
|
||||
|
||||
for my $existing_device ( @{ $suggested_devices{'iops'} } ) {
|
||||
|
||||
# Filter out devices (partitions) which are matched by existing ones
|
||||
# e.g. sda1 -> sda, c0d0p1 -> c0d0
|
||||
next DEVICE if ( $devname =~ m/$existing_device/ );
|
||||
}
|
||||
|
||||
push @{ $suggested_devices{'iops'} }, $devname;
|
||||
push @{ $suggested_devices{'throughput'} }, $devname;
|
||||
|
||||
# Only suggest latency graphs if the device supports it
|
||||
if ( $diskstats{$devname}->{'rd_ticks'} > 0
|
||||
|| $diskstats{$devname}->{'wr_ticks'} > 0 )
|
||||
{
|
||||
push @{ $suggested_devices{'latency'} }, $devname;
|
||||
}
|
||||
}
|
||||
|
||||
for my $mode ( keys %suggested_devices ) {
|
||||
for my $device ( sort @{ $suggested_devices{$mode} } ) {
|
||||
|
||||
my $printdev = translate_device_name($device, 'TO_FS');
|
||||
print "${mode}_$printdev\n";
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
|
||||
# Reading the scripts invocation name and setting some parameters,
|
||||
# needed from here on
|
||||
|
||||
my $basename = basename($0);
|
||||
my ( $mode, $device ) = $basename =~ m/linux_diskstat_(\w+)_([-+\w]+)$/;
|
||||
|
||||
if ( not defined $device ) {
|
||||
croak "Didn't get a device name. Aborting\n";
|
||||
}
|
||||
|
||||
$device = translate_device_name($device, 'FROM_FS');
|
||||
|
||||
##########
|
||||
# config #
|
||||
##########
|
||||
|
||||
if ( defined $ARGV[0] && $ARGV[0] eq 'config' ) {
|
||||
|
||||
my $pretty_device = $device;
|
||||
|
||||
if ($device =~ /^dm-\d+$/) {
|
||||
$pretty_device = translate_devicemapper_name($device);
|
||||
}
|
||||
|
||||
if ( $mode eq 'latency' ) {
|
||||
|
||||
print <<EOF;
|
||||
graph_title Disk latency for /dev/$pretty_device
|
||||
graph_args --base 1000
|
||||
graph_category disk
|
||||
|
||||
util.label Device utilization (percent)
|
||||
util.type GAUGE
|
||||
util.info Utilization of the device. If the time spent for I/O is close to 1000msec for a given second, the device is nearly 100% saturated.
|
||||
util.min 0
|
||||
svctm.label Average device IO time (ms)
|
||||
svctm.type GAUGE
|
||||
svctm.info Average time an I/O takes on the block device
|
||||
svctm.min 0
|
||||
avgwait.label Average IO Wait time (ms)
|
||||
avgwait.type GAUGE
|
||||
avgwait.info Average wait time for an I/O from request start to finish (includes queue times et al)
|
||||
avgwait.min 0
|
||||
avgrdwait.label Average Read IO Wait time (ms)
|
||||
avgrdwait.type GAUGE
|
||||
avgrdwait.info Average wait time for a read I/O from request start to finish (includes queue times et al)
|
||||
avgrdwait.min 0
|
||||
avgwrwait.label Average Write IO Wait time (ms)
|
||||
avgwrwait.type GAUGE
|
||||
avgwrwait.info Average wait time for a write I/O from request start to finish (includes queue times et al)
|
||||
avgwrwait.min 0
|
||||
|
||||
EOF
|
||||
|
||||
}
|
||||
elsif ( $mode eq 'throughput' ) {
|
||||
|
||||
print <<EOF;
|
||||
graph_title Disk throughput for /dev/$pretty_device
|
||||
graph_args --base 1024
|
||||
graph_vlabel Bytes/second
|
||||
graph_category disk
|
||||
|
||||
rdbytes.label Read Bytes
|
||||
rdbytes.type GAUGE
|
||||
rdbytes.min 0
|
||||
wrbytes.label Write Bytes
|
||||
wrbytes.type GAUGE
|
||||
wrbytes.min 0
|
||||
|
||||
EOF
|
||||
}
|
||||
elsif ( $mode eq 'iops' ) {
|
||||
|
||||
print <<EOF;
|
||||
graph_title Disk IOs for /dev/$pretty_device
|
||||
graph_args --base 1000
|
||||
graph_vlabel Units/second
|
||||
graph_category disk
|
||||
|
||||
rdio.label Read IO/sec
|
||||
rdio.type GAUGE
|
||||
rdio.min 0
|
||||
wrio.label Write IO/sec
|
||||
wrio.type GAUGE
|
||||
wrio.min 0
|
||||
avgrqsz.label Average Request Size (KiB)
|
||||
avgrqsz.type GAUGE
|
||||
avgrqsz.min 0
|
||||
avgrdrqsz.label Average Read Request Size (KiB)
|
||||
avgrdrqsz.type GAUGE
|
||||
avgrdrqsz.min 0
|
||||
avgwrrqsz.label Average Write Request Size (KiB)
|
||||
avgwrrqsz.type GAUGE
|
||||
avgwrrqsz.min 0
|
||||
|
||||
EOF
|
||||
|
||||
}
|
||||
else {
|
||||
croak "Unknown mode $mode\n";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
|
||||
########
|
||||
# MAIN #
|
||||
########
|
||||
|
||||
|
||||
my %cur_diskstat = fetch_device_counters($device);
|
||||
|
||||
|
||||
my ( $prev_time, %prev_diskstat ) = restore_state();
|
||||
|
||||
save_state( time(), %cur_diskstat );
|
||||
|
||||
# Probably the first run for the given device, we need state to do our job,
|
||||
# so let's wait for the next run.
|
||||
exit if ( not defined $prev_time or not %prev_diskstat );
|
||||
|
||||
calculate_and_print_values( $prev_time, \%prev_diskstat, \%cur_diskstat );
|
||||
|
||||
|
||||
|
||||
########
|
||||
# SUBS #
|
||||
########
|
||||
|
||||
sub calculate_and_print_values {
|
||||
my ( $prev_time, $prev_stats, $cur_stats ) = @_;
|
||||
|
||||
my $bytes_per_sector = 512;
|
||||
|
||||
my $interval = time() - $prev_time;
|
||||
|
||||
my $read_ios = $cur_stats->{'rd_ios'} - $prev_stats->{'rd_ios'};
|
||||
my $write_ios = $cur_stats->{'wr_ios'} - $prev_stats->{'wr_ios'};
|
||||
|
||||
my $rd_ticks = $cur_stats->{'rd_ticks'} - $prev_stats->{'rd_ticks'};
|
||||
my $wr_ticks = $cur_stats->{'wr_ticks'} - $prev_stats->{'wr_ticks'};
|
||||
|
||||
my $rd_sectors = $cur_stats->{'rd_sectors'} - $prev_stats->{'rd_sectors'};
|
||||
my $wr_sectors = $cur_stats->{'wr_sectors'} - $prev_stats->{'wr_sectors'};
|
||||
|
||||
my $tot_ticks = $cur_stats->{'tot_ticks'} - $prev_stats->{'tot_ticks'};
|
||||
|
||||
|
||||
my $read_io_per_sec = $read_ios / $interval;
|
||||
my $write_io_per_sec = $write_ios / $interval;
|
||||
|
||||
my $read_bytes_per_sec = $rd_sectors / $interval * $bytes_per_sector;
|
||||
my $write_bytes_per_sec = $wr_sectors / $interval * $bytes_per_sector;
|
||||
|
||||
|
||||
my $total_ios = $read_ios + $write_ios;
|
||||
my $total_ios_per_sec = $total_ios / $interval;
|
||||
|
||||
# Utilization - or "how busy is the device"?
|
||||
# If the time spent for I/O was close to 1000msec for
|
||||
# a given second, the device is nearly 100% saturated.
|
||||
my $utilization = $tot_ticks / $interval;
|
||||
|
||||
# Average time an I/O takes on the block device
|
||||
my $servicetime =
|
||||
$total_ios_per_sec ? $utilization / $total_ios_per_sec : 0;
|
||||
|
||||
# Average wait time for an I/O from start to finish
|
||||
# (includes queue times et al)
|
||||
my $average_wait = $total_ios ? ( $rd_ticks + $wr_ticks ) / $total_ios : 0;
|
||||
my $average_rd_wait = $read_ios ? $rd_ticks / $read_ios : 0;
|
||||
my $average_wr_wait = $write_ios ? $wr_ticks / $write_ios : 0;
|
||||
|
||||
my $average_rq_size_in_kb =
|
||||
$total_ios
|
||||
? ( $rd_sectors + $wr_sectors ) * $bytes_per_sector / 1024 / $total_ios
|
||||
: 0;
|
||||
my $average_rd_rq_size_in_kb =
|
||||
$read_ios ? $rd_sectors * $bytes_per_sector / 1024 / $read_ios : 0;
|
||||
my $average_wr_rq_size_in_kb =
|
||||
$write_ios ? $wr_sectors * $bytes_per_sector / 1024 / $write_ios : 0;
|
||||
|
||||
my $util_print = $utilization / 10;
|
||||
|
||||
|
||||
if ( $mode eq 'latency' ) {
|
||||
print <<EOF;
|
||||
|
||||
util.value $util_print
|
||||
svctm.value $servicetime
|
||||
avgwait.value $average_wait
|
||||
avgrdwait.value $average_rd_wait
|
||||
avgwrwait.value $average_wr_wait
|
||||
|
||||
EOF
|
||||
}
|
||||
elsif ( $mode eq 'throughput' ) {
|
||||
|
||||
print <<EOF;
|
||||
|
||||
rdbytes.value $read_bytes_per_sec
|
||||
wrbytes.value $write_bytes_per_sec
|
||||
|
||||
EOF
|
||||
}
|
||||
elsif ( $mode eq 'iops' ) {
|
||||
|
||||
print <<EOF;
|
||||
|
||||
rdio.value $read_io_per_sec
|
||||
wrio.value $write_io_per_sec
|
||||
avgrqsz.value $average_rq_size_in_kb
|
||||
avgrdrqsz.value $average_rd_rq_size_in_kb
|
||||
avgwrrqsz.value $average_wr_rq_size_in_kb
|
||||
|
||||
EOF
|
||||
|
||||
}
|
||||
else {
|
||||
croak "Unknown mode $mode\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub read_diskstats {
|
||||
|
||||
open STAT, '< /proc/diskstats'
|
||||
or croak "Failed to open '/proc/diskstats': $!\n";
|
||||
|
||||
my @lines;
|
||||
|
||||
for my $line (<STAT>) {
|
||||
|
||||
# Strip trailing newline and leading whitespace
|
||||
chomp $line;
|
||||
$line =~ s/^\s+//;
|
||||
|
||||
my @elems = split /\s+/, $line;
|
||||
|
||||
# We explicitly don't support old-style diskstats
|
||||
# There are situations where only _some_ lines (e.g.
|
||||
# partitions on older 2.6 kernels) have fewer stats
|
||||
# numbers, therefore we'll skip them silently
|
||||
if ( @elems != 14 ) {
|
||||
next;
|
||||
}
|
||||
push @lines, \@elems;
|
||||
}
|
||||
|
||||
close STAT or croak "Failed to close '/proc/diskstats': $!";
|
||||
return @lines;
|
||||
}
|
||||
|
||||
sub read_sysfs {
|
||||
|
||||
my ($want_device) = @_;
|
||||
|
||||
my @devices;
|
||||
my @lines;
|
||||
|
||||
if ( defined $want_device ) {
|
||||
|
||||
# sysfs uses '!' as replacement for '/', e.g. cciss!c0d0
|
||||
$want_device =~ tr#/#!#;
|
||||
@devices = $want_device;
|
||||
}
|
||||
else {
|
||||
@devices = glob "/sys/block/*/stat";
|
||||
@devices = map { m!/sys/block/([^/]+)/stat! } @devices;
|
||||
}
|
||||
|
||||
|
||||
for my $cur_device (@devices) {
|
||||
my $stats_file = "/sys/block/$cur_device/stat";
|
||||
|
||||
open STAT, "< $stats_file"
|
||||
or croak "Failed to open '$stats_file': $!\n";
|
||||
|
||||
my $line = <STAT>;
|
||||
|
||||
# Trimming whitespace
|
||||
$line =~ s/^\s+//;
|
||||
chomp $line;
|
||||
|
||||
my @elems = split /\s+/, $line;
|
||||
|
||||
croak "'$stats_file' doesn't contain exactly 11 values. Aborting"
|
||||
if ( @elems != 11 );
|
||||
|
||||
# Translate the devicename back before storing the information
|
||||
$cur_device =~ tr#!#/#;
|
||||
|
||||
# Faking missing diskstats values
|
||||
unshift @elems, ( '', '', $cur_device );
|
||||
|
||||
push @lines, \@elems;
|
||||
|
||||
close STAT or croak "Failed to close '$stats_file': $!\n";
|
||||
}
|
||||
|
||||
return @lines;
|
||||
}
|
||||
|
||||
|
||||
sub parse_diskstats {
|
||||
|
||||
my ($want_device) = @_;
|
||||
|
||||
my @stats;
|
||||
|
||||
if ( glob "/sys/block/*/stat" ) {
|
||||
|
||||
@stats = read_sysfs($want_device);
|
||||
}
|
||||
else {
|
||||
@stats = read_diskstats();
|
||||
}
|
||||
|
||||
my %diskstats;
|
||||
|
||||
for my $entry (@stats) {
|
||||
|
||||
my %devstat;
|
||||
|
||||
# Hash-Slicing for fun and profit
|
||||
@devstat{
|
||||
qw(major minor devname
|
||||
rd_ios rd_merges rd_sectors rd_ticks
|
||||
wr_ios wr_merges wr_sectors wr_ticks
|
||||
ios_in_prog tot_ticks rq_ticks)
|
||||
}
|
||||
= @{$entry};
|
||||
|
||||
$diskstats{ $devstat{'devname'} } = \%devstat;
|
||||
}
|
||||
|
||||
return %diskstats;
|
||||
}
|
||||
|
||||
sub fetch_device_counters {
|
||||
|
||||
my ($want_device) = @_;
|
||||
|
||||
my %diskstats = parse_diskstats($want_device);
|
||||
|
||||
for my $devname ( keys %diskstats ) {
|
||||
|
||||
if ( $want_device eq $devname ) {
|
||||
return %{ $diskstats{$devname} };
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
# We use '+' (and formerly '-') as placeholder for '/' in device-names
|
||||
# used as calling name for the script.
|
||||
sub translate_device_name {
|
||||
|
||||
my ($device, $mode) = @_;
|
||||
|
||||
if ($mode eq 'FROM_FS') {
|
||||
|
||||
# Hackaround to mitigate issues with unwisely chosen former separator
|
||||
if ( not ($device =~ m/dm-\d+/)) {
|
||||
$device =~ tr#-+#//#;
|
||||
}
|
||||
|
||||
}
|
||||
elsif ($mode eq 'TO_FS') {
|
||||
|
||||
$device =~ tr#/#+#;
|
||||
|
||||
}
|
||||
else {
|
||||
croak "translate_device_name: Unknown mode\n";
|
||||
}
|
||||
|
||||
return $device;
|
||||
}
|
||||
|
||||
|
||||
sub fake_munin_plugin {
|
||||
my $eval_code = <<'EOF';
|
||||
|
||||
use Storable;
|
||||
my $storable_filename = basename($0);
|
||||
$storable_filename = "/tmp/munin-state-$storable_filename";
|
||||
|
||||
sub save_state {
|
||||
my @state = @_;
|
||||
|
||||
if ( not -e $storable_filename or -f $storable_filename ) {
|
||||
store \@state, $storable_filename or croak "Failed to persist state to '$storable_filename': $!\n";
|
||||
}
|
||||
else {
|
||||
croak "$storable_filename is probably not a regular file. Please delete it.\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub restore_state {
|
||||
|
||||
if (-f $storable_filename) {
|
||||
my $state = retrieve($storable_filename);
|
||||
return @{$state};
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
eval($eval_code);
|
||||
}
|
||||
|
||||
sub translate_devicemapper_name {
|
||||
my ($device) = @_;
|
||||
|
||||
my ($want_minor) = $device =~ m/^dm-(\d+)$/;
|
||||
|
||||
croak "Failed to extract devicemapper id" unless defined ($want_minor);
|
||||
|
||||
my $dm_major = find_devicemapper_major();
|
||||
croak "Failed to get device-mapper major number\n" unless defined $dm_major;
|
||||
|
||||
for my $entry (glob "/dev/mapper/\*") {
|
||||
|
||||
my $rdev = (stat($entry))[6];
|
||||
my $major = floor($rdev / 256);
|
||||
my $minor = $rdev % 256;
|
||||
|
||||
if ($major == $dm_major && $minor == $want_minor) {
|
||||
|
||||
my $pretty_name = translate_lvm_name($entry);
|
||||
|
||||
return defined $pretty_name ? $pretty_name : $entry;
|
||||
|
||||
}
|
||||
}
|
||||
# Return original string if the device can't be found.
|
||||
return $device;
|
||||
}
|
||||
|
||||
|
||||
|
||||
sub translate_lvm_name {
|
||||
|
||||
my ($entry) = @_;
|
||||
|
||||
my $device_name = basename($entry);
|
||||
|
||||
# Check for single-dash-occurence to see if this could be a lvm devicemapper device.
|
||||
if ($device_name =~ m/(?<!-)-(?!-)/) {
|
||||
|
||||
# split device name into vg and lv parts
|
||||
my ($vg, $lv) = split /(?<!-)-(?!-)/, $device_name, 2;
|
||||
return undef unless ( defined($vg) && defined($lv) );
|
||||
|
||||
# remove extraneous dashes from vg and lv names
|
||||
$vg =~ s/--/-/g;
|
||||
$lv =~ s/--/-/g;
|
||||
|
||||
$device_name = "$vg/$lv";
|
||||
|
||||
# Sanity check - does the constructed device name exist?
|
||||
if (stat("/dev/$device_name")) {
|
||||
return "$device_name";
|
||||
}
|
||||
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub find_devicemapper_major {
|
||||
|
||||
open (FH, '< /proc/devices') or croak "Failed to open '/proc/devices': $!";
|
||||
|
||||
my $dm_major;
|
||||
|
||||
for my $line (<FH>) {
|
||||
chomp $line;
|
||||
|
||||
my ($major, $name) = split /\s+/, $line, 2;
|
||||
|
||||
next unless defined $name;
|
||||
|
||||
if ($name eq 'device-mapper') {
|
||||
$dm_major = $major;
|
||||
last;
|
||||
}
|
||||
}
|
||||
close(FH);
|
||||
|
||||
return $dm_major;
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
Check http://aouyar.github.com/PyMunin/
|
||||
to get the most recent versionof the PyMunin Multi graph Munin Plugins and documentation.
|
@ -1,106 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# Plugin to monitor BGP table summary statistics on a cisco router.
|
||||
#
|
||||
# Original Author: Peter Holzleitner
|
||||
#
|
||||
# Revision 1.1 2010/10/14 19:19
|
||||
#
|
||||
# Configuration variables:
|
||||
#
|
||||
# iosuser - username (default "")
|
||||
# iospass - password (default "")
|
||||
#
|
||||
# Parameters:
|
||||
#
|
||||
# config (required)
|
||||
#
|
||||
# Magic markers (optional - only used by munin-config and some
|
||||
# installation scripts):
|
||||
#%# family=auto
|
||||
|
||||
|
||||
use Net::Telnet::Cisco;
|
||||
use Sys::Syslog;
|
||||
|
||||
|
||||
if ($0 =~ /^(?:|.*\/)cisco_bgp_([^_]+)$/) {
|
||||
$host = $1;
|
||||
}
|
||||
|
||||
($^O eq "linux" || $^O eq "openbsd") && Sys::Syslog::setlogsock('unix');
|
||||
openlog('munin.bgp', 'cons,pid', 'daemon');
|
||||
|
||||
|
||||
my @BGP_nbr;
|
||||
my @BGP_pfx;
|
||||
my $tot_pfx;
|
||||
my $iosuser = $ENV{iosuser} || "";
|
||||
my $iospass = $ENV{iospass} || "";
|
||||
|
||||
&fetch_bgpstats($host, $iosuser, $iospass);
|
||||
|
||||
|
||||
if ($ARGV[0] and $ARGV[0] eq "config") {
|
||||
print "host_name $host\n";
|
||||
print "graph_args --base 1024 -l 0 --vertical-label Prefixes\n";
|
||||
print "graph_title BGP Neighbour Statistics\n";
|
||||
print "graph_category network\n";
|
||||
print "graph_info This graph shows the number of BGP prefixes received by neighbour.\n";
|
||||
|
||||
my($n, $i); $n = scalar @BGP_nbr; $i = 0;
|
||||
while($n--) {
|
||||
my $neigh = $BGP_nbr[$i++];
|
||||
print "n$i.label $neigh\n";
|
||||
}
|
||||
|
||||
# print "total.label Total\n";
|
||||
# print "total.info Total number of prefixes in the BGP table\n";
|
||||
|
||||
} else {
|
||||
|
||||
my($n, $i); $n = scalar @BGP_nbr; $i = 0;
|
||||
while($n--) {
|
||||
my $pfx = $BGP_pfx[$i++];
|
||||
print "n$i.value $pfx\n";
|
||||
}
|
||||
# print "total.value $tot_pfx\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
sub fetch_bgpstats
|
||||
{
|
||||
my $hostname = shift;
|
||||
my $username = shift;
|
||||
my $password = shift;
|
||||
my $session = Net::Telnet::Cisco->new(Host => $host);
|
||||
|
||||
$session->login($username, $password);
|
||||
$session->cmd('terminal length 200');
|
||||
$session->cmd('terminal width 200');
|
||||
my @output = $session->cmd('show ip bgp summary');
|
||||
|
||||
# example output of router
|
||||
# ------------------------
|
||||
# [...]
|
||||
# Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
|
||||
# 11.111.11.111 4 98765 12403694 509571 308911893 0 0 1d23h 329193
|
||||
# 122.122.122.122 4 1234 13242856 383827 308911879 0 0 00:08:22 330761
|
||||
|
||||
foreach(@output) {
|
||||
chomp; s/\r//g;
|
||||
$tot_pfx = $1 if /^BGP activity (\d+)\/(\d+) prefixes/;
|
||||
syslog('debug', "$hostname: $_\n");
|
||||
|
||||
next unless /^(\d+\.\d+\.\d+\.\d+)\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+[0-9a-z:]+\s+(\d+)/;
|
||||
my ($neigh, $as, $pfx) = ($1, $2, $3);
|
||||
syslog('debug', "$neigh (AS $as)");
|
||||
push @BGP_nbr, "$neigh (AS $as)";
|
||||
push @BGP_pfx, $pfx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# vim:syntax=perl:ts=8
|
@ -1,378 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
=head1 OPENTRACKER PLUGIN
|
||||
|
||||
A Plugin to monitor OpenTracker Servers and their Performance
|
||||
|
||||
=head1 MUNIN CONFIGURATION
|
||||
|
||||
[opentracker*]
|
||||
env.host 127.0.0.1 *default*
|
||||
env.port 6969 *default*
|
||||
env.uri /stats *default*
|
||||
|
||||
=head2 MUNIN ENVIRONMENT CONFIGURATION EXPLANATION
|
||||
|
||||
host = opentracker host to connect to
|
||||
port = opentracker http port to connect to
|
||||
uri = stats uri for appending requests for data
|
||||
|
||||
I need this information so I can later build the full url which normally
|
||||
looks like the following example when put together:
|
||||
http://127.0.0.1:6969/stats?mode=conn
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Matt West < https://github.com/mhwest13/OpenTracker-Munin-Plugin >
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf suggest
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use File::Basename;
|
||||
use LWP::UserAgent;
|
||||
|
||||
if (basename($0) !~ /^opentracker_/) {
|
||||
print "This script needs to be named opentracker_ and have symlinks which start the same.\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
my $host = $ENV{host} || '127.0.0.1';
|
||||
my $port = $ENV{port} || 6969;
|
||||
my $uri = $ENV{uri} || '/stats';
|
||||
|
||||
=head1 Graph Declarations
|
||||
|
||||
This block of code builds up all of the graph info for all root / sub graphs.
|
||||
|
||||
%graphs is a container for all of the graph definition information. In here is where you'll
|
||||
find the configuration information for munin's graphing procedure.
|
||||
Format:
|
||||
|
||||
$graph{graph_name} => {
|
||||
config => {
|
||||
{ key => value }, You'll find the main graph config stored here.
|
||||
{ ... },
|
||||
},
|
||||
keys => [ 'Name', 'Name', 'Name', ... ], Used for building results set.
|
||||
datasrc => [
|
||||
# Name: name given to data value
|
||||
# Attr: Attribute for given value, attribute must be valid plugin argument
|
||||
{ name => 'Name', info => 'info about graph' },
|
||||
{ ... },
|
||||
],
|
||||
results => {
|
||||
{ key => value }, You'll find the results info from fetch_stats call stored here.
|
||||
{ ... },
|
||||
},
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
my %graphs;
|
||||
|
||||
# graph for connections
|
||||
$graphs{conn} = {
|
||||
config => {
|
||||
args => '--lower-limit 0',
|
||||
vlabel => 'Connections',
|
||||
category => 'opentracker',
|
||||
title => 'Current Connections',
|
||||
info => 'Current Connections to OpenTracker',
|
||||
},
|
||||
keys => [ 'Requests', 'Announces' ],
|
||||
datasrc => [
|
||||
{ name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of Requests', draw => 'AREA' },
|
||||
{ name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of Announces', draw => 'LINE2' },
|
||||
],
|
||||
};
|
||||
# graph for peers
|
||||
$graphs{peer} = {
|
||||
config => {
|
||||
args => '--lower-limit 0',
|
||||
vlabel => 'Peers',
|
||||
category => 'opentracker',
|
||||
title => 'Peers and Seeders',
|
||||
info => 'Current Peer and Seeder Connections',
|
||||
},
|
||||
keys => [ 'Peers', 'Seeders' ],
|
||||
datasrc => [
|
||||
{ name => 'Peers', label => 'Peers', min => '0', type => 'GAUGE', info => 'current number of leechers & seeders (peers)', draw => 'AREA' },
|
||||
{ name => 'Seeders', label => 'Seeders', min => '0', type => 'GAUGE', info => 'current number of seeders', draw => 'LINE2' },
|
||||
],
|
||||
};
|
||||
# graph for scrapes
|
||||
$graphs{scrp} = {
|
||||
config => {
|
||||
args => '--lower-limit 0',
|
||||
vlabel => 'Scrapes',
|
||||
category => 'opentracker',
|
||||
title => 'Scrapes',
|
||||
info => 'Number of Scrapes (TCP/UDP)',
|
||||
},
|
||||
keys => [ 'TCP', 'UDP' ],
|
||||
datasrc => [
|
||||
{ name => 'TCP', label => 'TCP Requests', min => '0', type => 'COUNTER', info => 'number of scrapes requested via tcp', draw => 'AREASTACK' },
|
||||
{ name => 'UDP', label => 'UDP Requests', min => '0', type => 'COUNTER', info => 'number of scrapes requested via udp', draw => 'AREA' },
|
||||
],
|
||||
};
|
||||
# graph for livesyncs
|
||||
$graphs{syncs} = {
|
||||
config => {
|
||||
args => '--lower-limit 0',
|
||||
vlabel => 'Syncs',
|
||||
category => 'opentracker',
|
||||
title => 'LiveSyncs',
|
||||
info => 'OpenTracker LiveSync Requests',
|
||||
},
|
||||
keys => [ 'Incoming', 'Outgoing' ],
|
||||
datasrc => [
|
||||
{ name => 'Incoming', label => 'Incoming Syncs', min => '0', type => 'COUNTER', info => 'number of Incoming Syncs', draw => 'AREA' },
|
||||
{ name => 'Outgoing', label => 'Outgoing Syncs', min => '0', type => 'COUNTER', info => 'number of Outgoing Syncs', draw => 'LINE2' },
|
||||
],
|
||||
};
|
||||
# graph for tcp4 connections
|
||||
$graphs{tcp4} = {
|
||||
config => {
|
||||
args => '--lower-limit 0',
|
||||
vlabel => 'TCP4 Requests',
|
||||
category => 'opentracker',
|
||||
title => 'TCP4 Requests',
|
||||
info => 'Current TCP4 Requests / Announces',
|
||||
},
|
||||
keys => [ 'Requests', 'Announces' ],
|
||||
datasrc => [
|
||||
{ name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of tcp4 Requests', draw => 'AREA' },
|
||||
{ name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of tcp4 Announces', draw => 'LINE2' },
|
||||
],
|
||||
};
|
||||
# graph for torrents
|
||||
$graphs{torr} = {
|
||||
config => {
|
||||
args => '--lower-limit 0',
|
||||
vlabel => '# of Torrents',
|
||||
category => 'opentracker',
|
||||
title => 'Torrents',
|
||||
info => 'Current number of Torrents',
|
||||
},
|
||||
keys => [ 'Torrents' ],
|
||||
datasrc => [
|
||||
{ name => 'Torrents', label => 'Torrents', min => '0', type => 'GAUGE', info => 'number of torrents', draw => 'AREA' },
|
||||
],
|
||||
};
|
||||
# graph for udp4 connections
|
||||
$graphs{udp4} = {
|
||||
config => {
|
||||
args => '--lower-limit 0',
|
||||
vlabel => 'UDP4 Requests',
|
||||
category => 'opentracker',
|
||||
title => 'UDP4 Requests',
|
||||
info => 'Current UDP4 Requests / Announces',
|
||||
},
|
||||
keys => [ 'Requests', 'Announces' ],
|
||||
datasrc => [
|
||||
{ name => 'Requests', label => 'Requests', min => '0', type => 'COUNTER', info => 'number of udp4 Requests', draw => 'AREA' },
|
||||
{ name => 'Announces', label => 'Announces', min => '0', type => 'COUNTER', info => 'number of udp4 Announces', draw => 'LINE2' },
|
||||
],
|
||||
};
|
||||
|
||||
=head1 Munin Checks
|
||||
|
||||
These checks look for config / autoconf / suggest params
|
||||
|
||||
=head2 Config Check
|
||||
|
||||
This block of code looks at the argument that is possibly supplied,
|
||||
should it be config, it then checks to make sure the plugin
|
||||
specified exists, assuming it does, it will run the do_config
|
||||
subroutine for the plugin specified, otherwise it dies complaining
|
||||
about an unknown plugin.
|
||||
|
||||
=cut
|
||||
|
||||
if (defined $ARGV[0] && $ARGV[0] eq 'config') {
|
||||
# Lets take the plugin from the execution name.
|
||||
$0 =~ /opentracker_(.+)*/;
|
||||
my $plugin = $1;
|
||||
# And lets make sure we have a plugin called that.
|
||||
die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
|
||||
# Now lets go ahead and print out our config.
|
||||
print_config($plugin);
|
||||
exit 0;
|
||||
}
|
||||
|
||||
=head2 Autoconf Check
|
||||
|
||||
This block of code looks at the argument that is possibly supplied,
|
||||
should it be autoconf, we are going to print yes at this point since
|
||||
we've already tested for our binary to exist and be executable, the
|
||||
process will then exit.
|
||||
|
||||
=cut
|
||||
|
||||
if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
|
||||
# well we can execute the binary, so lets make sure we can curl opentracker
|
||||
my $url = "http://".$host.":".$port.$uri."\?mode=version";
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->timeout(15);
|
||||
my $response = $ua->get($url);
|
||||
if ($response->is_success) {
|
||||
print "yes\n";
|
||||
exit 0;
|
||||
} else {
|
||||
print "no: unable to connect to url: $url\n";
|
||||
exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
=head2 Suggest Check
|
||||
|
||||
This block of code looks at the argument that is possibly supplied,
|
||||
should it be suggest, we are going to print the possible plugins
|
||||
which can be specified.
|
||||
|
||||
=cut
|
||||
|
||||
if (defined $ARGV[0] && $ARGV[0] eq 'suggest') {
|
||||
# well we can execute the binary, so print possible plugin names
|
||||
my @rootplugins = ('conn','peer','scrp','syncs','tcp4','torr','udp4');
|
||||
foreach my $plugin (@rootplugins) {
|
||||
print "$plugin\n";
|
||||
}
|
||||
exit 0;
|
||||
}
|
||||
|
||||
=head1 Subroutines
|
||||
|
||||
Begin Subroutine calls to output data / config information
|
||||
|
||||
=head2 fetch_output
|
||||
|
||||
This subroutine is the main call for printing data for the plugin.
|
||||
No parameters are taken as this is the default call if no arguments
|
||||
are supplied from the command line.
|
||||
|
||||
=cut
|
||||
|
||||
fetch_output();
|
||||
|
||||
sub fetch_output {
|
||||
# Lets figure out what plugin they want to run, and check that it exists
|
||||
$0 =~ /opentracker_(.+)*/;
|
||||
my $plugin = $1;
|
||||
die 'Unknown Plugin Specified: ' . ($plugin ? $plugin : '') unless $graphs{$plugin};
|
||||
# Lets print out the data for our plugin
|
||||
print_output($plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
=head2 print_output
|
||||
|
||||
This block of code prints out the return values for our graphs. It takes
|
||||
one parameter $plugin. Returns when completed
|
||||
|
||||
$plugin; graph we are calling up to print data values for
|
||||
|
||||
Example: print_output($plugin);
|
||||
|
||||
=cut
|
||||
|
||||
sub print_output {
|
||||
# Lets get our plugin, set our graph information, and print for Munin to process
|
||||
my ($plugin) = (@_);
|
||||
my $graph = $graphs{$plugin};
|
||||
print "graph opentracker_$plugin\n";
|
||||
# Getting keys to pass to fetch_stats for data retrieval
|
||||
# call up fetch_stats with the keys we just got.
|
||||
my @keys = @{$graph->{keys}};
|
||||
fetch_stats($plugin,@keys);
|
||||
# print the results for the keys with the name for Munin to process
|
||||
foreach my $dsrc (@{$graph->{datasrc}}) {
|
||||
my $output = 0;
|
||||
my %datasrc = %$dsrc;
|
||||
while ( my ($key, $value) = each(%datasrc)) {
|
||||
next if ($key ne 'name');
|
||||
print "$dsrc->{name}.value $graph->{results}->{$value}\n";
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
=head2 print_config
|
||||
|
||||
This subroutine prints out the main config information for all of the graphs.
|
||||
It takes one parameters, $plugin
|
||||
|
||||
$plugin; graph being called up to print config for
|
||||
|
||||
Example: print_config($plugin);
|
||||
|
||||
=cut
|
||||
|
||||
sub print_config {
|
||||
# Lets get our plugin and graph, after that print for Munin to process it.
|
||||
my ($plugin) = (@_);
|
||||
my $graph = $graphs{$plugin};
|
||||
print "graph opentracker_$plugin\n";
|
||||
# Lets print out graph's main config info.
|
||||
my %graphconf = %{$graph->{config}};
|
||||
while ( my ($key, $value) = each(%graphconf)) {
|
||||
print "graph_$key $value\n";
|
||||
}
|
||||
# Lets print our graphs per graph config info.
|
||||
foreach my $dsrc (@{$graph->{datasrc}}) {
|
||||
my %datasrc = %$dsrc;
|
||||
while ( my ($key, $value) = each(%datasrc)) {
|
||||
next if ($key eq 'name');
|
||||
print "$dsrc->{name}.$key $value\n";
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
=head2 fetch_stats
|
||||
|
||||
This subroutine actually fetches data from opentracker with the plugin specified
|
||||
It will then parse the data using the keys assigned in an array.
|
||||
Two parameters are passed, $plugin and @keys, and it will return when complete.
|
||||
|
||||
$plugin; graph we are calling up, we use this to store the results in the hash
|
||||
for easy recall later.
|
||||
@keys; keys we want the values for from opentracker stats url.
|
||||
|
||||
Example: fetch_stats($plugin,@keys);
|
||||
|
||||
=cut
|
||||
|
||||
sub fetch_stats {
|
||||
# Lets get our current plugin and list of keys we want info for, as well as reference our graph
|
||||
my ($plugin,@keys) = (@_);
|
||||
my $graph = $graphs{$plugin};
|
||||
# Lets create our url to fetch
|
||||
my $url = "http://".$host.":".$port.$uri."\?mode=".$plugin;
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->timeout(15);
|
||||
my $response = $ua->get($url);
|
||||
# Lets print some info since we got back some info
|
||||
if ($response->is_success) {
|
||||
my @tmparray = split("\n",$response->content);
|
||||
foreach my $key (@keys) {
|
||||
my $value = shift(@tmparray);
|
||||
$graph->{results}->{$key} = $value;
|
||||
}
|
||||
} else {
|
||||
print "Unable to Fetch data from URL: $url\n";
|
||||
exit 1;
|
||||
}
|
||||
return;
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
Check http://aouyar.github.com/PyMunin/ to get the most recent versionof the
|
||||
PyMunin Multi graph Munin Plugins and documentation.
|
@ -1,2 +0,0 @@
|
||||
Check http://aouyar.github.com/PyMunin/
|
||||
to get the most recent versionof the PyMunin Multi graph Munin Plugins and documentation.
|
@ -1,54 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
|
||||
require LWP::UserAgent;
|
||||
|
||||
########################################################################################
|
||||
#
|
||||
# Installation / Configuration
|
||||
#
|
||||
# - place munin_xcache.php in a directory on your webserver
|
||||
# - add the url config to plugin-conf.d/munin-node
|
||||
#
|
||||
#
|
||||
# for more info see http://www.ohardt.net/dev/munin/
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
|
||||
chomp(my $fqdn=`hostname -f`);
|
||||
|
||||
|
||||
my $URL = exists $ENV{'url'} ? $ENV{'url'} : "http://user:pwd\@$fqdn/munin_xcache_new.php";
|
||||
|
||||
$URL = $URL . "?what=mem";
|
||||
|
||||
my $ua = LWP::UserAgent->new(timeout => 30);
|
||||
|
||||
|
||||
if ( exists $ARGV[0] and $ARGV[0] eq "config" )
|
||||
{
|
||||
|
||||
$URL = $URL . '&config';
|
||||
|
||||
my $response = $ua->request(HTTP::Request->new('GET',$URL . '&config' ));
|
||||
|
||||
print $response->content;
|
||||
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
|
||||
my $response = $ua->request(HTTP::Request->new('GET',$URL));
|
||||
|
||||
|
||||
print $response->content;
|
||||
|
||||
|
||||
exit( 0 );
|
||||
|
||||
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
Check http://aouyar.github.com/PyMunin/ to get the most recent versionof the
|
||||
PyMunin Multi graph Munin Plugins and documentation.
|
@ -1,28 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# toshiba_5520c_print_ munin grabber script
|
||||
# 2009.01 by steve@kosada.com
|
||||
|
||||
destination=`basename $0 | sed 's/^toshiba_5520c_print_//g'`
|
||||
|
||||
if [ "$1" = "config" ]; then
|
||||
echo "graph_title Toshiba 5520C: Pages Printed"
|
||||
echo 'graph_vlabel Pages'
|
||||
echo 'graph_args --lower-limit 0'
|
||||
echo 'graph_category printer'
|
||||
|
||||
echo "printBlack.label Black"
|
||||
echo "printBlack.draw AREA"
|
||||
|
||||
echo "printFullColor.label Full Color"
|
||||
echo "printFullColor.draw STACK"
|
||||
|
||||
echo "printTwinColor.label Twin Color"
|
||||
echo "printTwinColor.draw STACK"
|
||||
else
|
||||
infopage=`wget -q -O - http://$destination:8080/TopAccess/Counter/TotalCount/List.htm | dos2unix | perl -p -e 's/\n/ /m'`
|
||||
|
||||
echo printFullColor.value `echo $infopage | perl -p -e 's/^.+\<B\>Print Counter\<\/B\>.+?\{Full\ Color[^}]+\,([0-9]+)\}.+$/$1/'`
|
||||
echo printTwinColor.value `echo $infopage | perl -p -e 's/^.+\<B\>Print Counter\<\/B\>.+?\{Twin\ Color[^}]+\,([0-9]+)\}.+$/$1/'`
|
||||
echo printBlack.value `echo $infopage | perl -p -e 's/^.+\<B\>Print Counter\<\/B\>.+?\{Black[^}]+\,([0-9]+)\}.+$/$1/'`
|
||||
fi
|
@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
HOST=${host:-"127.0.0.1"}
|
||||
|
||||
: << =cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
snmp_HPLJ2015 - Consumables level on HP LaserJet 2015n reported over SNMP
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
HOST
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Oleksiy Kochkin
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
As is.
|
||||
|
||||
=back
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=contrib
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=cut
|
||||
|
||||
case $1 in
|
||||
config)
|
||||
|
||||
echo "graph_title Consumables level @ $HOST"
|
||||
echo 'graph_args --upper-limit 100 -l 0'
|
||||
echo 'graph_vlabel %'
|
||||
echo 'graph_category printers'
|
||||
echo 'graph_scale no'
|
||||
echo 'black.label Black toner level'
|
||||
echo 'black.draw LINE2'
|
||||
echo 'black.type GAUGE'
|
||||
echo 'black.colour 000000'
|
||||
echo 'black.warning 5:'
|
||||
echo 'black.critical 1:'
|
||||
echo 'black.min 0'
|
||||
echo 'black.max 100'
|
||||
exit 0;;
|
||||
esac
|
||||
|
||||
BLACK_MAX_OID=".1.3.6.1.2.1.43.11.1.1.8.1.1"
|
||||
BLACK_LVL_OID=".1.3.6.1.2.1.43.11.1.1.9.1.1"
|
||||
|
||||
BLACK_MAX=`snmpget -v 1 -c public -Ov -Oq $HOST $BLACK_MAX_OID`
|
||||
BLACK_LVL=`snmpget -v 1 -c public -Ov -Oq $HOST $BLACK_LVL_OID`
|
||||
BLACK_LVL_PERCENTS=$(($BLACK_LVL*100/$BLACK_MAX))
|
||||
|
||||
echo -n "black.value "
|
||||
echo $BLACK_LVL_PERCENTS
|
Loading…
Reference in New Issue
Block a user