Skip to content
Snippets Groups Projects
systemctl_monitor.py 3.27 KiB
#!/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()