Repository: DinoTools/monitoring-check_routeros (language: python)

Issue:
Check system.uptime  - add warning/critical 
Hello,
it would be great if you can add Warning\/Critical thresholds check for System Uptime.
It will allow to monitor for unexpected reboot.

Thanks.


Discussion / hints:

Fix patch:
diff --git a/routeros_check/check/system_uptime.py b/routeros_check/check/system_uptime.py
index 97f7172..76ef620 100644
--- a/routeros_check/check/system_uptime.py
+++ b/routeros_check/check/system_uptime.py
@@ -5,9 +5,10 @@
 import librouteros
 import librouteros.query
 import nagiosplugin
+from nagiosplugin.state import Ok as STATE_Ok, Warn as STATE_Warn, Critical as STATE_Critical
 
 from ..cli import cli
-from ..helper import logger
+from ..helper import humanize_time, logger
 from ..resource import RouterOSCheckResource
 
 
@@ -37,17 +38,49 @@ def probe(self):
         )
 
 
+class UptimeSimpleScalarContext(nagiosplugin.ScalarContext):
+    def describe(self, metric):
+        return humanize_time(metric.value)
+
+    def evaluate(self, metric, resource):
+        if str(self.critical) != "" and metric.value in self.critical:
+            return self.result_cls(
+                STATE_Critical,
+                None,
+                metric
+            )
+
+        if str(self.warning) != "" and metric.value in self.warning:
+            return self.result_cls(
+                STATE_Warn,
+                None,
+                metric
+            )
+        return self.result_cls(STATE_Ok, None, metric)
+
+
 @cli.command("system.uptime")
+@click.option(
+    "--warning",
+    help="State WARNING if current uptime is below this threshold",
+)
+@click.option(
+    "--critical",
+    help="State CRITICAL if current uptime is below this threshold",
+    default=None,
+)
 @click.pass_context
 @nagiosplugin.guarded
-def system_uptime(ctx):
+def system_uptime(ctx, warning, critical):
     """Get Uptime of a device"""
     check = nagiosplugin.Check(
         SystemUptimeResource(
             cmd_options=ctx.obj,
         ),
-        nagiosplugin.ScalarContext(
+        UptimeSimpleScalarContext(
             name="uptime",
+            warning=float(warning) if warning else None,
+            critical=float(critical) if critical else None,
         )
     )
 
diff --git a/routeros_check/helper.py b/routeros_check/helper.py
index b4b9a3e..057b62b 100644
--- a/routeros_check/helper.py
+++ b/routeros_check/helper.py
@@ -1,11 +1,12 @@
 # SPDX-FileCopyrightText: PhiBo DinoTools (2021)
 # SPDX-License-Identifier: GPL-3.0-or-later
 
+from datetime import timedelta
 import importlib
 import logging
 import os
 import re
-from typing import List, Optional
+from typing import List, Optional, Union
 
 logger = logging.getLogger('nagiosplugin')
 
@@ -90,6 +91,38 @@ def escape_filename(value):
     return re.sub(r"[-\s]+", '-', value)
 
 
+def humanize_time(time: Union[float, int, timedelta]):
+    interval_mappings = {
+        1: {
+            "short": "s",
+        },
+        60: {
+            "short": "m",
+        },
+        3600: {
+            "short": "h",
+        },
+        86400: {
+            "short": "d",
+        }
+    }
+
+    if isinstance(time, timedelta):
+        time = time.total_seconds()
+
+    intervals: List[int] = sorted(interval_mappings.keys())
+    intervals.reverse()
+
+    results: List[str] = []
+    for interval in intervals:
+        v = int(time // interval)
+        if v or len(results):
+            results.append(f"{v}{interval_mappings[interval]['short']}")
+        time = time % interval
+
+    return " ".join(results)
+
+
 def load_modules(pkg_names: Optional[List] = None):
     if pkg_names is None:
         pkg_names = [".check"]


Test patch:
diff --git a/tests/helpers_test.py b/tests/helpers_test.py
index 83005a6..72c0d1a 100644
--- a/tests/helpers_test.py
+++ b/tests/helpers_test.py
@@ -72,6 +72,28 @@ def test_compare_routeros_version_lt(self):
         for item in cmp_items:
             assert not helper.RouterOSVersion(item[0]) < helper.RouterOSVersion(item[1])
 
+    def test_humanize_time_with_int(self):
+        assert helper.humanize_time(10) == "10s"
+        assert helper.humanize_time(75) == "1m 15s"
+        assert helper.humanize_time(3601) == "1h 0m 1s"
+        assert helper.humanize_time(
+            60 * 60 * 24 +
+            60 * 60 * 1 +
+            60 * 13 +
+            44
+        ) == "1d 1h 13m 44s"
+
+    def test_humanize_time_with_timedelta(self):
+        from datetime import timedelta
+        assert helper.humanize_time(
+            timedelta(
+                days=2,
+                hours=12,
+                minutes=33,
+                seconds=56
+            )
+        ) == "2d 12h 33m 56s"
+
     def test_parse_routeros_version(self):
         a = helper.RouterOSVersion("7.8")
         assert a.major == 7