Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / disk / md_iostat_ @ c96bafa1

Historique | Voir | Annoter | Télécharger (7,08 ko)

1 4eb89df7 various
#!/usr/bin/perl -w
2
#
3
# Plugin for watching io-bound traffic (in blocks) on disks.
4
#
5
# Usage: Link or copy into /etc/lrrd/client.d/
6
#
7
# Parameters:
8
#
9
# 	config   (required)
10
# 	autoconf (optional - used by lrrd-config)
11
#
12
# $Log$
13
# Revision 1.14  2004/12/10 18:51:44  jimmyo
14
# linux/apt* has been forced to LANG=C, to get predictable output.
15
#
16
# Revision 1.13  2004/12/10 10:47:49  jimmyo
17
# Change name from ${scale} to ${graph_period}, to be more consistent.
18
#
19
# Revision 1.12  2004/12/09 22:12:56  jimmyo
20
# Added "graph_period" option, to make "graph_sums" usable.
21
#
22
# Revision 1.11  2004/11/21 00:17:12  jimmyo
23
# Changed a lot of plugins so they use DERIVE instead of COUNTER.
24
#
25
# Revision 1.10  2004/11/20 23:58:22  jimmyo
26
# The linux/iostat plugin now ignores devices without traffic (Deb#267195).
27
#
28
# Revision 1.9  2004/09/25 22:29:16  jimmyo
29
# Added info fields to a bunch of plugins.
30
#
31
# Revision 1.8  2004/08/24 13:37:29  ilmari
32
# Add total line
33
#
34
# Revision 1.7  2004/05/20 13:57:12  jimmyo
35
# Set categories to some of the plugins.
36
#
37
# Revision 1.6  2004/02/02 18:18:07  jimmyo
38
# Changed to an informative vlabel, since the field.label information has been made shorter.
39
#
40
# Revision 1.5  2004/02/02 17:52:32  jimmyo
41
# Linux/iostat now shows only disks also on machines without devfs.
42
#
43
# Revision 1.4  2004/02/02 16:54:38  jimmyo
44
# Make the iostat plugin work properly.
45
#
46
# Revision 1.3  2004/02/02 16:53:53  jimmyo
47
# Make the iostat plugin work properly.
48
#
49
# Revision 1.2  2004/01/31 19:24:52  jimmyo
50
# Rewrite of linux/iostat by Mike Fedyk (Deb##223373,224113).
51
#
52
# Revision 1.1  2004/01/02 18:50:01  jimmyo
53
# Renamed occurrances of lrrd -> munin
54
#
55
# Revision 1.1.1.1  2004/01/02 15:18:07  jimmyo
56
# Import of LRRD CVS tree after renaming to Munin
57
#
58
# Revision 1.5  2003/12/18 18:09:32  jimmyo
59
# Added total line
60
#
61
# Revision 1.4  2003/12/18 11:01:51  jimmyo
62
# Fix by_dev compare issue.
63
#
64
# Revision 1.3  2003/12/16 17:51:08  jimmyo
65
# Plugin linux/iostat modified. Now runs on 2.6, and now "mirrors" i/o like eth* et al. (Deb#224113, Deb#223373)
66
#
67
# Revision 1.2  2003/11/07 17:43:16  jimmyo
68
# Cleanups and log entries
69
#
70
#
71
#
72
# Magic markers (optional - used by lrrd-config and some installation
73
# scripts):
74
#
75
#%# family=auto
76
#%# capabilities=autoconf
77
78
use strict;
79
use Data::Dumper;
80
81
# Where to get stats from
82
my $detailed_present = 0;
83
my $stat_present = 0;
84
# And md things here?
85
my $mdstat_present = 0;
86
87
if ( (-f '/proc/diskstats') or
88
     (system("grep -q 'rio rmerge rsect ruse wio wmerge wsect wuse running use aveq' /proc/partitions") == 0) ) {
89
  $detailed_present = 1;
90
} elsif (system("grep -q '^disk_io: [^ ]' /proc/stat") == 0) {
91
  $stat_present = 1;
92
}
93
94
$mdstat_present = -f '/proc/mdstat';
95
96
if ( defined($ARGV[0]) and $ARGV[0] eq "autoconf") {
97
  if ($mdstat_present and ($detailed_present or $stat_present)) {
98
    print "yes\n";
99
    exit 0;
100
  }
101
  print "no\n";
102
  exit 1;
103
}
104
105
my %devs;
106
my %nametodev;
107
108
if ($detailed_present) {
109
  &fetch_detailed;
110
} elsif ($stat_present) {
111
  # Falling back to /proc/stat
112
  &fetch_stat;
113
}
114
115
my $md = $0;
116
$md =~ s/.*_//;
117
118
open(MD,"/proc/mdstat");
119
120
my ($dev,$mdstatus,$raid,@devs);
121
122
while (<MD>) {
123
  next unless /^$md/o;
124
  ($dev, $mdstatus) = split(/\s+:\s+/,$_,2);
125
  ($mdstatus, $raid, @devs) = split(/\s+/,$mdstatus);
126
  last;
127
}
128
129
# print "DEVICES: ",join(', ',@devs),"\n";
130
131
# Remove unwanted things like raid device number, partition number
132
# and sort nicely.
133
@devs = sort by_dev map { s/\d*\[.*\]$//; $_; } @devs;
134
135
# Insert the raid device into the mix.
136
unshift(@devs,$md);
137
138
# And translate to the device name used by the datastructures.
139
@devs = map { $nametodev{$_}; } @devs;
140
141
close(MD);
142
my $i=0;
143
144
if ( $ARGV[0] and $ARGV[0] eq "config") {
145
	print "graph_title IOstat for $md\n";
146
	print "graph_args --base 1024 -l 0\n";
147
	print "graph_vlabel blocks / \${graph_period} read (-) / written (+)\n";
148
	print "graph_category disk\n";
149
	print "graph_info This graph shows the I/O to and from block devices comprising the $raid device $md.\n";
150
151
	my @grapho = @devs;
152
	# The first shall be last
153
	push(@grapho,shift(@grapho));
154
155
	print "graph_order";
156
	foreach my $key (@grapho) {
157
	  print " ", $key, "_read ", $key, "_write ";
158
	}
159
	print "\n";
160
	foreach my $key (@devs) {
161
	  print $key . "_read.label $devs{$key}->{name}\n";
162
		print $key . "_read.type DERIVE\n";
163
		print $key . "_read.max 900000\n";
164
		print $key . "_read.min 0\n";
165
		print $key . "_read.graph no\n";
166
		print $key . "_write.label $devs{$key}->{name}\n";
167
		print $key . "_write.info I/O on device $devs{$key}->{name}\n";
168
		print $key . "_write.type DERIVE\n";
169
		print $key . "_write.max 900000\n";
170
		print $key . "_write.min 0\n";
171
		print $key . "_write.negative " . $key . "_read\n";
172
	  if ($i == 0) {
173
	    print "${key}_read.draw LINE2\n";
174
	    print "${key}_write.draw LINE2\n";
175
	  } elsif ($i == 1) {
176
	    print "${key}_read.draw AREA\n";
177
	    print "${key}_write.draw AREA\n";
178
	  } else {
179
	    print "${key}_read.draw STACK\n";
180
	    print "${key}_write.draw STACK\n";
181
	  }
182
	  $i++;
183
	}
184
	exit 0;
185
}
186
187
# print Dumper \%nametodev;
188
# print Dumper \%devs;
189
190
foreach my $key (@devs) {
191
  # print "Device name: $key, iostat name: ",$nametodev{$key},"\n";
192
  print $key, "_read.value ", $devs{$key}->{rsect}, "\n";
193
  print $key, "_write.value ", $devs{$key}->{wsect}, "\n";
194
}
195
196
sub by_dev {
197
	return $a cmp $b;
198
}
199
200
sub fetch_stat() {
201
  open (IN, "/proc/stat") or die "Could not open /proc/stat for reading: $!\n";
202
203
  while (<IN>) {
204
    next unless (/^disk_io:\s*(.+)\s*/);
205
    foreach my $dev (split /\s+/) {
206
      next unless $dev =~ /\S/;
207
      next unless ($dev =~ /\((\d+),(\d+)\):\(\d+,(\d+),(\d+),(\d+),(\d+)\)/);
208
209
      my $name = "dev".$1."_".$2;
210
211
      $nametodev{$name}=$name;
212
213
      $devs{$name} = {
214
		      name => $name,
215
		      rio => $3,
216
		      rsect => $4,
217
		      wio => $5,
218
		      wsect => $6
219
		     };
220
    }
221
  }
222
  close (IN);
223
}
224
225
my %maj_count;
226
sub get_disk_count()
227
{
228
	my @disk_count;
229
	my $major = $_[0];
230
	$maj_count{$major} = 0 unless exists($maj_count{$major});
231
	$disk_count[0] = $maj_count{$major}++;
232
	die "Could not find disk_count for major: $major" unless (exists($disk_count[0]));
233
	return $disk_count[0];
234
}
235
236
237
sub fetch_detailed() {
238
239
  if (open(DETAILED, "/proc/diskstats")
240
      or open(DETAILED, "/proc/partitions")) {
241
    while (<DETAILED>) {
242
      if (/^\s+(\d+)\s+\d+\s*\d*\s+([[:alpha:][:digit:]\/]+)\s+(.*)/) {
243
	my @fields = split(/\s+/, $3);
244
	my $tmpnam = $2;
245
	my $major  = $1;
246
	if ($tmpnam =~ /^md\d+/) {
247
	  # That's fine, we want raid disks reported here.
248
	} elsif ($tmpnam =~ /\d+$/ ) {
249
	  # Special case for devices like cXdXpX,
250
	  # like the cciss driver
251
	  next unless $tmpnam =~ /\/c\d+d\d+$/
252
	}
253
	next unless grep { $_ } @fields;
254
255
	$tmpnam =~ s/\/[[:alpha:]]+(\d+)/\/$1/g;
256
	$tmpnam =~ s/^([^\/]+)\//$1/;
257
	$tmpnam =~ s/\/disc$//;
258
259
	my $devnam = "dev".$major."_".&get_disk_count($major);
260
261
	$nametodev{$tmpnam} = $devnam;
262
263
	$devs{$devnam} = {
264
			  major => $major,
265
			  name => $tmpnam,
266
			  rio => $fields[0],
267
			  rmerge => $fields[1],
268
			  rsect => $fields[2],
269
			  ruse => $fields[3],
270
			  wio => $fields[4],
271
			  wmerge => $fields[5],
272
			  wsect => $fields[6],
273
			  wuse => $fields[7],
274
			  running => $fields[8],
275
			  use => $fields[9],
276
			  aveq => $fields[10]
277
			 };
278
      }
279
    }
280
    close (DETAILED);
281
  }
282
}
283
# vim:syntax=perl