Projet

Général

Profil

Révision 7ed16b61

ID7ed16b61e55a61c3ba98be13dcb6486c3a171088
Parent fd5126e0
Enfant 1f9d76a7

Ajouté par Diego Elio Pettenò il y a environ 13 ans

freeipmi: replace wildcard plugin with a multigraph one.

This new plugin is written in Perl rather than sh+awk, executes
ipmi-sensors only once per call (config/fetch still require two calls
total), and with one call it produces all the available graphs
depending on the available sensors.

This still allows for monitoring a remote system, and that becomes
even more interesting since it only fetches data once.

The plugin will also now fail autoconf if there is no sensor output
that can be monitored.

Voir les différences:

plugins/sensors/freeipmi
1
#!/usr/bin/perl -w
2
# -*- cperl -*-
3
=head1 NAME
4

  
5
  freeipmi - Multigraph-plugin to monitor sensors using FreeIPMI
6

  
7
=head1 CONFIGURATION
8

  
9
=head2 ENVIRONMENT VARIABLES
10

  
11
When used to monitor a foreign host, this plugins use the variables
12
IPMI_USERNAME and IPMI_PASSWORD to log in on the remote system.
13

  
14
=head2 WILDCARD PLUGIN
15

  
16
When used for the local host, the plugin should be linked as
17
non-wildcard plugin, i.e., 'freeipmi', whereas when used to monitor a
18
foreign host it should be, e.g., 'freeipmi_192.168.0.253'.
19

  
20
=head1 AUTHOR
21

  
22
Diego Elio Pettenò <flameeyes@flameeyes.eu>.
23

  
24
=head1 LICENSE
25

  
26
GPLv2
27

  
28
=head1 MAGIC MARKERS
29

  
30
 #%# family=auto
31
 #%# capabilities=autoconf
32

  
33
=cut
34

  
35
use strict;
36
use Munin::Plugin;
37

  
38
$ENV{'LANG'} = "C"; # Force parsable output from sensors.
39
$ENV{'LC_ALL'} = "C"; # Force parsable output from sensors.
40
my $IPMISENSORS = $ENV{'ipmisensors'} || 'ipmi-sensors';
41

  
42
$0 =~ /freeipmi(?:_(.+))$/;
43
my $hostname = $1;
44

  
45
$IPMISENSORS .= " --quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors --sensor-types=Temperature,Fan,Current,Voltage --output-sensor-thresholds";
46
$IPMISENSORS .= " --hostname=$hostname" if defined($hostname);
47
$IPMISENSORS .= " --username=$ENV{IPMI_USERNAME}" if defined($ENV{IPMI_USERNAME});
48
$IPMISENSORS .= " --password=$ENV{IPMI_PASSWORD}" if defined($ENV{IPMI_PASSWORD});
49

  
50
my $output=`$IPMISENSORS --output-sensor-thresholds 2>/dev/null`;
51
my $retval=$?;
52

  
53
if ( defined $ARGV[0] and $ARGV[0] eq 'autoconf' ) {
54
  if ($retval >= 1) {
55
    print "no (ipmi-sensors died)\n";
56
  } elsif ($retval == -1) {
57
    print "no (ipmi-sensors not found)\n";
58
  } elsif ($output eq "\n") {
59
    print "no (no compatible sensors)\n";
60
  } else {
61
    print "yes\n";
62
  }
63

  
64
  exit 0;
65
}
66

  
67
my %sensors = (
68
	       temp => {
69
			inputs => [],
70
			title => "Temperatures by IPMI",
71
			vlabel => "Degrees Celsius",
72
			graph_args => "--base 1000 -l 0",
73
		       },
74
	       fan => {
75
		       inputs => [],
76
		       title => "Fans speed by IPMI",
77
		       vlabel => "RPM",
78
		       graph_args => "--base 1000 -l 0",
79
		      },
80
	       power => {
81
			 inputs => [],
82
			 title => "Power by IPMI",
83
			 vlabel => "W",
84
			 graph_args => "--base 1000 -l 0",
85
			},
86
	       current => {
87
			 inputs => [],
88
			 title => "Current by IPMI",
89
			 vlabel => "A",
90
			 graph_args => "--base 1000 -l 0",
91
			},
92
	       voltage => {
93
			   inputs => [],
94
			   title => "Voltages by IPMI",
95
			   vlabel => "Volt",
96
			   graph_args => "--base 1000 --logarithmic",
97
			  },
98
	      );
99

  
100
my @data = split(/\n/, $output);
101
foreach my $line (@data) {
102
  my @dataline = split(/,/, $line);
103

  
104
  my %sensor = (
105
		graphid => "ipmi" . $dataline[0],
106
		value => $dataline[3],
107
		label => $dataline[1]
108
	       );
109
  $sensor{lwarn} = $dataline[7] if $dataline[7] ne "N/A";
110
  $sensor{hwarn} = $dataline[9] if $dataline[9] ne "N/A";
111

  
112
  $sensor{lcrit} = $dataline[6] if $dataline[6] ne "N/A";
113
  $sensor{hcrit} = $dataline[10] if $dataline[10] ne "N/A";
114

  
115
  my $type;
116
  if ( $dataline[2] eq "Temperature" ) {
117
    $type = "temp";
118
  } elsif ( $dataline[2] eq "Fan" ) {
119
    $type = "fan"
120
  } elsif ( $dataline[2] eq "Current" and $dataline[4] eq "W" ) {
121
    $type = "power";
122
  } elsif ( $dataline[2] eq "Current" and $dataline[4] eq "A" ) {
123
    $type = "current";
124
  } elsif ( $dataline[2] eq "Voltage" ) {
125
    $type = "voltage";
126
  }
127

  
128
  push(@{$sensors{$type}->{inputs}}, \%sensor);
129
}
130

  
131

  
132
if ( defined $ARGV[0] and $ARGV[0] eq 'config' ) {
133
  foreach my $type (keys %sensors) {
134
    # don't print anything if no value is found
135
    next if scalar(@{$sensors{$type}->{inputs}}) == 0;
136

  
137
    print "host_name $hostname" if defined($hostname);
138

  
139
    print <<END;
140

  
141
multigraph freeipmi_$type
142
graph_title $sensors{$type}->{title}
143
graph_vlabel $sensors{$type}->{vlabel}
144
graph_args $sensors{$type}->{graph_args}
145
graph_category sensors
146
END
147

  
148
    foreach my $sensor (@{$sensors{$type}->{inputs}}) {
149
      print "$sensor->{graphid}.label $sensor->{label}\n";
150

  
151
      print "$sensor->{graphid}.warning $sensor->{lwarn}:$sensor->{hwarn}\n"
152
	if defined($sensor->{lwarn}) or defined($sensor->{hwarn});
153
      print "$sensor->{graphid}.critical $sensor->{lcrit}:$sensor->{hcrit}\n"
154
	if defined($sensor->{lcrit}) or defined($sensor->{hcrit});
155
    }
156
  }
157

  
158
  exit 0;
159
}
160

  
161
foreach my $type (keys %sensors) {
162
  # don't print anything if no value is found
163
  next if scalar(@{$sensors{$type}->{inputs}}) == 0;
164

  
165
  print "multigraph sensors_$type\n";
166

  
167
  foreach my $sensor (@{$sensors{$type}->{inputs}}) {
168
    print "$sensor->{graphid}.value $sensor->{value}\n";
169
  }
170
}
plugins/sensors/freeipmi_
1
#!/bin/sh
2
# -*- sh -*-
3

  
4
: << =cut
5

  
6
=head1 NAME
7

  
8
freeipmi_ - Plugin to monitor temperature or fan speed using FreeIPMI
9

  
10
=head1 CONFIGURATION
11

  
12
=head2 ENVIRONMENT VARIABLES
13

  
14
When used to monitor a foreign host, this plugins use the variables
15
IPMI_USERNAME and IPMI_PASSWORD to log in on the remote system.
16

  
17
=head2 WILDCARD PLUGIN
18

  
19
You can monitor either the current system (via /dev/ipmi0 and the
20
like) or a remote system (via the LAN protocols), and for each of the
21
two options you can select your sensors:
22

  
23
 - fans;
24
 - temp;
25
 - power;
26
 - current;
27
 - voltage.
28

  
29
When used for the local host, the plugin should be linked as, e.g.,
30
'ipmi_temp', whereas when used to monitor a foreign host it should be,
31
e.g., 'ipmi_192.168.0.253_temp'.
32

  
33
=head1 NOTE
34

  
35
=head1 AUTHOR
36

  
37
Rewritten by Diego Elio Pettenò <flameeyes@flameeyes.eu>.
38
Based on the work of Nicolai Langfeldt <janl@linpro.no>, Logilab and
39
Peter Palfrader.
40

  
41
=head1 LICENSE
42

  
43
GPLv2
44

  
45
=head1 MAGIC MARKERS
46

  
47
 #%# family=auto
48
 #%# capabilities=autoconf suggest
49

  
50
=cut
51

  
52
#### Parse commandline to determine what the job is
53

  
54
_ipmisensors() {
55
    params="--quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors"
56
    if [ "x${hostname}" != "x" ]; then
57
	params="${params} --hostname=${hostname}"
58
	[ "x${IPMI_USERNAME}" != "x" ] && params="${params} --username=${IPMI_USERNAME}"
59
	[ "x${IPMI_PASSWORD}" != "x" ] && params="${params} --password=${IPMI_PASSWORD}"
60
    fi
61

  
62
    if ! ipmi-sensors ${params} --output-sensor-thresholds "$@"; then
63
	ipmi-sensors ${params} "$@"
64
    fi
65
}
66

  
67
# extract and eventual hostname out of the called name; we
68
# have to check whether it's set to "u" as that's what happens
69
# when the compatibility with ipmi_sensor_ is used.
70
hostname1=${0#*_}
71
hostname=${hostname1%%_*}
72
if [ "x${hostname}" = "xu" -o "x${hostname}" = "x${hostname1}" ]; then
73
    hostname=""
74
fi
75

  
76
case $0 in
77
    *_temp|*_u_degrees_c)
78
	title="Temperatures"
79
	vlabel="degrees Celsius"
80
	type=Temperature
81
	unit=C
82
	;;
83
    *_fans|*_u_rpm)
84
	title="Fan speeds"
85
	vlabel="Rotations per Minute (RPM)"
86
	type=Fan
87
	unit=RPM
88
	;;
89
    *_power|*_u_watts)
90
	title="Power consumption"
91
	vlabel="Watts"
92
	type=Current
93
	unit=W
94
	;;
95
    *_current|*_u_amps)
96
	title="Current drain"
97
	vlabel="Amperes"
98
	type=Current
99
	unit=A
100
	;;
101
    *_voltage|*_u_volts)
102
	title="Voltages"
103
	vlabel="Volts"
104
	type=Voltage
105
	unit=V
106
	;;
107
    *)
108
	if [ x"$1" != x"autoconf" -a x"$1" != x"suggest" ]; then
109
	    echo "Please invoke as one of the supported sensors types:" >&2
110
	    echo freeipmi_{temp,fans,power,current} >&2
111
	    exit 1
112
	fi
113
esac
114

  
115
case $1 in
116
    autoconf)
117
	if ! command -v ipmi-sensors >/dev/null 2>&1 ; then
118
	    echo 'no (missing ipmi-sensors command)'
119
	    exit 0
120
	fi
121

  
122
	if ! _ipmisensors -t OS_Boot >/dev/null 2>&1 ; then
123
	    echo 'no (unable to access IPMI device)'
124
	    exit 0
125
	fi
126

  
127
	echo yes
128
	exit 0
129
	;;
130
    suggest)
131
	_ipmisensors | awk -F, '
132
$3 == "Temperature" { print "temp"; }
133
$3 == "Fan" { print "fans"; }
134
$3 == "Current" && $5 == "W" { print "power"; }
135
$3 == "Current" && $5 == "A" { print "current"; }
136
$3 == "Voltage" { print "voltage"; }
137
'
138
	exit 0;;
139
    config)
140
	cat - <<EOF
141
graph_title ${title} based on IPMI sensors
142
graph_vlabel ${vlabel}
143
graph_category Sensors
144
EOF
145

  
146
	if [ "x${hostname}" != "x" ]; then
147
	    echo "host_name ${hostname}"
148
	fi
149
	;;
150
esac
151

  
152
_ipmisensors -t ${type} | awk -F, -v CONFIG=$1 -v UNIT=$unit '
153
$5 == UNIT {
154
    if ( CONFIG != "config" ) {
155
      printf("ipmi%s.value %s\n", $1, $4);
156
    } else {
157
      printf("ipmi%s.label %s\n", $1, $2);
158

  
159
      # This can only happen if FreeIPMI is new enough
160
      if ( NF == 12 ) {
161
        if ( $8 != "N/A" && $10 != "N/A" )
162
          printf("ipmi%s.warning %s:%s\n", $1, $8, $10);
163
        else if ( $8 == "N/A" && $10 != "N/A" )
164
          printf("ipmi%s.warning :%s\n", $1, $10);
165
        else if ( $8 != "N/A" && $10 == "N/A" )
166
          printf("ipmi%s.warning %s:\n", $1, $8);
167

  
168
        if ( $7 != "N/A" && $11 != "N/A" )
169
          printf("ipmi%s.critical %s:%s\n", $1, $7, $11);
170
        else if ( $7 == "N/A" && $11 != "N/A" )
171
          printf("ipmi%s.critical :%s\n", $1, $11);
172
        else if ( $7 != "N/A" && $11 == "N/A" )
173
          printf("ipmi%s.critical %s:\n", $1, $7);
174
      }
175
  }
176
}
177
'
178

  
179
# vim: syntax=sh ts=4 et

Formats disponibles : Unified diff