Cap storage/memory usage sensors at 100% to handle device firmware bugs
Fixes an issue where storage usage was reporting values over 200,000% due to incorrect SNMP values from the device. This can occur when: - Device firmware has bugs in hrStorageUsed/hrStorageSize reporting - SNMP allocation units differ between OIDs - Values are read during device reconfiguration Changes: - PollerWorker: Cap percentage sensors at 100%, log warning with raw values - Mikrotik profile: Cap storage usage at 100% during discovery - NetSnmp profile: Cap memory usage at 100% during discovery The raw percentage is logged before capping to help diagnose device issues. All percentage sensors now have consistent validation across polling and discovery.
This commit is contained in:
parent
79dabd840b
commit
de002f9903
3 changed files with 50 additions and 4 deletions
|
|
@ -278,7 +278,25 @@ defmodule Towerops.Snmp.PollerWorker do
|
|||
size when is_number(size) <- decode_snmp_value(size_raw),
|
||||
true <- size > 0 do
|
||||
percentage = used / size * 100
|
||||
{:ok, percentage}
|
||||
|
||||
# Validate percentage and warn if it exceeds 100%
|
||||
# This can happen if the device reports incorrect SNMP values or if
|
||||
# hrStorageAllocationUnits differs between used/size OIDs
|
||||
capped_percentage =
|
||||
if percentage > 100 do
|
||||
Logger.warning(
|
||||
"Percentage sensor #{sensor.sensor_descr} (#{sensor.sensor_type}) " <>
|
||||
"exceeded 100%: #{Float.round(percentage, 2)}% " <>
|
||||
"(used=#{used} from #{used_oid}, size=#{size} from #{size_oid}). " <>
|
||||
"Capping at 100%. This may indicate a device firmware bug."
|
||||
)
|
||||
|
||||
100.0
|
||||
else
|
||||
percentage
|
||||
end
|
||||
|
||||
{:ok, capped_percentage}
|
||||
else
|
||||
{:error, reason} -> {:error, reason}
|
||||
false -> {:error, :division_by_zero}
|
||||
|
|
|
|||
|
|
@ -282,6 +282,21 @@ defmodule Towerops.Snmp.Profiles.Mikrotik do
|
|||
percent = used / size * 100
|
||||
type = determine_storage_type(descr)
|
||||
|
||||
# Cap percentage at 100% and log warning if exceeded
|
||||
# This can happen if the device reports incorrect SNMP values
|
||||
capped_percent =
|
||||
if percent > 100 do
|
||||
Logger.warning(
|
||||
"Storage sensor #{descr} exceeded 100%: #{Float.round(percent, 2)}% " <>
|
||||
"(used=#{used} from #{used_oid}, size=#{size} from #{size_oid}). " <>
|
||||
"Capping at 100%. This may indicate a device firmware bug."
|
||||
)
|
||||
|
||||
100.0
|
||||
else
|
||||
percent
|
||||
end
|
||||
|
||||
%{
|
||||
sensor_type: "#{type}_usage",
|
||||
sensor_index: index,
|
||||
|
|
@ -289,8 +304,8 @@ defmodule Towerops.Snmp.Profiles.Mikrotik do
|
|||
sensor_descr: descr,
|
||||
sensor_unit: "%",
|
||||
sensor_divisor: 1,
|
||||
last_value: percent,
|
||||
status: storage_status(type, percent),
|
||||
last_value: capped_percent,
|
||||
status: storage_status(type, capped_percent),
|
||||
metadata: %{
|
||||
size_oid: size_oid,
|
||||
calculation: "percentage"
|
||||
|
|
|
|||
|
|
@ -208,7 +208,20 @@ defmodule Towerops.Snmp.Profiles.NetSnmp do
|
|||
|
||||
used_percent =
|
||||
if total_kb && total_kb > 0 && used_kb do
|
||||
used_kb / total_kb * 100
|
||||
percent = used_kb / total_kb * 100
|
||||
|
||||
# Cap percentage at 100% and log warning if exceeded
|
||||
if percent > 100 do
|
||||
Logger.warning(
|
||||
"Memory usage exceeded 100%: #{Float.round(percent, 2)}% " <>
|
||||
"(used=#{used_kb} KB, total=#{total_kb} KB). " <>
|
||||
"Capping at 100%. This may indicate a device firmware bug."
|
||||
)
|
||||
|
||||
100.0
|
||||
else
|
||||
percent
|
||||
end
|
||||
end
|
||||
|
||||
[
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue