From 7650da955c4d47bfbbc36855375239b060833186 Mon Sep 17 00:00:00 2001 From: anima Date: Mon, 10 Feb 2025 00:09:30 +0100 Subject: [PATCH] add disk health check --- checks/check_snmp_synology.py | 116 ++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 20 deletions(-) diff --git a/checks/check_snmp_synology.py b/checks/check_snmp_synology.py index ad833e2..5c73313 100755 --- a/checks/check_snmp_synology.py +++ b/checks/check_snmp_synology.py @@ -8,7 +8,7 @@ - https://easysnmp.readthedocs.io/en/latest/session_api.html """ -__version__ = '0.9.0' +__version__ = '0.10.0' __author__ = 'anima' # imports @@ -126,6 +126,26 @@ class SNMPSynologyDisk(): return disks +# +# Synology General Summary +# + +class SNMPSynologySummary(nagiosplugin.Summary): + def verbose(self, results): + result_str = '' + for result in results: + result_str += f'{str(result)}\n' + return result_str + + def ok(self, results): + return + + def problem(self, results): + return + + + + # # Synology [DSM & DSM UC] System partition status. # @@ -275,20 +295,6 @@ class SNMPSynologyFansResult(nagiosplugin.Result): return f'{self.metric.name} fan is in status {status}!' -class SNMPSynologyFansSummary(nagiosplugin.Summary): - def verbose(self, results): - result_str = '' - for result in results: - result_str += f'{str(result)}\n' - return result_str - - def ok(self, results): - return - - def problem(self, results): - return - - # # Synology [DSM & DSM UC] Checks whether a new version or update of DSM is available # @@ -381,6 +387,75 @@ class SNMPSynologyMemoryResource(nagiosplugin.Resource): self.session = session +# +# Synology [DSM & DSM UC] Checks disks +# +class SNMPSynologyDiskHealthResource(nagiosplugin.Resource, SNMPSynologyDisk): + def __init__(self, session) -> None: + self.session = session + + def probe(self) -> list: + """check staus and health of all disks + + Returns: + Generator[nagisplugin.Metric]: multiple metric elements (yield) + """ + disks = self.get_disks() + for disk in disks: + yield nagiosplugin.Metric(name=disk['id'], value=disk, context='disk_status_context') + yield nagiosplugin.Metric(name=disk['id'], value=disk, context='disk_health_context') + + + +class SNMPSynologyDiskStatusContext(nagiosplugin.Context): + def __init__(self, name): + super().__init__(name, fmt_metric='{name} is', result_cls=SNMPSynologyDiskStatusResult) + + def evaluate(self, metric, resource): + if metric.value['status'] in ['4', '5']: + return self.result_cls(nagiosplugin.Critical, "critical", metric) + elif metric.value['status'] in ['2', '3']: + return self.result_cls(nagiosplugin.Warn, "warning", metric) + elif metric.value['status'] == '1': + return self.result_cls(nagiosplugin.Ok, "ok", metric) + return self.result_cls(nagiosplugin.Unknown, "unknown", metric) + + +class SNMPSynologyDiskStatusResult(nagiosplugin.Result): + def __str__(self): + if self.metric.value['status'] == '1': status = 'Normal' + elif self.metric.value['status'] == '2': status = 'Initialized' + elif self.metric.value['status'] == '3': status = 'NotInitialized' + elif self.metric.value['status'] == '4': status = 'SystemPartitionFailed' + elif self.metric.value['status'] == '5': status = 'Crashed' + else: status = 'unknown' + return f'{self.metric.name} (role: {self.metric.value["role"]}) is in status {status}!' + + +class SNMPSynologyDiskHealthContext(nagiosplugin.Context): + def __init__(self, name): + super().__init__(name, fmt_metric='{name} is', result_cls=SNMPSynologyDiskHealthResult) + + def evaluate(self, metric, resource): + if metric.value['health'] in ['3', '4']: + return self.result_cls(nagiosplugin.Critical, "critical", metric) + elif metric.value['health'] == '2': + return self.result_cls(nagiosplugin.Warn, "warning", metric) + elif metric.value['health'] == '1': + return self.result_cls(nagiosplugin.Ok, "ok", metric) + return self.result_cls(nagiosplugin.Unknown, "unknown", metric) + + +class SNMPSynologyDiskHealthResult(nagiosplugin.Result): + def __str__(self): + if self.metric.value['health'] == '1': status = 'Normal' + elif self.metric.value['health'] == '2': status = 'Warning' + elif self.metric.value['health'] == '3': status = 'Critical' + elif self.metric.value['health'] == '4': status = 'Failing' + else: status = 'unknown' + return f'Health of {self.metric.name} is in status {status}!' + + # # Arguments # @@ -472,7 +547,7 @@ def main(): case 'fans': check = nagiosplugin.Check(SNMPSynologyFansResource(session=session), SNMPSynologyFansContext(name='fan_context'), - SNMPSynologyFansSummary()) + SNMPSynologySummary()) check.name = "Fans Status" case 'firmware': check = nagiosplugin.Check(SNMPSynologyFirmwareResource(session=session), @@ -490,10 +565,11 @@ def main(): nagiosplugin.Summary()) check.name = "Memory Usage" case 'disk': - # check = nagiosplugin.Check(SNMPSynologyDiskResource(session=session), - # nagiosplugin.ScalarContext(name='memory_scalar_context', warning=args.warning, critical=args.critical), - # nagiosplugin.Summary()) - # check.name = "Memory Usage" + check = nagiosplugin.Check(SNMPSynologyDiskHealthResource(session=session), + SNMPSynologyDiskHealthContext(name='disk_health_context'), + SNMPSynologyDiskStatusContext(name='disk_status_context'), + SNMPSynologySummary()) + check.name = "Disk Health" pass case _: raise nagiosplugin.CheckError(f'Unknown check mode: {args.check_mode}')