"Fossies" - the Fresh Open Source Software Archive

Member "munin-2.0.52/plugins/node.d.linux/iostat.in" (20 Nov 2019, 5014 Bytes) of package /linux/misc/munin-2.0.52.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 #!@@PERL@@ -w
    2 # -*- cperl -*-
    3 =head1 NAME
    4 
    5 iostat - Munin plugin to monitor io-bound traffic (in blocks) on disks
    6 
    7 =head1 APPLICABLE SYSTEMS
    8 
    9 Linux systems.
   10 
   11 =head1 CONFIGURATION
   12 
   13 The plugin detects block devices from /proc/diskstat or /proc/stat.
   14 By default it will only show un-numbered devices such as sda and not
   15 sda0.  By setting
   16 
   17    [iostat]
   18    env.SHOW_NUMBERED 1
   19 
   20 it will show numbered devices.  This is sometimes needed in
   21 virtualized environments (e.g. Xen) where sda1 to sda<n> exists but
   22 not sda.  In a virtualized environment this is usefull to show which
   23 guest OS/dom-U IO-traffic originates in.
   24 
   25 =head1 USAGE
   26 
   27 Link this plugin to @@CONFDIR@@/plugins/ and restart the munin-node.
   28 
   29 =head1 INTERPRETATION
   30 
   31 To be written...
   32 
   33 =head1 MAGIC MARKERS
   34 
   35  #%# family=legacy
   36  #%# capabilities=autoconf
   37 
   38 =head1 VERSION
   39 
   40   $Id$
   41 
   42 =head1 AUTHOR
   43 
   44 This plugin has been in Munin since it was called "LRRD".  The log for
   45 this file shows that there was a rewrite by Mike Fedyk applied in
   46 January 2004.  We have no other records of who wrote it.
   47 
   48 =head1 LICENSE
   49 
   50 GPLv2
   51 
   52 =cut
   53 
   54 use strict;
   55 
   56 use Munin::Plugin;
   57 
   58 my $detailed_present = 0;
   59 my $stat_present = 0;
   60 my $include_numbered = 0;    # By default we want sda but not sda1
   61 
   62 if (defined $ENV{'SHOW_NUMBERED'}) {
   63     $include_numbered = $ENV{'SHOW_NUMBERED'};
   64 };
   65 
   66 if (system("grep -q '' /proc/diskstats > /dev/null 2>&1") == 0 ||
   67     system("grep -q 'rio rmerge rsect ruse wio wmerge wsect wuse running use aveq' /proc/partitions > /dev/null 2>&1") == 0) {
   68     $detailed_present = 1;
   69 } elsif (system("grep -q '^disk_io: [^ ]' /proc/stat") == 0) {
   70     $stat_present = 1;
   71 }
   72 
   73 if ( $ARGV[0] and $ARGV[0] eq "autoconf") {
   74     if ($detailed_present eq 1 || $stat_present eq 1) {
   75 	print "yes\n";
   76 	exit 0;
   77     }
   78     print "no\n";
   79     exit 0;
   80 }
   81 
   82 my %devs;
   83 
   84 if ($detailed_present eq 1) {
   85     &fetch_detailed;
   86 } elsif ($stat_present eq 1) {
   87     # Falling back to /proc/stat
   88     &fetch_stat;
   89 }
   90 
   91 if ( $ARGV[0] and $ARGV[0] eq "config") {
   92     print "graph_title IOstat\n";
   93     print "graph_args --base 1024 -l 0\n";
   94     print "graph_vlabel blocks per \${graph_period} read (-) / written (+)\n";
   95     print "graph_category disk\n";
   96     print "graph_total Total\n" if (keys (%devs) > 1);
   97     print "graph_info This graph shows the I/O to and from block devices.\n";
   98     print "graph_order";
   99     foreach my $key (sort by_dev keys %devs) {
  100 	print " ", $key, "_read ", $key, "_write ";
  101     }
  102     print "\n";
  103     foreach my $key (sort by_dev keys %devs) {
  104 	print $key . "_read.label $devs{$key}->{name}\n";
  105 	print $key . "_read.type DERIVE\n";
  106 	print $key . "_read.min 0\n";
  107 	print $key . "_read.graph no\n";
  108 	print $key . "_write.label $devs{$key}->{name}\n";
  109 	print $key . "_write.info I/O on device $devs{$key}->{name}\n";
  110 	print $key . "_write.type DERIVE\n";
  111 	print $key . "_write.min 0\n";
  112 	print $key . "_write.negative " . $key . "_read\n";
  113 
  114 	print_thresholds($key . "_read");
  115 	print_thresholds($key . "_write");
  116     }
  117     exit 0;
  118 }
  119 
  120 foreach my $key (sort by_dev keys %devs) {
  121     print $key, "_read.value ", $devs{$key}->{rsect}, "\n";
  122     print $key, "_write.value ", $devs{$key}->{wsect}, "\n";
  123 }
  124 
  125 sub by_dev {
  126     return $a cmp $b;
  127 }
  128 
  129 sub fetch_stat() {
  130     open (IN, "/proc/stat") or
  131       die "Could not open /proc/stat for reading: $!\n";
  132 
  133     while (<IN>) {
  134 	next unless (/^disk_io:\s*(.+)\s*/);
  135 	foreach my $dev (split /\s+/) {
  136 	    next unless $dev =~ /\S/;
  137 	    next unless ($dev =~ /\((\d+),(\d+)\):\(\d+,(\d+),(\d+),(\d+),(\d+)\)/);
  138 	    my $name = "dev".$1."_".$2;
  139 	    $devs{$name} =
  140 	      {
  141 	       name => $name,
  142 	       rio => $3,
  143 	       rsect => $4,
  144 	       wio => $5,
  145 	       wsect => $6
  146 	      };
  147 	}
  148     }
  149     close (IN);
  150 }
  151 
  152 my %maj_count;
  153 
  154 sub get_disk_count() {
  155     my @disk_count;
  156     my $major = $_[0];
  157     $maj_count{$major} = 0 unless exists($maj_count{$major});
  158     $disk_count[0] = $maj_count{$major}++;
  159     die "Could not find disk_count for major: $major"
  160       unless (exists($disk_count[0]));
  161     return $disk_count[0];
  162 }
  163 
  164 sub fetch_detailed() {
  165     if (open(DETAILED, "/proc/diskstats") or
  166 	open(DETAILED, "/proc/partitions")) {
  167 
  168 	while (<DETAILED>) {
  169 	    if (/^\s+(\d+)\s+\d+\s*\d*\s+([[:alpha:][:digit:]\/]+)\s+(.*)/) {
  170 		my @fields = split(/\s+/, $3);
  171 		my $tmpnam = $2;
  172 		my $major  = $1;
  173 		if ($tmpnam =~ /\d+$/ and !$include_numbered) {
  174 		    # Special case for devices like cXdXpX,
  175 		    # like the cciss driver
  176 		    next unless $tmpnam =~ /\/c\d+d\d+$/
  177 		}
  178 		next unless grep { $_ } @fields;
  179 
  180 		$tmpnam =~ s/\/[[:alpha:]]+(\d+)/\/$1/g;
  181 		$tmpnam =~ s/^([^\/]+)\//$1/;
  182 		$tmpnam =~ s/\/disc$//;
  183 
  184 		$devs{"dev".$major."_".&get_disk_count($major)} =
  185 		  {
  186 		   major => $major,
  187 		   name => $tmpnam,
  188 		   rio => $fields[0],
  189 		   rmerge => $fields[1],
  190 		   rsect => $fields[2],
  191 		   ruse => $fields[3],
  192 		   wio => $fields[4],
  193 		   wmerge => $fields[5],
  194 		   wsect => $fields[6],
  195 		   wuse => $fields[7],
  196 		   running => $fields[8],
  197 		   use => $fields[9],
  198 		   aveq => $fields[10]
  199 		  };
  200 	    }
  201 	}
  202 	close (DETAILED);
  203     }
  204 }
  205 # vim:syntax=perl