#!/usr/bin/python3 import argparse import subprocess import logging import time import urllib.parse from config_collector import ConfigCollector, InfluxWriter from influxdb import InfluxDBClient logging.basicConfig(level=logging.INFO) logger = logging.getLogger() class SystemctlMonitor: ACTIVE_STATE_KEY='ActiveState' SUBSTATE_KEY='SubState' LOAD_STATE_KEY='LoadState' def __init__(self, service_name, sample_rate, agg_period, hostname, port, database): self.service_name = service_name self.writer = InfluxWriter(hostname, port, database) self.collection_thread = ConfigCollector(self.get_systemctl_sample, self.writer.write_func, self.service_name, sample_rate, agg_period) def start(self): self.collection_thread.start() def stop(self): self.collection_thread.stop() def get_current_measurement(self): return self.collection_thread.current_measurement def get_systemctl_sample(self): return (self.get_systemctl_status(self.service_name), time.time()) def get_systemctl_status(self, service_name): load_state = 'unknown' active_state = 'unknown' sub_state = 'unknown' cmd = "systemctl show {0}".format(service_name) proc = subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True) out, err = proc.communicate() if out: out = out.decode('ascii') if err: err = err.decode('ascii') logger.debug("Return code = {0}".format(proc.returncode)) if proc.returncode != 0: logger.error("Could not get status for service {0}, {1}".format(service_name, err)) raise Exception("Could not get status for service {0}, {1}".format(service_name, err)) for line in iter(out.splitlines()): parts = line.split('=') if parts[0] == SystemctlMonitor.LOAD_STATE_KEY: load_state = parts[1] elif parts[0] == SystemctlMonitor.ACTIVE_STATE_KEY: active_state = parts[1] elif parts[0] == SystemctlMonitor.SUBSTATE_KEY: sub_state = parts[1] return load_state + "." + active_state + "." + sub_state def main(): parser = argparse.ArgumentParser(description='systemctrl state monitor') parser.add_argument('-service', help='service name', required=True) parser.add_argument('-rate', help='sample rate', required=True) parser.add_argument('-agg', help='aggregation period', required=True) parser.add_argument('-host', help='telegraf hostname', required=True) parser.add_argument('-port', help='telegraf port', required=True) parser.add_argument('-db', help='database name', required=True) parser.add_argument('-debug', '--debug', action='store_true') args = parser.parse_args() print("Starting SystemctlMonitor : {0}, {1}, {2}, {3}, {4}, {5}".format(args.service, args.rate, args.agg, args.host, args.port, args.db)) if args.debug == True: print("Setting logging level to to DEBUG") logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) mon = SystemctlMonitor(args.service, int(args.rate), int(args.agg), args.host, int(args.port), args.db) mon.start() if __name__== "__main__": main()