Projet

Général

Profil

Révision 6dbfc425

ID6dbfc42550ac3d1906a381f83f05fee3e09a7dce
Parent 37c8fd9a
Enfant 81a80fba

Ajouté par Nikolay Beresnev il y a presque 14 ans

Added handling of parameter 190 (Airflow_Temperature), Seagate hard drives the next generation.

Voir les différences:

plugins/other/hddtemp_smartctl
1
#!/usr/local/bin/perl -w
2
# -*- perl -*-
3

  
4
=head1 NAME
5

  
6
hddtemp_smartctl - Plugin to monitor harddrive temperatures through
7
SMART
8

  
9
=head1 CONFIGURATION
10

  
11
This plugin needs to run as root or some other user that has access to
12
the harddrive devices.
13

  
14
The following environment variables are used
15

  
16
 smartctl  - path to smartctl executable
17
 drives	   - List drives to monitor. E.g. "env.drives hda hdc".
18
 type_$dev - device type for one drive, e.g. "env.type_sda 3ware,0"
19
             or more typically "env.type_sda ata" if sda is a SATA disk.
20
 args_$dev - additional arguments to smartctl for one drive,
21
             e.g. "env.args_hda -v 194,10xCelsius".  Use this to make
22
             the plugin use the --all or -a option if your disk will
23
             not return its temperature when only the -A option is
24
             used.
25
 dev_$dev  - monitoring device for one drive, e.g. twe0
26

  
27
If the "smartctl" enviroment variable is not set the plugin will
28
search your $PATH, /usr/bin, /usr/sbin, /usr/local/bin and
29
/usr/local/sbin for a file called "smartctl", and use that.
30

  
31
If the "drives" environment variable is not set, the plugin will
32
attempt to search for drives to probe.
33

  
34
=head1 MAGIC MARKERS
35

  
36
 #%# family=auto
37
 #%# capabilities=autoconf
38

  
39
=head1 AUTHOR
40

  
41
Copyright (c) 2005, Lutz Peter Christoph
42
All rights reserved.
43

  
44
=head1 LICENSE
45

  
46
Redistribution and use in source and binary forms, with or without
47
modification, are permitted provided that the following conditions
48
are met:
49

  
50
  * Redistributions of source code must retain the above copyright
51
    notice, this list of conditions and the following disclaimer.
52

  
53
  * Redistributions in binary form must reproduce the above copyright
54
    notice, this list of conditions and the following disclaimer in
55
    the documentation and/or other materials provided with the
56
    distribution.
57

  
58
  * The name and aliases of Lutz Peter Christoph ("Lupe Christoph",
59
    "Lutz Christoph") may not be used to endorse or promote products
60
    derived from this software without specific prior written
61
    permission.
62

  
63
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
64
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
65
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
66
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
67
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
68
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
69
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
70
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
71
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
73
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74

  
75
=head1 NOTES
76

  
77
Note for users of RAID controllers (smartmontools currently only
78
supports 3ware): you can specify the drives attached to your RAID
79
controller(s) as raiddev_num (e.g. sda_0). Then you must specify the
80
type like this: type_sda_0 3ware,0.
81

  
82
Recent versions of the kernel driver use a separate major device
83
number for monitoring purposes, like /dev/twe<n> or /dev/twa<n>. This
84
can be put in the e.g. dev_sda environment variable, to allow the user
85
to keep sda as the name of the disk.
86

  
87
To avoid spinning up sleeping disks smartctl will use the --nocheck
88
parameter. If this parameter isn't supported by your version of
89
smartctl then hdparm will be used.  Note that hdparm isn't available
90
on all platforms.
91

  
92
=cut
93

  
94
use strict;
95

  
96
my $DEBUG = $ENV{'MUNIN_DEBUG'} || 0;
97

  
98
my $smartctl = exists $ENV{smartctl} ? $ENV{smartctl} : '';
99

  
100
# If the envvar is not set, look for smartctl
101
if (!$smartctl) {
102
   # Still not found? Check obvious places
103
    my @dirs = split(':',$ENV{PATH});
104
    push (@dirs, qw(/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin) );
105
    
106
    until ($smartctl or @dirs == 0) {
107
	my $dir = shift @dirs;
108
	my $path = $dir.'/smartctl';
109
	$smartctl = $path if -x $path;
110
    }
111
} elsif (! -x $smartctl) {
112
    # If it is set, verify it
113
    warn "Predefined smartctl ($smartctl) is not a executable\n";
114
    undef $smartctl;
115
}
116

  
117
# Check version of smartctl to determine --nocheck capabilities
118
my $use_nocheck = 0;
119
if ($smartctl and `$smartctl --version` =~ / version (\d+\.\d+) /i) {
120
    $use_nocheck = $1 >= 5.37;
121
    warn "[DEBUG] Smartctl supports --nocheck\n" if $DEBUG;
122
}
123

  
124
# hdparm is used as a fallback
125
my $hdparm = `which hdparm 2>/dev/null`;
126
chomp $hdparm;
127

  
128
my @drives;
129

  
130
# Try to get a default set of drives
131
if ($^O eq 'linux') {
132
  # On Linux, we know how to enumerate ide drives. SCSI is not as easy
133
  if (-d '/proc/ide') {
134
    opendir(IDE, '/proc/ide');
135
    @drives = grep /hd[a-z]/, readdir IDE;
136
    closedir(IDE);
137
  }
138
  # "SCSI disks" could be both SCSI or SATA - we can't know which
139
  # without probing them.
140
} elsif ($^O eq 'freebsd') {
141
  opendir(DEV, '/dev');
142
  @drives = grep /^ada*[0-9]+$/, readdir DEV;
143
  closedir(DEV);
144
} elsif ($^O eq 'solaris') {
145
  @drives = map { s@.*/@@ ; $_ } glob '/dev/rdsk/c*t*d*s2';
146
}
147

  
148
@drives = split ' ', $ENV{drives} if exists $ENV{drives};
149

  
150
# Sort list of drives
151
@drives = sort @drives;
152

  
153
warn "[DEBUG] Drives: ",join(', ',@drives),"\n" if $DEBUG;
154

  
155
if (defined $ARGV[0]) {
156
  if ($ARGV[0] eq 'autoconf') {
157
    if ($smartctl and -x $smartctl) {
158
      if (@drives) {
159
        my $cmd = command_for_drive_device($drives[0],
160
                                           device_for_drive($drives[0]));
161
        if (`$cmd` =~ /Temperature/) {
162
          print "yes\n";
163
        } else {
164
          print "no (first drive not supported, configure the plugin)\n";
165
        }
166
        exit 0;
167
      } else {
168
        print "no (no drives known)\n";
169
        exit 0;
170
      }
171
    } else {
172
      print "no (smartctl not found)\n";
173
      exit 0;
174
    }
175
  } elsif ($ARGV[0] eq 'config') {
176
    print "graph_title HDD temperature\n";
177
    print "graph_args --base 1000 -l 0\n";
178
    print "graph_vlabel temp in ?C\n";
179
    print "graph_category sensors\n";
180
    print "graph_info This graph shows the temperature in degrees Celsius of the hard drives in the machine.\n";
181
    print "$_.label $_\n" foreach @drives;
182
    exit 0;
183
  }
184
}
185

  
186
foreach my $drive (@drives) {
187
  warn "[DEBUG] Processing $drive\n" if $DEBUG;
188
  my $fulldev = device_for_drive($drive);
189

  
190
  # Fall back to using hdparm for detecting disks in stand-by only if nocheck
191
  # isn't supported (hdparm isn't available on all platforms).
192
  if (!$use_nocheck && $hdparm && $fulldev =~ /\/dev\/[sh]d?/) {
193
    if (`$hdparm -C $fulldev 2>/dev/null` =~ /standby/) {
194
	warn "[DEBUG] Drive $fulldev is in standby mode, not checking\n"
195
	    if $DEBUG;
196
	next;
197
    }
198
  }
199

  
200
  my $cmd = command_for_drive_device($drive, $fulldev, $use_nocheck);
201
  warn "[DEBUG] Command for $drive is % $cmd %\n" if $DEBUG;
202

  
203
  my $output = `$cmd`;
204
  if ($? ne 0) {
205
      print "$drive.value U\n";
206
      print "$drive.extinfo Command $cmd on drive $drive failed: $?.  The plugin needs to have read permission on all monitored devices.\n";
207
      warn "[ERROR] Command $cmd on drive $drive failed: $?.  The plugin needs to have read permission on all monitored devices.\n";
208
      next;
209
  }
210
  if ($output =~ /Current Drive Temperature:\s*(\d+)/) {
211
    print "$drive.value $1\n";
212
  } elsif ($output =~ /^(194 Temperature_Celsius.*)/m) {
213
    my @F = split /\s+/, $1;
214
    print "$drive.value $F[9]\n";
215
  } elsif ($output =~ /^(231 Temperature_Celsius.*)/m) {
216
    my @F = split ' ', $1;
217
    print "$drive.value $F[9]\n";
218
  } else {
219
      print "$drive.value U\n";
220
      print "$drive.extinfo Temperature not detected in smartctl output\n";
221
  }
222
}
223

  
224

  
225
sub device_for_drive {
226
    my ($drive) = @_;
227

  
228
    my $dev = $drive =~ /(.*)(?:_\d+)/ ? $1 : $drive;
229

  
230
    my $fulldev = '/dev/';
231
    $fulldev .= 'rdsk/' if $^O eq 'solaris';
232
    $fulldev .= exists $ENV{'dev_'.$drive} ? $ENV{'dev_'.$drive} : $dev;
233

  
234
    return $fulldev;
235
}
236

  
237
sub command_for_drive_device {
238
    my ($drive, $fulldev, $use_nocheck) = @_;
239

  
240
    my $cmd = $smartctl.' -A ';
241
    $cmd .= '--nocheck=standby ' if $use_nocheck;
242
    $cmd .= $ENV{'args_'.$drive}.' ' if exists $ENV{'args_'.$drive};
243
    $cmd .= '-d '.$ENV{'type_'.$drive}.' ' if exists $ENV{'type_'.$drive};
244
    $cmd .= $fulldev;
245

  
246
}
247

  
1
#!/usr/local/bin/perl -w
2
# -*- perl -*-
3

  
4
=head1 NAME
5

  
6
hddtemp_smartctl - Plugin to monitor harddrive temperatures through
7
SMART
8

  
9
=head1 CONFIGURATION
10

  
11
This plugin needs to run as root or some other user that has access to
12
the harddrive devices.
13

  
14
The following environment variables are used
15

  
16
 smartctl  - path to smartctl executable
17
 drives    - List drives to monitor. E.g. "env.drives hda hdc".
18
 type_$dev - device type for one drive, e.g. "env.type_sda 3ware,0"
19
             or more typically "env.type_sda ata" if sda is a SATA disk.
20
 args_$dev - additional arguments to smartctl for one drive,
21
             e.g. "env.args_hda -v 194,10xCelsius".  Use this to make
22
             the plugin use the --all or -a option if your disk will
23
             not return its temperature when only the -A option is
24
             used.
25
 dev_$dev  - monitoring device for one drive, e.g. twe0
26

  
27
If the "smartctl" enviroment variable is not set the plugin will
28
search your $PATH, /usr/bin, /usr/sbin, /usr/local/bin and
29
/usr/local/sbin for a file called "smartctl", and use that.
30

  
31
If the "drives" environment variable is not set, the plugin will
32
attempt to search for drives to probe.
33

  
34
=head1 MAGIC MARKERS
35

  
36
 #%# family=auto
37
 #%# capabilities=autoconf
38

  
39
=head1 AUTHOR
40

  
41
Copyright (c) 2005, Lutz Peter Christoph
42
All rights reserved.
43

  
44
=head1 LICENSE
45

  
46
Redistribution and use in source and binary forms, with or without
47
modification, are permitted provided that the following conditions
48
are met:
49

  
50
  * Redistributions of source code must retain the above copyright
51
    notice, this list of conditions and the following disclaimer.
52

  
53
  * Redistributions in binary form must reproduce the above copyright
54
    notice, this list of conditions and the following disclaimer in
55
    the documentation and/or other materials provided with the
56
    distribution.
57

  
58
  * The name and aliases of Lutz Peter Christoph ("Lupe Christoph",
59
    "Lutz Christoph") may not be used to endorse or promote products
60
    derived from this software without specific prior written
61
    permission.
62

  
63
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
64
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
65
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
66
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
67
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
68
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
69
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
70
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
71
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
73
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74

  
75
=head1 NOTES
76

  
77
Note for users of RAID controllers (smartmontools currently only
78
supports 3ware): you can specify the drives attached to your RAID
79
controller(s) as raiddev_num (e.g. sda_0). Then you must specify the
80
type like this: type_sda_0 3ware,0.
81

  
82
Recent versions of the kernel driver use a separate major device
83
number for monitoring purposes, like /dev/twe<n> or /dev/twa<n>. This
84
can be put in the e.g. dev_sda environment variable, to allow the user
85
to keep sda as the name of the disk.
86

  
87
To avoid spinning up sleeping disks smartctl will use the --nocheck
88
parameter. If this parameter isn't supported by your version of
89
smartctl then hdparm will be used.  Note that hdparm isn't available
90
on all platforms.
91

  
92
=cut
93

  
94
use strict;
95

  
96
my $DEBUG = $ENV{'MUNIN_DEBUG'} || 0;
97

  
98
my $smartctl = exists $ENV{smartctl} ? $ENV{smartctl} : '';
99

  
100
# If the envvar is not set, look for smartctl
101
if (!$smartctl) {
102
   # Still not found? Check obvious places
103
    my @dirs = split(':',$ENV{PATH});
104
    push (@dirs, qw(/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin) );
105

  
106
    until ($smartctl or @dirs == 0) {
107
        my $dir = shift @dirs;
108
        my $path = $dir.'/smartctl';
109
        $smartctl = $path if -x $path;
110
    }
111
} elsif (! -x $smartctl) {
112
    # If it is set, verify it
113
    warn "Predefined smartctl ($smartctl) is not a executable\n";
114
    undef $smartctl;
115
}
116

  
117
# Check version of smartctl to determine --nocheck capabilities
118
my $use_nocheck = 0;
119
if ($smartctl and `$smartctl --version` =~ / version (\d+\.\d+) /i) {
120
    $use_nocheck = $1 >= 5.37;
121
    warn "[DEBUG] Smartctl supports --nocheck\n" if $DEBUG;
122
}
123

  
124
# hdparm is used as a fallback
125
my $hdparm = `which hdparm 2>/dev/null`;
126
chomp $hdparm;
127

  
128
my @drives;
129

  
130
# Try to get a default set of drives
131
if ($^O eq 'linux') {
132
  # On Linux, we know how to enumerate ide drives. SCSI is not as easy
133
  if (-d '/proc/ide') {
134
    opendir(IDE, '/proc/ide');
135
    @drives = grep /hd[a-z]/, readdir IDE;
136
    closedir(IDE);
137
  }
138
  # "SCSI disks" could be both SCSI or SATA - we can't know which
139
  # without probing them.
140
} elsif ($^O eq 'freebsd') {
141
  opendir(DEV, '/dev');
142
  @drives = grep /^ad[0-9]+$/, readdir DEV;
143
  closedir(DEV);
144
} elsif ($^O eq 'solaris') {
145
  @drives = map { s@.*/@@ ; $_ } glob '/dev/rdsk/c*t*d*s2';
146
}
147

  
148
@drives = split ' ', $ENV{drives} if exists $ENV{drives};
149

  
150
# Sort list of drives
151
@drives = sort @drives;
152

  
153
warn "[DEBUG] Drives: ",join(', ',@drives),"\n" if $DEBUG;
154

  
155
if (defined $ARGV[0]) {
156
  if ($ARGV[0] eq 'autoconf') {
157
    if ($smartctl and -x $smartctl) {
158
      if (@drives) {
159
        my $cmd = command_for_drive_device($drives[0],
160
                                           device_for_drive($drives[0]));
161
        if (`$cmd` =~ /Temperature/) {
162
          print "yes\n";
163
        } else {
164
          print "no (first drive not supported, configure the plugin)\n";
165
        }
166
        exit 0;
167
      } else {
168
        print "no (no drives known)\n";
169
        exit 0;
170
      }
171
    } else {
172
      print "no (smartctl not found)\n";
173
      exit 0;
174
    }
175
  } elsif ($ARGV[0] eq 'config') {
176
    print "graph_title HDD temperature\n";
177
    print "graph_args --base 1000 -l 0\n";
178
    print "graph_vlabel temp in ╟C\n";
179
    print "graph_category sensors\n";
180
    print "graph_info This graph shows the temperature in degrees Celsius of the hard drives in the machine.\n";
181
    print "$_.label $_\n" foreach @drives;
182
    exit 0;
183
  }
184
}
185

  
186
foreach my $drive (@drives) {
187
  warn "[DEBUG] Processing $drive\n" if $DEBUG;
188
  my $fulldev = device_for_drive($drive);
189

  
190
  # Fall back to using hdparm for detecting disks in stand-by only if nocheck
191
  # isn't supported (hdparm isn't available on all platforms).
192
  if (!$use_nocheck && $hdparm && $fulldev =~ /\/dev\/[sh]d?/) {
193
    if (`$hdparm -C $fulldev 2>/dev/null` =~ /standby/) {
194
        warn "[DEBUG] Drive $fulldev is in standby mode, not checking\n"
195
            if $DEBUG;
196
        next;
197
    }
198
  }
199

  
200
  my $cmd = command_for_drive_device($drive, $fulldev, $use_nocheck);
201
  warn "[DEBUG] Command for $drive is % $cmd %\n" if $DEBUG;
202

  
203
  my $output = `$cmd`;
204
  if ($? ne 0) {
205
      print "$drive.value U\n";
206
      print "$drive.extinfo Command $cmd on drive $drive failed: $?.  The plugin needs to have read permission on all monitored devices.\n";
207
      warn "[ERROR] Command $cmd on drive $drive failed: $?.  The plugin needs to have read permission on all monitored devices.\n";
208
      next;
209
  }
210
  if ($output =~ /Current Drive Temperature:\s*(\d+)/) {
211
    print "$drive.value $1\n";
212
  } elsif ($output =~ /^(194 Temperature_Celsius.*)/m) {
213
    my @F = split /\s+/, $1;
214
    print "$drive.value $F[9]\n";
215
  } elsif ($output =~ /^(231 Temperature_Celsius.*)/m) {
216
    my @F = split ' ', $1;
217
    print "$drive.value $F[9]\n";
218
  } elsif ($output =~ /^(190 Airflow_Temperature_Cel.*)/m) {
219
    my @F = split ' ', $1;
220
    print "$drive.value $F[9]\n";
221
  } else {
222
      print "$drive.value U\n";
223
      print "$drive.extinfo Temperature not detected in smartctl output\n";
224
  }
225
}
226

  
227

  
228
sub device_for_drive {
229
    my ($drive) = @_;
230

  
231
    my $dev = $drive =~ /(.*)(?:_\d+)/ ? $1 : $drive;
232

  
233
    my $fulldev = '/dev/';
234
    $fulldev .= 'rdsk/' if $^O eq 'solaris';
235
    $fulldev .= exists $ENV{'dev_'.$drive} ? $ENV{'dev_'.$drive} : $dev;
236

  
237
    return $fulldev;
238
}
239

  
240
sub command_for_drive_device {
241
    my ($drive, $fulldev, $use_nocheck) = @_;
242

  
243
    my $cmd = $smartctl.' -A ';
244
    $cmd .= '--nocheck=standby ' if $use_nocheck;
245
    $cmd .= $ENV{'args_'.$drive}.' ' if exists $ENV{'args_'.$drive};
246
    $cmd .= '-d '.$ENV{'type_'.$drive}.' ' if exists $ENV{'type_'.$drive};
247
    $cmd .= $fulldev;
248

  
249
}

Formats disponibles : Unified diff