From 5f34f3169a8e855b22685f92eee4c27504c89a95 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 30 May 2025 23:26:22 +0200 Subject: [PATCH] updated routermon e upsmon, ora funzionano --- .vscode/launch.json | 10 ++--- docker/docker-compose.yaml | 70 ++++++++++++++++++++++++++++++++++ routermon/routermon.Dockerfile | 6 ++- routermon/routermon.py | 48 ++++++++++++----------- upsmon/ups.py | 35 ++++++++++++----- upsmon/upsmon.Dockerfile | 9 +++++ 6 files changed, 140 insertions(+), 38 deletions(-) create mode 100644 docker/docker-compose.yaml create mode 100644 upsmon/upsmon.Dockerfile diff --git a/.vscode/launch.json b/.vscode/launch.json index d57feba..6c3ad72 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,13 +9,13 @@ "console": "integratedTerminal", "env": { "INTERVAL" : "5", - "INFLUXDB_TOKEN":"rg5dZrBHQxJTH4Etq2jmDduggCC28QaWcua0VVvW4hjsEVhy_JUpVhcyg-aLAbM-TXv92pTB7IGJlyAPvi7Kvw==", - "INFLUXDB_URL" : "http://edelweiss-srv:4567", + "INFLUXDB_TOKEN":"b46xoZRVsQvyGnv8TVMmTDmxT8LZZsi7O_u776MHIxiE9CPh7yHi0iHMOerUT5o1y65MMxeKKA7S-ijQ3elK-g==", + "INFLUXDB_URL" : "http://localhost:8085", "INFLUXDB_ORG" : "edelweiss", - "INFLUXDB_BUCKET" : "router", - "MIKROTIK_IP": "10.128.0.1", + "INFLUXDB_BUCKET" : "theatre", + "MIKROTIK_IP": "192.168.31.1", "MIKROTIK_USER": "service", - "MIKROTIK_PASSWORD": "edxservice", + "MIKROTIK_PASSWORD": "dataservice", "LOG_FILE": "/tmp/routermon.log", "LOG_FILE_LVL": "WARNING", "LOG_CLI_LVL": "DEBUG" diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml new file mode 100644 index 0000000..ba2a8fd --- /dev/null +++ b/docker/docker-compose.yaml @@ -0,0 +1,70 @@ +services: + influxdb2: + image: influxdb:2-alpine + container_name: edx-influxdb + restart: unless-stopped + ports: + - 8086:8086 + volumes: + - type: volume + source: influxdb2-data + target: /var/lib/influxdb2 + - type: volume + source: influxdb2-config + target: /etc/influxdb2 + + grafana: + image: grafana/grafana:latest + container_name: edx-grafana + restart: unless-stopped + ports: + - 8085:3000 + volumes: + - grafana-data:/var/lib/grafana + depends_on: + - influxdb2 + + upsmon: + image: upsmon:latest + container_name: edx-upsmon + restart: unless-stopped + depends_on: + - influxdb2 + devices: + - /dev/ttyUSB1:/dev/ttyUSB1 + environment: + - INTERVAL=5 + - INFLUXDB_TOKEN=b46xoZRVsQvyGnv8TVMmTDmxT8LZZsi7O_u776MHIxiE9CPh7yHi0iHMOerUT5o1y65MMxeKKA7S-ijQ3elK-g== + - INFLUXDB_URL=http://influxdb2:8086 + - INFLUXDB_ORG=edelweiss + - INFLUXDB_BUCKET=theatre + - PORT=/dev/ttyUSB1 + - BAUD=2400 + - LOG_FILE=/tmp/upsmon.log + - LOG_FILE_LVL=WARNING + - LOG_CLI_LVL=INFO + + routermon: + image: routermon:latest + container_name: edx-routermon + restart: unless-stopped + depends_on: + - influxdb2 + environment: + - INTERVAL=5 + - INFLUXDB_TOKEN=b46xoZRVsQvyGnv8TVMmTDmxT8LZZsi7O_u776MHIxiE9CPh7yHi0iHMOerUT5o1y65MMxeKKA7S-ijQ3elK-g== + - INFLUXDB_URL=http://influxdb2:8086 + - INFLUXDB_ORG=edelweiss + - INFLUXDB_BUCKET=theatre + - MIKROTIK_IP=192.168.31.1 + - MIKROTIK_USER=service + - MIKROTIK_PASSWORD=dataservice + - LOG_FILE=/tmp/routermon.log + - LOG_FILE_LVL=WARNING + - LOG_CLI_LVL=INFO + + +volumes: + influxdb2-data: + influxdb2-config: + grafana-data: diff --git a/routermon/routermon.Dockerfile b/routermon/routermon.Dockerfile index a9ded21..e91c2b9 100644 --- a/routermon/routermon.Dockerfile +++ b/routermon/routermon.Dockerfile @@ -2,4 +2,8 @@ FROM python:3.12-alpine RUN apk update && apk upgrade --no-cache -RUN apk add python3-routeros \ No newline at end of file +RUN pip install --no-cache-dir RouterOS-API influxdb-client + +COPY ./routermon.py /home/routermon.py + +CMD [ "python", "/home/routermon.py" ] diff --git a/routermon/routermon.py b/routermon/routermon.py index 2335637..8549350 100644 --- a/routermon/routermon.py +++ b/routermon/routermon.py @@ -6,30 +6,32 @@ import signal import json import routeros_api -import influxdb_client -from influxdb_client import Point +from influxdb_client.client.write.point import Point +from influxdb_client.client.influxdb_client import InfluxDBClient from influxdb_client.client.write_api import ASYNCHRONOUS, SYNCHRONOUS # Get environment variables env = dict(os.environ) LOGGER: logging.Logger -class Runner: - running: bool = True - def __init__(self): - signal.signal(signal.SIGINT, self.stop) - signal.signal(signal.SIGTERM, self.stop) +class SignalHandler: + running: bool - def stop(self, _): + def __init__(self): + self.running: bool = True + signal.signal(signal.SIGINT, self._handle_sigint) + signal.signal(signal.SIGTERM, self._handle_sigint) + + def _handle_sigint(self, signum, frame): self.running = False def main(): INTERVAL = int(env['INTERVAL']) # Init InfluxDB - write_client = influxdb_client.InfluxDBClient(url=env['INFLUXDB_URL'], - token=env['INFLUXDB_TOKEN'], - org=env['INFLUXDB_ORG']) + write_client = InfluxDBClient(url=env['INFLUXDB_URL'], + token=env['INFLUXDB_TOKEN'], + org=env['INFLUXDB_ORG']) write_api = write_client.write_api(write_options=ASYNCHRONOUS) # Init routerOS API connection = routeros_api.RouterOsApiPool(env['MIKROTIK_IP'], @@ -38,10 +40,14 @@ def main(): plaintext_login=True) api = connection.get_api() - run = Runner.running + run: SignalHandler = SignalHandler() last = 0 if_points = [] if_stats_old = api.get_resource('/interface/ethernet').call('print', {'proplist': 'name,rx-bytes,tx-bytes'}) + for n,d in enumerate(if_stats_old): + for k,v in d.items(): + if str.isdecimal(v): + if_stats_old[n][k] = int(v) ### MAIN LOOP ### while run: try: @@ -53,14 +59,14 @@ def main(): for k,v in d.items(): if str.isdecimal(v): if_stats[n][k] = int(v) - if_stats[n]['rx-rate'] = int((d['rx-bytes']-if_stats_old[n]['rx-bytes'])/(now-last)) - if_stats[n]['tx-rate'] = int((d['tx-bytes']-if_stats_old[n]['tx-bytes'])/(now-last)) - if_points.append( - Point("interfaces") - .tag("interface", d['name']) - .field('rx-rate', if_stats[n]['rx-rate']) - .field('tx-rate', if_stats[n]['tx-rate']) - ) + if_stats[n]['rx-rate'] = int((if_stats[n]['rx-bytes']-if_stats_old[n]['rx-bytes'])/(now-last)) + if_stats[n]['tx-rate'] = int((if_stats[n]['tx-bytes']-if_stats_old[n]['tx-bytes'])/(now-last)) + if_points.append( + Point("interfaces") + .tag("interface", d['name']) + .field('rx-rate', if_stats[n]['rx-rate']) + .field('tx-rate', if_stats[n]['tx-rate']) + ) rs1 = write_api.write(bucket=env['INFLUXDB_BUCKET'], org=env['INFLUXDB_ORG'], record=if_points) rs2 = write_api.write(bucket=env['INFLUXDB_BUCKET'], org=env['INFLUXDB_ORG'], @@ -72,8 +78,6 @@ def main(): LOGGER.debug(f"\nInterfaces: {json.dumps(if_stats, indent = 2)}") LOGGER.debug(f"\nResources: {json.dumps(hw_stats, indent = 2)}") time.sleep(INTERVAL) - except KeyboardInterrupt: - run = False except Exception as e: print(f"Unexpected exception: [{e}]") return 1 diff --git a/upsmon/ups.py b/upsmon/ups.py index 8c1e1c7..d14a751 100644 --- a/upsmon/ups.py +++ b/upsmon/ups.py @@ -7,17 +7,23 @@ import logging import signal import json +from influxdb_client.client.write.point import Point +from influxdb_client.client.influxdb_client import InfluxDBClient +from influxdb_client.client.write_api import ASYNCHRONOUS, SYNCHRONOUS + # Get environment variables env = dict(os.environ) LOGGER: logging.Logger -class Runner: - running: bool = True - def __init__(self): - signal.signal(signal.SIGINT, self.stop) - signal.signal(signal.SIGTERM, self.stop) +class SignalHandler: + running: bool - def stop(self, _): + def __init__(self): + self.running: bool = True + signal.signal(signal.SIGINT, self._handle_sigint) + signal.signal(signal.SIGTERM, self._handle_sigint) + + def _handle_sigint(self, signum, frame): self.running = False def send(port: serial.Serial, d: str): @@ -47,9 +53,14 @@ def bruteforceCommands(port: serial.Serial): def main(): INTERVAL = int(env['INTERVAL']) - run = Runner.running + LOGGER.debug(json.dumps(env, indent=2)) + run: SignalHandler = SignalHandler() port = serial.Serial(port=env['PORT'], baudrate=int(env['BAUD']), bytesize=8, parity='N', stopbits=1) - while run: + write_client = InfluxDBClient(url=env['INFLUXDB_URL'], + token=env['INFLUXDB_TOKEN'], + org=env['INFLUXDB_ORG']) + write_api = write_client.write_api(write_options=ASYNCHRONOUS) + while run.running: try: send(port, "Q1") data = receive(port, "Q1").lstrip('(').split() @@ -66,9 +77,13 @@ def main(): 'onLine': True if str(data[7]).endswith('1') else False, } LOGGER.debug(f"UPS Status: \n{json.dumps(values, indent=2)}") + if values['onBatt']: + LOGGER.info(f"OnBattery\n{json.dumps(values,indent=2)}") + p = Point('ups') + for k,v in values.items(): + p.field(k,v) + write_api.write(bucket=env['INFLUXDB_BUCKET'], org=env['INFLUXDB_ORG'], record=p) time.sleep(INTERVAL) - except KeyboardInterrupt: - run = False except Exception as e: print(f"Unexpected exception: [{e}]") return 1 diff --git a/upsmon/upsmon.Dockerfile b/upsmon/upsmon.Dockerfile new file mode 100644 index 0000000..70a707f --- /dev/null +++ b/upsmon/upsmon.Dockerfile @@ -0,0 +1,9 @@ +FROM python:3.12-alpine + +RUN apk update && apk upgrade --no-cache + +RUN pip install --no-cache-dir pyserial RouterOS-API influxdb-client + +COPY ./ups.py /home/ups.py + +CMD [ "python", "/home/ups.py" ]