check_trex/check_trex.py
Julien Riou f62623af38
chore: Bump version to 1.0.3
Signed-off-by: Julien Riou <julien@riou.xyz>
2022-05-14 11:49:20 +02:00

314 lines
8.7 KiB
Python
Executable file

#!/usr/bin/env python3
import argparse
import logging
import sys
import requests
from nagiosplugin import (
Check,
Context,
Metric,
Performance,
Resource,
ScalarContext,
Summary,
)
from nagiosplugin.state import Critical, Ok, Unknown, Warn
logger = logging.getLogger(__name__)
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument(
"-v",
"--verbose",
dest="loglevel",
action="store_const",
const=logging.INFO,
help="Print more output",
)
parser.add_argument(
"-d",
"--debug",
dest="loglevel",
action="store_const",
const=logging.DEBUG,
default=logging.WARNING,
help="Print even more output",
)
parser.add_argument(
"--version",
dest="show_version",
action="store_true",
help="Print version and exit",
)
parser.add_argument(
"--url",
dest="url",
type=str,
help="API URL of T-Rex miner",
default="http://127.0.0.1:4067",
)
parser.add_argument(
"--timeout",
dest="timeout",
type=int,
help="Timeout when requesting T-Rex API",
default=3,
)
parser.add_argument(
"--hashrate-warning",
dest="hashrate_warning",
type=int,
help="Raise warning if hashrate goes below this threshold",
)
parser.add_argument(
"--hashrate-critical",
dest="hashrate_critical",
type=int,
help="Raise critical if hashrate goes below this threshold",
)
parser.add_argument(
"--uptime-warning",
dest="uptime_warning",
type=int,
help="Raise warning if uptime goes below this threshold",
)
parser.add_argument(
"--uptime-critical",
dest="uptime_critical",
type=int,
help="Raise critical if uptime goes below this threshold",
)
parser.add_argument(
"--paused-warning",
dest="paused_warning",
action="store_true",
help="Raise warning when T-Rex is paused",
)
parser.add_argument(
"--paused-critical",
dest="paused_critical",
action="store_true",
help="Raise critical when T-Rex is paused",
)
parser.add_argument(
"--temperature-warning",
dest="temperature_warning",
type=int,
help="Raise warning if temperature goes over this threshold",
default=70,
)
parser.add_argument(
"--temperature-critical",
dest="temperature_critical",
type=int,
help="Raise critcal if temperature goes over this threshold",
default=90,
)
parser.add_argument(
"--memory-temperature-warning",
dest="memory_temperature_warning",
type=int,
help="Raise warning if memory temperature goes over this threshold",
default=90,
)
parser.add_argument(
"--memory-temperature-critical",
dest="memory_temperature_critical",
type=int,
help="Raise critcal if memory temperature goes over this threshold",
default=110,
)
args = parser.parse_args()
return args
def setup_logging(args):
logging.basicConfig(format="%(levelname)s: %(message)s", level=args.loglevel)
def show_version():
print("1.0.3")
class BelowThresholdContext(Context):
def __init__(self, name, warning=None, critical=None):
super().__init__(name)
self.warning = warning
self.critical = critical
def evaluate(self, metric, resource):
if self.critical and metric.value <= self.critical:
return self.result_cls(Critical, f"{metric.value}<={self.critical}", metric)
elif self.warning and metric.value <= self.warning:
return self.result_cls(Warn, f"{metric.value}<={self.warning}", metric)
else:
return self.result_cls(Ok, None, metric)
def performance(self, metric, resource):
return Performance(
metric.name,
metric.value,
metric.uom,
self.warning,
self.critical,
metric.min,
metric.max,
)
class BooleanContext(Context):
def __init__(self, name, expected=True, warning=False, critical=False):
super().__init__(name)
self.expected = expected
self.warning = warning
self.critical = critical
def evaluate(self, metric, resource):
if not metric.value is self.expected:
result_type = Ok
if self.critical:
result_type = Critical
elif self.warning:
result_type = Warn
return self.result_cls(
result_type, f"{metric.name} is not {self.expected}", metric
)
else:
return self.result_cls(Ok, None, metric)
class Trex(Resource):
def __init__(self, url, timeout):
self.url = url
self.timeout = timeout
def probe(self):
r = requests.get(f"{self.url}/summary", timeout=self.timeout)
r.raise_for_status()
data = r.json()
logger.debug("Response:")
logger.debug(data)
metrics = []
if "hashrate" in data:
hashrate = data["hashrate"]
logger.info(f"Hashrate is {hashrate}")
metrics.append(Metric("hashrate", hashrate, context="hashrate"))
if "success" in data:
success = bool(data["success"])
if success:
logger.info("T-Rex is successfully started")
else:
logger.info("T-Rex is not successfully started")
metrics.append(Metric("success", success, context="success"))
if "paused" in data:
paused = bool(data["paused"])
if paused:
logger.info("T-Rex is paused")
else:
logger.info("T-Rex is not paused")
metrics.append(Metric("paused", paused, context="paused"))
if "uptime" in data:
uptime = data["uptime"]
seconds = "seconds" if uptime > 1 else "second"
logger.info(f"Uptime is {uptime} {seconds}")
metrics.append(Metric("uptime", uptime, context="uptime"))
for gpu in data.get("gpus"):
name = gpu["name"]
id = gpu["gpu_id"]
if "temperature" in gpu:
temperature = gpu["temperature"]
logger.info(f"GPU {id} ({name}): temperature is {temperature}C")
metrics.append(
Metric(f"temperature_{id}", temperature, context="temperature")
)
if "memory_temperature" in gpu:
memory_temperature = gpu["memory_temperature"]
logger.info(
f"GPU {id} ({name}): memory temperature is {memory_temperature}C"
)
metrics.append(
Metric(
f"memory_temperature_{id}",
memory_temperature,
context="memory_temperature",
)
)
return metrics
class TrexSummary(Summary):
def problem(self, results):
return ", ".join(
[
f"{result.metric.name} {result.state}: {result.hint}"
for result in results
if str(result.state) != "ok"
]
)
def main():
args = parse_arguments()
setup_logging(args)
if args.show_version:
show_version()
return
try:
check = Check(
Trex(url=args.url, timeout=args.timeout),
BooleanContext("success", expected=True),
BooleanContext(
"paused",
expected=True,
warning=args.paused_warning,
critical=args.paused_critical,
),
BelowThresholdContext(
"hashrate",
warning=args.hashrate_warning,
critical=args.hashrate_critical,
),
BelowThresholdContext(
"uptime", warning=args.uptime_warning, critical=args.uptime_critical
),
ScalarContext(
"temperature",
warning=args.temperature_warning,
critical=args.temperature_critical,
),
ScalarContext(
"memory_temperature",
warning=args.memory_temperature_warning,
critical=args.memory_temperature_critical,
),
TrexSummary(),
)
check.main()
except Exception as err:
print(f"Failed to execute check: {str(err)}")
logger.debug(err, exc_info=True)
sys.exit(Unknown.code)
if __name__ == "__main__":
main()