| 1 |
package Core::Iostat; |
|---|
| 2 |
|
|---|
| 3 |
use strict; |
|---|
| 4 |
use warnings; |
|---|
| 5 |
|
|---|
| 6 |
use base 'Resmon::Module'; |
|---|
| 7 |
|
|---|
| 8 |
use Resmon::ExtComm qw(run_command cache_command); |
|---|
| 9 |
|
|---|
| 10 |
=pod |
|---|
| 11 |
|
|---|
| 12 |
=head1 NAME |
|---|
| 13 |
|
|---|
| 14 |
Core::Iostat - Monitor disk I/O statistics using iostat |
|---|
| 15 |
|
|---|
| 16 |
=head1 SYNOPSIS |
|---|
| 17 |
|
|---|
| 18 |
Core::Iostat { |
|---|
| 19 |
sd0 : noop |
|---|
| 20 |
sd1 : noop |
|---|
| 21 |
} |
|---|
| 22 |
|
|---|
| 23 |
Core::Iostat { |
|---|
| 24 |
hda : iostat_path => /usr/sbin/iostat |
|---|
| 25 |
} |
|---|
| 26 |
|
|---|
| 27 |
=head1 DESCRIPTION |
|---|
| 28 |
|
|---|
| 29 |
This module monitors I/O statistics for a given disk. It uses the running |
|---|
| 30 |
total values reported by iostat. The type and number of metrics returned |
|---|
| 31 |
depend on the type returned by each platform's respective iostat command. |
|---|
| 32 |
|
|---|
| 33 |
=head1 CONFIGURATION |
|---|
| 34 |
|
|---|
| 35 |
=over |
|---|
| 36 |
|
|---|
| 37 |
=item check_name |
|---|
| 38 |
|
|---|
| 39 |
The name of the check refers to the disk to query status for. |
|---|
| 40 |
|
|---|
| 41 |
=item iostat_path |
|---|
| 42 |
|
|---|
| 43 |
Provide an alternate path to the iostat command (optional). |
|---|
| 44 |
|
|---|
| 45 |
=back |
|---|
| 46 |
|
|---|
| 47 |
=head1 METRICS |
|---|
| 48 |
|
|---|
| 49 |
=over |
|---|
| 50 |
|
|---|
| 51 |
=item reads_sec |
|---|
| 52 |
|
|---|
| 53 |
Reads per second. |
|---|
| 54 |
|
|---|
| 55 |
=item writes_sec |
|---|
| 56 |
|
|---|
| 57 |
Writes per second. |
|---|
| 58 |
|
|---|
| 59 |
=item kb_read_sec |
|---|
| 60 |
|
|---|
| 61 |
Kilobytes read per second. |
|---|
| 62 |
|
|---|
| 63 |
=item kb_write_sec |
|---|
| 64 |
|
|---|
| 65 |
Kilobytes written per second. |
|---|
| 66 |
|
|---|
| 67 |
=item wait_txn |
|---|
| 68 |
|
|---|
| 69 |
Average number of transactions waiting for service. |
|---|
| 70 |
|
|---|
| 71 |
=item actv_txn |
|---|
| 72 |
|
|---|
| 73 |
Average number of transactions actively being serviced. |
|---|
| 74 |
|
|---|
| 75 |
=item rspt_txn |
|---|
| 76 |
|
|---|
| 77 |
Average response time of transactions, in milliseconds. |
|---|
| 78 |
|
|---|
| 79 |
=item wait_pct |
|---|
| 80 |
|
|---|
| 81 |
Percent of time there are transactions waiting for service. |
|---|
| 82 |
|
|---|
| 83 |
=item busy_pct |
|---|
| 84 |
|
|---|
| 85 |
Percent of time the disk is busy. |
|---|
| 86 |
|
|---|
| 87 |
=item soft_errors |
|---|
| 88 |
|
|---|
| 89 |
Number of soft errors. |
|---|
| 90 |
|
|---|
| 91 |
=item hard_errors |
|---|
| 92 |
|
|---|
| 93 |
Number of hard errors. |
|---|
| 94 |
|
|---|
| 95 |
=item txport_errors |
|---|
| 96 |
|
|---|
| 97 |
Number of transport errors. |
|---|
| 98 |
|
|---|
| 99 |
=item kb_xfrd |
|---|
| 100 |
|
|---|
| 101 |
Kilobytes transferred. |
|---|
| 102 |
|
|---|
| 103 |
=item disk_xfrs |
|---|
| 104 |
|
|---|
| 105 |
Disk transfers. |
|---|
| 106 |
|
|---|
| 107 |
=item busy_sec |
|---|
| 108 |
|
|---|
| 109 |
Seconds spent in disk activity. |
|---|
| 110 |
|
|---|
| 111 |
=item xfrs_sec |
|---|
| 112 |
|
|---|
| 113 |
Disk transfers per second. |
|---|
| 114 |
|
|---|
| 115 |
=back |
|---|
| 116 |
|
|---|
| 117 |
=cut |
|---|
| 118 |
|
|---|
| 119 |
sub handler { |
|---|
| 120 |
my $self = shift; |
|---|
| 121 |
my $disk = $self->{'check_name'}; |
|---|
| 122 |
my $config = $self->{'config'}; |
|---|
| 123 |
my $iostat_path = $config->{'iostat_path'} || 'iostat'; |
|---|
| 124 |
my $osname = $^O; |
|---|
| 125 |
|
|---|
| 126 |
if ($osname eq 'solaris') { |
|---|
| 127 |
my $output = run_command("$iostat_path -xe $disk"); |
|---|
| 128 |
my ($line) = grep(/$disk\s*/, split(/\n/, $output)); |
|---|
| 129 |
if ($line =~ /$disk\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+).*/) { |
|---|
| 130 |
return { |
|---|
| 131 |
'reads_sec' => [$1, 'i'], |
|---|
| 132 |
'writes_sec' => [$2, 'i'], |
|---|
| 133 |
'kb_read_sec' => [$3, 'i'], |
|---|
| 134 |
'kb_write_sec' => [$4, 'i'], |
|---|
| 135 |
'wait_txn' => [$5, 'i'], |
|---|
| 136 |
'actv_txn' => [$6, 'i'], |
|---|
| 137 |
'rspt_txn' => [$7, 'i'], |
|---|
| 138 |
'wait_pct' => [$8, 'i'], |
|---|
| 139 |
'busy_pct' => [$9, 'i'], |
|---|
| 140 |
'soft_errors' => [$10, 'i'], |
|---|
| 141 |
'hard_errors' => [$11, 'i'], |
|---|
| 142 |
'txport_errors' => [$12, 'i'], |
|---|
| 143 |
'total_errors' => [$13, 'i'] |
|---|
| 144 |
}; |
|---|
| 145 |
} else { |
|---|
| 146 |
die "Unable to find disk: $disk\n"; |
|---|
| 147 |
} |
|---|
| 148 |
} elsif ($osname eq 'linux') { |
|---|
| 149 |
my $output = run_command("$iostat_path $disk"); |
|---|
| 150 |
my ($line) = grep(/$disk\s*/, split(/\n/, $output)); |
|---|
| 151 |
if ($line =~ /^$disk\s+(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+).*/) { |
|---|
| 152 |
return { |
|---|
| 153 |
'xfrs_sec' => [$1, 'i'], |
|---|
| 154 |
'reads_sec' => [$2, 'i'], |
|---|
| 155 |
'writes_sec' => [$3, 'i'] |
|---|
| 156 |
}; |
|---|
| 157 |
} else { |
|---|
| 158 |
die "Unable to find disk: $disk\n"; |
|---|
| 159 |
} |
|---|
| 160 |
} elsif ($osname eq 'openbsd') { |
|---|
| 161 |
my $output = run_command("$iostat_path -D -I $disk"); |
|---|
| 162 |
if ($output =~ /\s+$disk\s+\n\s+KB xfr time\s+\n\s+(\d+)\s+(\d+)\s+(\S+).*/) { |
|---|
| 163 |
return { |
|---|
| 164 |
'kb_xfrd' => [$1, 'i'], |
|---|
| 165 |
'disk_xfrs' => [$2, 'i'], |
|---|
| 166 |
'busy_sec' => [$3, 'i'] |
|---|
| 167 |
}; |
|---|
| 168 |
} else { |
|---|
| 169 |
die "Unable to find disk: $disk\n"; |
|---|
| 170 |
} |
|---|
| 171 |
} else { |
|---|
| 172 |
die "Unsupported platform: $osname\n"; |
|---|
| 173 |
} |
|---|
| 174 |
}; |
|---|
| 175 |
|
|---|
| 176 |
1; |
|---|