import os import sys import time import logging import signal import json import routeros_api import influxdb_client from influxdb_client import Point from influxdb_client.client.write_api import ASYNCHRONOUS, SYNCHRONOUS # Get environment variables env = dict(os.environ) LOGGER = None class Runner: running: property = True def __init__(self): signal.signal(signal.SIGINT, self.stop) signal.signal(signal.SIGTERM, self.stop) def stop(self, _): 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_api = write_client.write_api(write_options=ASYNCHRONOUS) # Init routerOS API connection = routeros_api.RouterOsApiPool(env['MIKROTIK_IP'], username=env['MIKROTIK_USER'], password=env['MIKROTIK_PASSWORD'], plaintext_login=True) api = connection.get_api() run = Runner.running last = 0 if_points = [] if_stats_old = api.get_resource('/interface/ethernet').call('print', {'proplist': 'name,rx-bytes,tx-bytes'}) ### MAIN LOOP ### while run: try: now = time.time() if_stats = api.get_resource('/interface/ethernet').call('print', {'proplist': 'name,rx-bytes,tx-bytes'}) hw_stats = api.get_resource('/system/resource').call('print', {'proplist':'uptime,cpu-load'})[0] # calcolo della velocita' interfaccia a ogni ciclo for n,d in enumerate(if_stats): 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']) ) 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'], record=Point('resources').field('cpu',int(hw_stats['cpu-load'])) ) LOGGER.debug(f"InfluxWrite: W1:{rs1}, W2:{rs2}") if_stats_old = if_stats last = time.time() 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 ### END MAIN LOOP ### connection.disconnect() return 0 if __name__ == "__main__": # Logger Constants LOG_FORMAT = '%(asctime)s| %(levelname)-7s|%(funcName)-10s|%(lineno)-3d: %(message)-50s' # Enabling Logger LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) LOGGER.propagate = False formatter = logging.Formatter(LOG_FORMAT, None) levels = logging.getLevelNamesMapping() # File logging log_name = os.path.abspath(env['LOG_FILE']) fh = logging.FileHandler(log_name) fh.setLevel(levels[env['LOG_FILE_LVL']]) fh.setFormatter(formatter) LOGGER.addHandler(fh) # Console logging cl = logging.StreamHandler(sys.stdout) cl.setLevel(levels[env['LOG_CLI_LVL']]) cl.setFormatter(formatter) LOGGER.addHandler(cl) LOGGER.warning(f"Routermon started on: {time.asctime()}") while main(): LOGGER.error("Main thread exited unexpectedly") time.sleep(15) sys.exit(0)