diff --git a/zabbix_scripts/util_generate_sensors_ini b/zabbix_scripts/util_generate_sensors_ini index 9f3a5d9..f65e08b 100755 --- a/zabbix_scripts/util_generate_sensors_ini +++ b/zabbix_scripts/util_generate_sensors_ini @@ -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; +}