SNMP discovery updates continued
This commit is contained in:
@@ -58,6 +58,10 @@ ENT_PHY_SENSOR_SCALE = (1, 3, 6, 1, 2, 1, 99, 1, 1, 1, 2)
|
||||
ENT_PHY_SENSOR_PRECISION = (1, 3, 6, 1, 2, 1, 99, 1, 1, 1, 3)
|
||||
ENT_PHY_SENSOR_VALUE = (1, 3, 6, 1, 2, 1, 99, 1, 1, 1, 4)
|
||||
ENT_PHY_SENSOR_OPER_STATUS = (1, 3, 6, 1, 2, 1, 99, 1, 1, 1, 5)
|
||||
UCD_LA_LOAD_INT = (1, 3, 6, 1, 4, 1, 2021, 10, 1, 5)
|
||||
UCD_MEM_TOTAL_REAL = (1, 3, 6, 1, 4, 1, 2021, 4, 5, 0)
|
||||
UCD_MEM_AVAIL_REAL = (1, 3, 6, 1, 4, 1, 2021, 4, 6, 0)
|
||||
UCD_DSK_PERCENT = (1, 3, 6, 1, 4, 1, 2021, 9, 1, 9)
|
||||
|
||||
STATUS_LABELS = {
|
||||
1: "up",
|
||||
@@ -128,6 +132,61 @@ def _run_snmp_check_sync(config: SnmpCheckConfig) -> SnmpCheckResult:
|
||||
metrics=[SnmpMetricValue(name="load_percent", value=float(value), unit="%")],
|
||||
)
|
||||
|
||||
if config.item_type == "linux_load_average":
|
||||
load_index = _item_index(config.item_id, "linux", position=2)
|
||||
if load_index is None:
|
||||
return SnmpCheckResult(status="down", response_time_ms=0, message="SNMP Linux load item was not valid")
|
||||
oid = _with_index(UCD_LA_LOAD_INT, load_index)
|
||||
value = _int_value(client.get_many([oid]).get(oid))
|
||||
response_time_ms = int((perf_counter() - started) * 1000)
|
||||
if value is None:
|
||||
return SnmpCheckResult(status="down", response_time_ms=response_time_ms, message="Linux load average was not reported")
|
||||
load_average = value / 100
|
||||
label = config.label or "Load average"
|
||||
return SnmpCheckResult(
|
||||
status="up",
|
||||
response_time_ms=response_time_ms,
|
||||
message=f"{label} is {load_average:.2f}",
|
||||
metrics=[SnmpMetricValue(name="load_average", value=load_average)],
|
||||
)
|
||||
|
||||
if config.item_type == "linux_memory_usage":
|
||||
values = client.get_many([UCD_MEM_TOTAL_REAL, UCD_MEM_AVAIL_REAL])
|
||||
response_time_ms = int((perf_counter() - started) * 1000)
|
||||
total_kb = _int_value(values.get(UCD_MEM_TOTAL_REAL))
|
||||
available_kb = _int_value(values.get(UCD_MEM_AVAIL_REAL))
|
||||
if not total_kb or available_kb is None:
|
||||
return SnmpCheckResult(status="down", response_time_ms=response_time_ms, message="Linux memory was not reported")
|
||||
used_kb = total_kb - available_kb
|
||||
used_percent = (used_kb / total_kb) * 100
|
||||
return SnmpCheckResult(
|
||||
status="up",
|
||||
response_time_ms=response_time_ms,
|
||||
message=f"Memory is {used_percent:.1f}% used",
|
||||
metrics=[
|
||||
SnmpMetricValue(name="used_percent", value=used_percent, unit="%"),
|
||||
SnmpMetricValue(name="used_bytes", value=float(used_kb * 1024), unit="bytes"),
|
||||
SnmpMetricValue(name="total_bytes", value=float(total_kb * 1024), unit="bytes"),
|
||||
],
|
||||
)
|
||||
|
||||
if config.item_type == "linux_disk_usage":
|
||||
disk_index = _item_index(config.item_id, "linux", position=2)
|
||||
if disk_index is None:
|
||||
return SnmpCheckResult(status="down", response_time_ms=0, message="SNMP Linux disk item was not valid")
|
||||
oid = _with_index(UCD_DSK_PERCENT, disk_index)
|
||||
used_percent = _int_value(client.get_many([oid]).get(oid))
|
||||
response_time_ms = int((perf_counter() - started) * 1000)
|
||||
if used_percent is None:
|
||||
return SnmpCheckResult(status="down", response_time_ms=response_time_ms, message="Linux disk usage was not reported")
|
||||
label = config.label or "Disk"
|
||||
return SnmpCheckResult(
|
||||
status="up",
|
||||
response_time_ms=response_time_ms,
|
||||
message=f"{label} is {used_percent}% used",
|
||||
metrics=[SnmpMetricValue(name="used_percent", value=float(used_percent), unit="%")],
|
||||
)
|
||||
|
||||
if config.item_type in {"memory_usage", "storage_usage"}:
|
||||
storage_index = _item_index(config.item_id, "storage")
|
||||
if storage_index is None:
|
||||
@@ -276,12 +335,12 @@ def _interface_index(item_id: str) -> int | None:
|
||||
return _item_index(item_id, "interface")
|
||||
|
||||
|
||||
def _item_index(item_id: str, expected_prefix: str) -> int | None:
|
||||
def _item_index(item_id: str, expected_prefix: str, position: int = 1) -> int | None:
|
||||
parts = item_id.split(".")
|
||||
if len(parts) < 3 or parts[0] != expected_prefix:
|
||||
if len(parts) <= position or parts[0] != expected_prefix:
|
||||
return None
|
||||
try:
|
||||
return int(parts[1])
|
||||
return int(parts[position])
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ from app.collectors.snmp import (
|
||||
HR_STORAGE_SIZE,
|
||||
HR_STORAGE_USED,
|
||||
SYS_UPTIME,
|
||||
UCD_DSK_PERCENT,
|
||||
UCD_LA_LOAD_INT,
|
||||
UCD_MEM_AVAIL_REAL,
|
||||
UCD_MEM_TOTAL_REAL,
|
||||
SnmpCheckConfig,
|
||||
_with_index,
|
||||
run_snmp_check,
|
||||
@@ -66,6 +70,72 @@ class SnmpCollectorTestCase(unittest.IsolatedAsyncioTestCase):
|
||||
("load_percent", 42.0, "%")
|
||||
]
|
||||
|
||||
async def test_collects_linux_load_average(self) -> None:
|
||||
oid = _with_index(UCD_LA_LOAD_INT, 1)
|
||||
with patch("app.collectors.snmp.SnmpV2Client") as client_class:
|
||||
client_class.return_value.get_many.return_value = {oid: 123}
|
||||
|
||||
result = await run_snmp_check(
|
||||
SnmpCheckConfig(
|
||||
host="192.0.2.10",
|
||||
community="private-community",
|
||||
item_id="linux.load.1",
|
||||
item_type="linux_load_average",
|
||||
label="Load average 1 minute",
|
||||
)
|
||||
)
|
||||
|
||||
assert result.status == "up"
|
||||
assert result.message == "Load average 1 minute is 1.23"
|
||||
assert [(metric.name, metric.value, metric.unit) for metric in result.metrics] == [
|
||||
("load_average", 1.23, None)
|
||||
]
|
||||
|
||||
async def test_collects_linux_memory_usage(self) -> None:
|
||||
with patch("app.collectors.snmp.SnmpV2Client") as client_class:
|
||||
client_class.return_value.get_many.return_value = {
|
||||
UCD_MEM_TOTAL_REAL: 1000,
|
||||
UCD_MEM_AVAIL_REAL: 250,
|
||||
}
|
||||
|
||||
result = await run_snmp_check(
|
||||
SnmpCheckConfig(
|
||||
host="192.0.2.10",
|
||||
community="private-community",
|
||||
item_id="linux.memory.real",
|
||||
item_type="linux_memory_usage",
|
||||
)
|
||||
)
|
||||
|
||||
assert result.status == "up"
|
||||
assert result.message == "Memory is 75.0% used"
|
||||
assert [(metric.name, metric.value, metric.unit) for metric in result.metrics] == [
|
||||
("used_percent", 75.0, "%"),
|
||||
("used_bytes", 768000.0, "bytes"),
|
||||
("total_bytes", 1024000.0, "bytes"),
|
||||
]
|
||||
|
||||
async def test_collects_linux_disk_usage(self) -> None:
|
||||
oid = _with_index(UCD_DSK_PERCENT, 31)
|
||||
with patch("app.collectors.snmp.SnmpV2Client") as client_class:
|
||||
client_class.return_value.get_many.return_value = {oid: 81}
|
||||
|
||||
result = await run_snmp_check(
|
||||
SnmpCheckConfig(
|
||||
host="192.0.2.10",
|
||||
community="private-community",
|
||||
item_id="linux.disk.31",
|
||||
item_type="linux_disk_usage",
|
||||
label="Disk / usage",
|
||||
)
|
||||
)
|
||||
|
||||
assert result.status == "up"
|
||||
assert result.message == "Disk / usage is 81% used"
|
||||
assert [(metric.name, metric.value, metric.unit) for metric in result.metrics] == [
|
||||
("used_percent", 81.0, "%")
|
||||
]
|
||||
|
||||
async def test_collects_storage_usage(self) -> None:
|
||||
oids = [
|
||||
_with_index(HR_STORAGE_ALLOCATION_UNITS, 31),
|
||||
|
||||
Reference in New Issue
Block a user