|
|
|
@ -14,34 +14,38 @@ my $output = undef; |
|
|
|
|
# When a threshold can be automatically detected, |
|
|
|
|
# you may want to be notified before it's reached, so you can |
|
|
|
|
# set a margin which will be substracted from the real threshold |
|
|
|
|
my $temp_margin = '20'; |
|
|
|
|
my $temp_margin = '20'; |
|
|
|
|
my $temp_hd_margin = '10'; |
|
|
|
|
my $pwr_margin = '200'; |
|
|
|
|
my $pwr_margin = '200'; |
|
|
|
|
my $pwr_rel_margin = '20'; |
|
|
|
|
# This value will be substracted from the higher threshold to define the low one |
|
|
|
|
# so you can have hysteresis to prevent flip-flop |
|
|
|
|
my $temp_hyst = '10'; |
|
|
|
|
my $temp_hd_hyst = '5'; |
|
|
|
|
my $temp_hyst = '10'; |
|
|
|
|
my $temp_hd_hyst = '5'; |
|
|
|
|
my $temp_ups_hyst = '5'; |
|
|
|
|
my $pwr_hyst = '200'; |
|
|
|
|
my $pwr_hyst = '200'; |
|
|
|
|
my $pwr_rel_hyst = '10'; |
|
|
|
|
|
|
|
|
|
# Default threshold if not detected |
|
|
|
|
my $def_temp_thres_high = '50'; |
|
|
|
|
my $def_hd_thres_high = '50'; |
|
|
|
|
my $def_ups_thres_high = '40'; |
|
|
|
|
my $def_fan_thres_high = '1000'; |
|
|
|
|
my $def_fan_thres_low = '700'; |
|
|
|
|
my $def_pwr_thres_high = '1000'; |
|
|
|
|
|
|
|
|
|
my $def_temp_thres_high = '50'; |
|
|
|
|
my $def_hd_temp_thres_high = '50'; |
|
|
|
|
my $def_ups_temp_thres_high = '40'; |
|
|
|
|
my $def_fan_thres_high = '1000'; |
|
|
|
|
my $def_fan_thres_low = '700'; |
|
|
|
|
my $def_pwr_thres_high = '1000'; |
|
|
|
|
my $def_pwr_rel_thres_high = '80'; |
|
|
|
|
|
|
|
|
|
GetOptions( |
|
|
|
|
"output=s" => \$output, |
|
|
|
|
"temp-margin=i" => \$temp_margin, |
|
|
|
|
"temp-hd-margin=i" => \$temp_hd_margin, |
|
|
|
|
"pwr-margin=i" => \$pwr_margin, |
|
|
|
|
"pwr-rel-margin=i" => \$pwr_rel_margin, |
|
|
|
|
"temp-hyst=i" => \$temp_hyst, |
|
|
|
|
"temp-hd-hyst=i" => \$temp_hd_hyst, |
|
|
|
|
"temp-ups-hyst=i" => \$temp_ups_hyst, |
|
|
|
|
"pwr-hyst=i" => \$pwr_hyst |
|
|
|
|
"pwr-hyst=i" => \$pwr_hyst, |
|
|
|
|
"pwr-rel-hys=i" => \$pwr_rel_hyst |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
sub usage(){ |
|
|
|
@ -84,10 +88,12 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
print "Couldn't get detail for sensor $name\n"; |
|
|
|
|
next SENSOR; |
|
|
|
|
} |
|
|
|
|
my $val = undef; |
|
|
|
|
foreach my $d (@details){ |
|
|
|
|
chomp $d; |
|
|
|
|
if ($d =~ m/^\s*Sensor\sReading\s*:\s*(\w+)/){ |
|
|
|
|
my $val = $1; |
|
|
|
|
$val = $1; |
|
|
|
|
print "Sensor $name has value: $val\n"; |
|
|
|
|
if ($val !~ m/^\d+$/){ |
|
|
|
|
print "Skipping sensor $name, couldn't parse its value: $val\n"; |
|
|
|
|
next SENSOR; |
|
|
|
@ -100,6 +106,7 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
$sensor->{threshold_low} = $1-$temp_margin; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
next SENSOR unless $val; |
|
|
|
|
$sensor->{threshold_high} ||= $def_temp_thres_high; |
|
|
|
|
$sensor->{threshold_low} ||= $def_temp_thres_high-$temp_hyst; |
|
|
|
|
$sensor->{threshold_high} =~ s/\.0+$//; |
|
|
|
@ -108,8 +115,7 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
$sensor->{type} = 'temp'; |
|
|
|
|
$sensor->{unit} = '°C'; |
|
|
|
|
$sensor->{cmd} = "$ipmitool sdr get '$name' | grep 'Sensor Reading' | awk '{print \$4}'"; |
|
|
|
|
my $id = lc $name; |
|
|
|
|
$id =~ s/\s/_/g; |
|
|
|
|
my $id = sensor_name($name); |
|
|
|
|
$sensors->{$id} = $sensor; |
|
|
|
|
print "Found a temperature sensor using IPMI: $name\n"; |
|
|
|
|
} |
|
|
|
@ -121,9 +127,11 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
if ($? == 0){ |
|
|
|
|
SENSOR: foreach my $l (@lines){ |
|
|
|
|
chomp $l; |
|
|
|
|
$l =~ m/^(\w+[\s\w]+?\w+)\s*\|.*\|\s*([\w\.\s]+)\s*\|.*\|\s*([\-\w\.\s]+)$/; |
|
|
|
|
if ($l !~ m/^(\w+[\s\w]+?\w+)\s*\|.*\|\s*([\w\.\s]+)\s*\|.*\|\s*([\-\w\.\s]+)$/){ |
|
|
|
|
next SENSOR; |
|
|
|
|
} |
|
|
|
|
my $name = $1; |
|
|
|
|
my $value = my $val = $3; |
|
|
|
|
my $value = $3; |
|
|
|
|
my $sensor = {}; |
|
|
|
|
|
|
|
|
|
my @details = qx($ipmitool sdr get '$name'); |
|
|
|
@ -131,6 +139,7 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
print "Couldn't get detail for sensor $name\n"; |
|
|
|
|
next SENSOR; |
|
|
|
|
} |
|
|
|
|
my $val = undef; |
|
|
|
|
foreach my $d (@details){ |
|
|
|
|
chomp $d; |
|
|
|
|
if ($d =~ m/^\s*Sensor\sReading\s*:\s*(\w+)/){ |
|
|
|
@ -147,6 +156,7 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
$sensor->{threshold_high} = $1-$temp_margin; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
next SENSOR unless $val; |
|
|
|
|
$sensor->{threshold_high} ||= $def_fan_thres_high; |
|
|
|
|
$sensor->{threshold_low} ||= $def_fan_thres_high-$temp_hyst; |
|
|
|
|
$sensor->{threshold_high} =~ s/\.0+$//; |
|
|
|
@ -155,8 +165,7 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
$sensor->{type} = 'fan'; |
|
|
|
|
$sensor->{unit} = ($value =~ m/percent|%/ || $val < 100) ? '%' : 'rpm'; |
|
|
|
|
$sensor->{cmd} = "$ipmitool sdr get '$name' | grep 'Sensor Reading' | awk '{print \$4}'"; |
|
|
|
|
my $id = lc $name; |
|
|
|
|
$id =~ s/\s/_/g; |
|
|
|
|
my $id = sensor_name($name); |
|
|
|
|
$sensors->{$id} = $sensor; |
|
|
|
|
print "Found a fan sensor using IPMI: $name\n"; |
|
|
|
|
} |
|
|
|
@ -166,16 +175,21 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
if ($? == 0){ |
|
|
|
|
SENSOR: foreach my $l (@lines){ |
|
|
|
|
chomp $l; |
|
|
|
|
$l =~ m/^(\w+[\s\w]+?\w+)\s*\|.*\|\s*([\w\.\s]+)\s*\|.*\|\s*([\-\w\.\s]+)$/; |
|
|
|
|
my $name = $1; |
|
|
|
|
my $val = $3; |
|
|
|
|
if ($l !~ m/^(\w+[\s\w]+?\w+(\s%)?)\s*\|.*\|\s*([\w\.\s]+)\s*\|.*\|\s*([\-\w\.\s]+)$/){ |
|
|
|
|
print "Skiping line $l\n"; |
|
|
|
|
next SENSOR; |
|
|
|
|
} |
|
|
|
|
my $name = $1; |
|
|
|
|
my $value = $4; |
|
|
|
|
my $sensor = {}; |
|
|
|
|
if ($name =~ m/Power|Pwr|Consumption/i || $val =~ m/W(att)?/i){ |
|
|
|
|
if ($name =~ m/(Power)|(Pwr)|(Consumption)|(PS\d+\sCurr\sOut)/i || $value =~ m/W(att)?/i){ |
|
|
|
|
my @details = qx($ipmitool sdr get '$name'); |
|
|
|
|
if ($? != 0){ |
|
|
|
|
print "Couldn't get detail for sensor $name\n"; |
|
|
|
|
next SENSOR; |
|
|
|
|
} |
|
|
|
|
my $val = undef; |
|
|
|
|
my $unit = ($name =~ m/%/) ? '%' : 'Watt'; |
|
|
|
|
foreach my $d (@details){ |
|
|
|
|
chomp $d; |
|
|
|
|
if ($d =~ m/^\s*Sensor\sReading\s*:\s*(\w+)/){ |
|
|
|
@ -186,22 +200,22 @@ if ($ipmitool && -x $ipmitool){ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
elsif ($d =~ m/^\s*Upper\scritical\s*:\s*(\d+(\.\d+)?)/){ |
|
|
|
|
$sensor->{threshold_high} = $1-$pwr_margin; |
|
|
|
|
$sensor->{threshold_high} = ($unit eq '%') ? $1-$pwr_rel_margin : $1-$pwr_margin; |
|
|
|
|
} |
|
|
|
|
elsif ($d =~ m/^\s*Upper\snon\-critical\s*:\s*(\d+(\.\d+)?)/){ |
|
|
|
|
$sensor->{threshold_low} = $1-$pwr_margin; |
|
|
|
|
$sensor->{threshold_low} = ($unit eq '%') ? $1-$pwr_rel_margin : $1-$pwr_margin; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
$sensor->{threshold_high} ||= $def_pwr_thres_high; |
|
|
|
|
$sensor->{threshold_low} ||= $def_pwr_thres_high-$pwr_hyst; |
|
|
|
|
next SENSOR unless $val; |
|
|
|
|
$sensor->{threshold_high} ||= ($unit eq '%') ? $def_pwr_rel_thres_high : $def_pwr_thres_high; |
|
|
|
|
$sensor->{threshold_low} ||= ($unit eq '%') ? $def_pwr_rel_thres_high-$pwr_rel_hyst : $def_pwr_thres_high-$pwr_hyst; |
|
|
|
|
$sensor->{threshold_high} =~ s/\.0+$//; |
|
|
|
|
$sensor->{threshold_low} =~ s/\.0+$//; |
|
|
|
|
$sensor->{description} = $name; |
|
|
|
|
$sensor->{type} = 'power'; |
|
|
|
|
$sensor->{unit} = 'Watt'; |
|
|
|
|
$sensor->{unit} = ($name =~ m/%/) ? '%' : 'Watt'; |
|
|
|
|
$sensor->{cmd} = "$ipmitool sdr get '$name' | grep 'Sensor Reading' | awk '{print \$4}'"; |
|
|
|
|
my $id = lc $name; |
|
|
|
|
$id =~ s/\s/_/g; |
|
|
|
|
my $id = sensor_name($name); |
|
|
|
|
$sensors->{$id} = $sensor; |
|
|
|
|
print "Found a power sensor using IPMI: $name\n"; |
|
|
|
|
} |
|
|
|
@ -218,8 +232,8 @@ if ($smartctl && -x $smartctl){ |
|
|
|
|
if ($l =~ /Temperature_Celsius/){ |
|
|
|
|
$sensors->{$block} = { |
|
|
|
|
description => "$block temperature", |
|
|
|
|
threshold_low => $def_hd_thres_high-$temp_hd_hyst, |
|
|
|
|
threshold_high => $def_hd_thres_high, |
|
|
|
|
threshold_low => $def_hd_temp_thres_high-$temp_hd_hyst, |
|
|
|
|
threshold_high => $def_hd_temp_thres_high, |
|
|
|
|
type => 'temp', |
|
|
|
|
unit => '°C', |
|
|
|
|
cmd => "$smartctl -A /dev/$block | grep Temperature_Celsius | awk '{print \$10}'" |
|
|
|
@ -260,17 +274,27 @@ if ($upsc && -x $upsc){ |
|
|
|
|
next if ($? != 0); |
|
|
|
|
foreach my $l (@lines){ |
|
|
|
|
if ($l =~ m/^ups\.temperature:\s+(\d+(\.\d+)?)/){ |
|
|
|
|
$sensors->{'ups_' . lc $ups} = { |
|
|
|
|
$sensors->{'ups_' . lc $ups . '_temp'} = { |
|
|
|
|
description => "ups temperature for $ups", |
|
|
|
|
type => 'temp', |
|
|
|
|
threshold_high => $def_ups_thres_high, |
|
|
|
|
threshold_low => $def_ups_thres_high-$temp_ups_hyst, |
|
|
|
|
threshold_high => $def_ups_temp_thres_high, |
|
|
|
|
threshold_low => $def_ups_temp_thres_high-$temp_ups_hyst, |
|
|
|
|
unit => '°C', |
|
|
|
|
cmd => "$upsc $ups ups.temperature" |
|
|
|
|
}; |
|
|
|
|
print "Found a temperature sensor for ups $ups\n"; |
|
|
|
|
last; |
|
|
|
|
} |
|
|
|
|
elsif ($l =~ m/^ups\.load:\s+(\d+(\.\d+)?)/){ |
|
|
|
|
$sensors->{'ups_' . lc $ups . '_load'} = { |
|
|
|
|
description => "ups load for $ups", |
|
|
|
|
type => 'power', |
|
|
|
|
threshold_high => $def_pwr_rel_thres_high, |
|
|
|
|
threshold_low => $def_pwr_rel_thres_high-$pwr_rel_hyst, |
|
|
|
|
unit => '%', |
|
|
|
|
cmd => "$upsc $ups ups.load" |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -281,3 +305,13 @@ foreach my $s (sort keys %$sensors){ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$cfg->write($output); |
|
|
|
|
|
|
|
|
|
# Take a sensor description and return a suitable string as sensor ID |
|
|
|
|
sub sensor_name{ |
|
|
|
|
my $desc = shift; |
|
|
|
|
my $id = lc $desc; |
|
|
|
|
$id =~ s/\s/_/g; |
|
|
|
|
$id =~ s/%/percent/g; |
|
|
|
|
$id =~ s/_rpm$//; |
|
|
|
|
return $id; |
|
|
|
|
} |
|
|
|
|