Created
January 8, 2010 16:07
-
-
Save jashkenas/272134 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
# | |
# Plugin for watching io-bound traffic (in blocks) on disks. | |
# | |
# Usage: Link or copy into /etc/lrrd/client.d/ | |
# | |
# Parameters: | |
# | |
# config (required) | |
# autoconf (optional - used by lrrd-config) | |
# | |
# $Log$ | |
# Revision 1.14 2004/12/10 18:51:44 jimmyo | |
# linux/apt* has been forced to LANG=C, to get predictable output. | |
# | |
# Revision 1.13 2004/12/10 10:47:49 jimmyo | |
# Change name from ${scale} to ${graph_period}, to be more consistent. | |
# | |
# Revision 1.12 2004/12/09 22:12:56 jimmyo | |
# Added "graph_period" option, to make "graph_sums" usable. | |
# | |
# Revision 1.11 2004/11/21 00:17:12 jimmyo | |
# Changed a lot of plugins so they use DERIVE instead of COUNTER. | |
# | |
# Revision 1.10 2004/11/20 23:58:22 jimmyo | |
# The linux/iostat plugin now ignores devices without traffic (Deb#267195). | |
# | |
# Revision 1.9 2004/09/25 22:29:16 jimmyo | |
# Added info fields to a bunch of plugins. | |
# | |
# Revision 1.8 2004/08/24 13:37:29 ilmari | |
# Add total line | |
# | |
# Revision 1.7 2004/05/20 13:57:12 jimmyo | |
# Set categories to some of the plugins. | |
# | |
# Revision 1.6 2004/02/02 18:18:07 jimmyo | |
# Changed to an informative vlabel, since the field.label information has been made shorter. | |
# | |
# Revision 1.5 2004/02/02 17:52:32 jimmyo | |
# Linux/iostat now shows only disks also on machines without devfs. | |
# | |
# Revision 1.4 2004/02/02 16:54:38 jimmyo | |
# Make the iostat plugin work properly. | |
# | |
# Revision 1.3 2004/02/02 16:53:53 jimmyo | |
# Make the iostat plugin work properly. | |
# | |
# Revision 1.2 2004/01/31 19:24:52 jimmyo | |
# Rewrite of linux/iostat by Mike Fedyk (Deb##223373,224113). | |
# | |
# Revision 1.1 2004/01/02 18:50:01 jimmyo | |
# Renamed occurrances of lrrd -> munin | |
# | |
# Revision 1.1.1.1 2004/01/02 15:18:07 jimmyo | |
# Import of LRRD CVS tree after renaming to Munin | |
# | |
# Revision 1.5 2003/12/18 18:09:32 jimmyo | |
# Added total line | |
# | |
# Revision 1.4 2003/12/18 11:01:51 jimmyo | |
# Fix by_dev compare issue. | |
# | |
# Revision 1.3 2003/12/16 17:51:08 jimmyo | |
# Plugin linux/iostat modified. Now runs on 2.6, and now "mirrors" i/o like eth* et al. (Deb#224113, Deb#223373) | |
# | |
# Revision 1.2 2003/11/07 17:43:16 jimmyo | |
# Cleanups and log entries | |
# | |
# | |
# | |
# Magic markers (optional - used by lrrd-config and some installation | |
# scripts): | |
# | |
#%# family=auto | |
#%# capabilities=autoconf | |
use strict; | |
my $detailed_present = my $stat_present = 0; | |
if (system("grep -q '' /proc/diskstats > /dev/null 2>&1") == 0 | |
|| system("grep -q 'rio rmerge rsect ruse wio wmerge wsect wuse running use aveq' /proc/partitions > /dev/null 2>&1") == 0) | |
{ | |
$detailed_present = 1; | |
} | |
elsif (system("grep -q '^disk_io: [^ ]' /proc/stat") == 0) | |
{ | |
$stat_present = 1; | |
} | |
if ( $ARGV[0] and $ARGV[0] eq "autoconf") | |
{ | |
if ($detailed_present eq 1 || $stat_present eq 1) | |
{ | |
print "yes\n"; | |
exit 0; | |
} | |
print "no\n"; | |
exit 1; | |
} | |
my %devs; | |
if ($detailed_present eq 1) | |
{ | |
&fetch_detailed; | |
} | |
# Falling back to /proc/stat | |
elsif ($stat_present eq 1) | |
{ | |
&fetch_stat; | |
} | |
if ( $ARGV[0] and $ARGV[0] eq "config") | |
{ | |
print "graph_title IOstat\n"; | |
print "graph_args --base 1024 -l 0\n"; | |
print "graph_vlabel blocks per \${graph_period} read (-) / written (+)\n"; | |
print "graph_category disk\n"; | |
print "graph_total Total\n" if (keys (%devs) > 1); | |
print "graph_info This graph shows the I/O to and from block devices.\n"; | |
print "graph_order"; | |
foreach my $key (sort by_dev keys %devs) | |
{ | |
print " ", $key, "_read ", $key, "_write "; | |
} | |
print "\n"; | |
foreach my $key (sort by_dev keys %devs) | |
{ | |
print $key . "_read.label $devs{$key}->{name}\n"; | |
print $key . "_read.type DERIVE\n"; | |
print $key . "_read.max 900000\n"; | |
print $key . "_read.min 0\n"; | |
print $key . "_read.graph no\n"; | |
print $key . "_write.label $devs{$key}->{name}\n"; | |
print $key . "_write.info I/O on device $devs{$key}->{name}\n"; | |
print $key . "_write.type DERIVE\n"; | |
print $key . "_write.max 900000\n"; | |
print $key . "_write.min 0\n"; | |
print $key . "_write.negative " . $key . "_read\n"; | |
} | |
exit 0; | |
} | |
foreach my $key (sort by_dev keys %devs) | |
{ | |
print $key, "_read.value ", $devs{$key}->{rsect}, "\n"; | |
print $key, "_write.value ", $devs{$key}->{wsect}, "\n"; | |
} | |
sub by_dev { | |
return $a cmp $b; | |
} | |
sub fetch_stat() | |
{ | |
open (IN, "/proc/stat") or die "Could not open /proc/stat for reading: $!\n"; | |
while (<IN>) | |
{ | |
next unless (/^disk_io:\s*(.+)\s*/); | |
foreach my $dev (split /\s+/) | |
{ | |
next unless $dev =~ /\S/; | |
next unless ($dev =~ /\((\d+),(\d+)\):\(\d+,(\d+),(\d+),(\d+),(\d+)\)/); | |
my $name = "dev".$1."_".$2; | |
$devs{$name} = | |
{ | |
name => $name, | |
rio => $3, | |
rsect => $4, | |
wio => $5, | |
wsect => $6 | |
}; | |
} | |
} | |
close (IN); | |
} | |
my %maj_count; | |
sub get_disk_count() | |
{ | |
my @disk_count; | |
my $major = $_[0]; | |
$maj_count{$major} = 0 unless exists($maj_count{$major}); | |
$disk_count[0] = $maj_count{$major}++; | |
die "Could not find disk_count for major: $major" unless (exists($disk_count[0])); | |
return $disk_count[0]; | |
} | |
sub fetch_detailed() | |
{ | |
if (open(DETAILED, "/proc/diskstats") or open(DETAILED, "/proc/partitions")) | |
{ | |
while (<DETAILED>) | |
{ | |
if (/^\s+(\d+)\s+\d+\s*\d*\s+([[:alpha:][:digit:]\/]+)\s+(.*)/) | |
{ | |
my @fields = split(/\s+/, $3); | |
my $tmpnam = $2; | |
my $major = $1; | |
if ($tmpnam =~ /\d+$/ ) { | |
# Special case for devices like cXdXpX, | |
# like the cciss driver | |
next unless $tmpnam =~ /\/c\d+d\d+$/ | |
} | |
next unless grep { $_ } @fields; | |
$tmpnam =~ s/\/[[:alpha:]]+(\d+)/\/$1/g; | |
$tmpnam =~ s/^([^\/]+)\//$1/; | |
$tmpnam =~ s/\/disc$//; | |
$devs{"dev".$major."_".&get_disk_count($major)} = | |
{ | |
major => $major, | |
name => $tmpnam, | |
rio => $fields[0], | |
rmerge => $fields[1], | |
rsect => $fields[2], | |
ruse => $fields[3], | |
wio => $fields[4], | |
wmerge => $fields[5], | |
wsect => $fields[6], | |
wuse => $fields[7], | |
running => $fields[8], | |
use => $fields[9], | |
aveq => $fields[10] | |
}; | |
} | |
} | |
close (DETAILED); | |
} | |
} | |
# vim:syntax=perl |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment