From 66b90c89dc008c50939ef6e1918565b0f33b7d87 Mon Sep 17 00:00:00 2001 From: Francesco Beneventi Date: Tue, 29 Apr 2025 00:32:46 +0200 Subject: [PATCH 1/6] Add support for threads #2 #4 - Improved doc #3 --- ipmi_pub.py | 205 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 142 insertions(+), 63 deletions(-) diff --git a/ipmi_pub.py b/ipmi_pub.py index 3a4baf2..dbdc8fc 100644 --- a/ipmi_pub.py +++ b/ipmi_pub.py @@ -1,13 +1,11 @@ #!/usr/bin/python # -*- coding: utf-8 -*- """ - IPMItool/freeipmi MQTT publisher Created on Fri Dec 19 12:20:56 2014 @author: francesco.beneventi@unibo.it - """ import re import os @@ -23,6 +21,7 @@ from subprocess import Popen, PIPE import paho.mqtt.client as mqtt import multiprocessing as mp +from multiprocessing.dummy import Pool as ThreadPool import signal from daemon import Daemon @@ -51,6 +50,8 @@ def __init__(self, hostinfo, tool_path='ipmitool', mqtt_base_topic='', timeout=N self.mqtt_topic = self.build_base_topic(mqtt_base_topic) self.timeout = timeout self.client = None + self.process = None + self.terminate_event = False mp.current_process().name = self.hostinfo['hostname'] def build_base_topic(self, mqtt_base_topic): @@ -66,10 +67,10 @@ def build_base_topic(self, mqtt_base_topic): rack, chassis, slot = server_coord return topic.format(mqtt_base_topic, - self.hostinfo['hostname'], - rack, - chassis, - slot) + self.hostinfo['hostname'], + rack, + chassis, + slot) def setup_cmd(self, tool_par): """ @@ -79,39 +80,39 @@ def setup_cmd(self, tool_par): if self.TOOL_PATH == 'ipmitool': cmd = self.TOOL_PATH - cmd += (' -I lanplus') - cmd += (' -H %s' % self.hostinfo['bmc_ip']) + cmd += ' -I lanplus' + cmd += ' -H %s' % self.hostinfo['bmc_ip'] if self.hostinfo['username'] is not None: - cmd += (' -U %s' % self.hostinfo['username']) + cmd += ' -U %s' % self.hostinfo['username'] if self.hostinfo['password'] is not None: - cmd += (' -P %s' % self.hostinfo['password']) + cmd += ' -P %s' % self.hostinfo['password'] if self.hostinfo['custom_opt'] is not None: - cmd += (' %s' % self.hostinfo['custom_opt']) - cmd += (' ') - cmd += (IPMI_OPTIONS) + cmd += ' %s' % self.hostinfo['custom_opt'] + cmd += ' ' + cmd += IPMI_OPTIONS if self.TOOL_PATH == 'ipmi-sensors': cmd = self.TOOL_PATH - cmd += (' -h %s' % self.hostinfo['bmc_ip']) + cmd += ' -h %s' % self.hostinfo['bmc_ip'] if self.hostinfo['username'] is not None: - cmd += (' -u %s' % self.hostinfo['username']) + cmd += ' -u %s' % self.hostinfo['username'] if self.hostinfo['password'] is not None: - cmd += (' -p %s' % self.hostinfo['password']) - cmd += (' ') - cmd += (IPMI_OPTIONS) + cmd += ' -p %s' % self.hostinfo['password'] + cmd += ' ' + cmd += IPMI_OPTIONS if self.TOOL_PATH == 'openbmctool': cmd = self.TOOL_PATH - cmd += (' -H %s' % self.hostinfo['bmc_ip']) + cmd += ' -H %s' % self.hostinfo['bmc_ip'] if self.hostinfo['username'] is not None: - cmd += (' -U %s' % self.hostinfo['username']) + cmd += ' -U %s' % self.hostinfo['username'] if self.hostinfo['password'] is not None: - cmd += (' -P %s' % self.hostinfo['password']) - cmd += (' ') - cmd += (IPMI_OPTIONS) + cmd += ' -P %s' % self.hostinfo['password'] + cmd += ' ' + cmd += IPMI_OPTIONS - cmd += (' %s' % tool_par) - cmd += (' 2>&1') + cmd += ' %s' % tool_par + cmd += ' 2>&1' return cmd @@ -120,17 +121,21 @@ def run_cmd(self, cmd): output = '' if self.hostinfo['password'] is not None: - logger.debug("[%s] Executing command: %s", mp.current_process().name, cmd.replace(self.hostinfo['password'], '*' * 8)) + logger.debug("[%s] Executing command: %s", mp.current_process().name, + cmd.replace(self.hostinfo['password'], '*' * 8)) else: logger.debug("[%s] Executing command: %s", mp.current_process().name, cmd) try: if self.timeout: cmd = ('timeout %s ' % self.timeout) + cmd - child = Popen(cmd, shell=True, text=True, stdout=PIPE) - output = child.communicate()[0] - if child.returncode != 0: - logger.error("[%s] Error in run_cmd(): %s - cmd: %s - ret %s", mp.current_process().name, output, cmd, child.returncode) + self.process = Popen(cmd, shell=True, text=True, stdout=PIPE) + output = self.process.communicate()[0] + if self.process.returncode != 0: + logger.error("[%s] Error in run_cmd(): %s - cmd: %s - ret %s", + mp.current_process().name, output, cmd, self.process.returncode) + if self.terminate_event: + return output except Exception: logger.exception("[%s] Exception in run_cmd(): ", mp.current_process().name) @@ -183,9 +188,9 @@ def run(self): Daemon main code loop """ info_txt = "[%s] Binding IPMI publisher [%s] to: Host=%s BMC_IP=%s tool_path=%s" % ( - mp.current_process().name, mp.current_process().name, self.hostinfo['hostname'], + mp.current_process().name, mp.current_process().name, self.hostinfo['hostname'], self.hostinfo['bmc_ip'], self.TOOL_PATH) - + logger.info(info_txt) self.client = mqtt.Client() @@ -208,23 +213,27 @@ def run(self): logger.info("[%s] Running... ", mp.current_process().name) while True: - time.sleep(float(TS) - (time.time() % float(TS))) - timestamp = time.time() - ipmiout = self.run_cmd(cmd) - sens_dict = self.parse_cmd_output(ipmiout) - for k, v in sens_dict.items(): - mqtt_str = str(v[0]) - mqtt_str += (";%.3f" % (math.floor(timestamp * 100) / 100)) - mqtt_tpc = self.mqtt_topic - mqtt_tpc += '/units/' + (v[1]).replace(' ', '_').replace('+', '_').replace('#', '_').replace('/', '_') - mqtt_tpc += '/' + (k).replace(' ', '_').replace('+', '_').replace('#', '_').replace('/', '_') - logger.debug("[%s] Topic: %s", mp.current_process().name, mqtt_tpc) - logger.debug("[%s] Payload: %s", mp.current_process().name, mqtt_str) - try: - self.client.publish(mqtt_tpc, payload=str(mqtt_str), qos=0, retain=False) - except Exception: - logger.exception("[%s] Exception in MQTT publish: ", mp.current_process().name) - continue + if not self.terminate_event: + time.sleep(float(TS) - (time.time() % float(TS))) + timestamp = time.time() + ipmiout = self.run_cmd(cmd) + sens_dict = self.parse_cmd_output(ipmiout) + for k, v in sens_dict.items(): + mqtt_str = str(v[0]) + mqtt_str += (";%.3f" % (math.floor(timestamp * 100) / 100)) + mqtt_tpc = self.mqtt_topic + mqtt_tpc += '/units/' + (v[1]).replace(' ', '_').replace('+', '_').replace('#', '_').replace('/', '_') + mqtt_tpc += '/' + (k).replace(' ', '_').replace('+', '_').replace('#', '_').replace('/', '_') + logger.debug("[%s] Topic: %s", mp.current_process().name, mqtt_tpc) + logger.debug("[%s] Payload: %s", mp.current_process().name, mqtt_str) + try: + self.client.publish(mqtt_tpc, payload=str(mqtt_str), qos=0, retain=False) + except Exception: + logger.exception("[%s] Exception in MQTT publish: ", mp.current_process().name) + continue + else: + logger.info("[%s] Terminating...", mp.current_process().name) + return def on_connect(self, client, userdata, flags, rc): """MQTT connection callback""" @@ -235,6 +244,18 @@ def on_connect(self, client, userdata, flags, rc): else: logger.info("[%s] Connected with result code: %s", mp.current_process().name, str(rc)) + def cleanup(self): + """Clean up resources""" + self.terminate_event = True + if self.client: + self.client.loop_stop() + self.client.disconnect() + if self.process and self.process.poll() is None: + try: + self.process.terminate() + except Exception: + pass + def get_ipmi_hosts(conf_file, username, passw): """ @@ -261,14 +282,51 @@ def get_ipmi_hosts(conf_file, username, passw): return ipmi_db -def worker(hostinfo): +def thread_worker(hostinfo): """ - Worker process code + Thread worker code """ daemon = IpmiPub(hostinfo, tool_path='ipmitool', mqtt_base_topic=MQTT_TOPIC) return daemon.run() +def process_worker(hostinfo_group): + """ + Process worker that manages multiple threads + """ + + thread_pool = ThreadPool(len(hostinfo_group)) + + daemons = [] + + for hostinfo in hostinfo_group: + daemon = IpmiPub(hostinfo, tool_path='ipmitool', mqtt_base_topic=MQTT_TOPIC) + daemons.append(daemon) + + def handle_signal(signum, frame): + logger.info(f"[{mp.current_process().name}] Received signal {signum}, cleaning up...") + for daemon in daemons: + daemon.cleanup() + thread_pool.close() + thread_pool.join() + sys.exit(0) + + signal.signal(signal.SIGTERM, handle_signal) + signal.signal(signal.SIGINT, handle_signal) + + try: + thread_pool.map(lambda daemon: daemon.run(), daemons) + thread_pool.close() + thread_pool.join() + except Exception as e: + logger.exception(f"[{mp.current_process().name}] Exception in thread pool: {str(e)}") + for daemon in daemons: + daemon.cleanup() + thread_pool.close() + thread_pool.join() + raise + + def kill_child_processes(signum, frame): """ Handle sigterm @@ -282,6 +340,12 @@ def kill_child_processes(signum, frame): sys.exit(0) +def split_list(lst, n): + """Split list into n chunks of approximately equal size""" + chunk_size = max(1, len(lst) // n) + return [lst[i:i + chunk_size] for i in range(0, len(lst), chunk_size)] + + if __name__ == '__main__': config = configparser.RawConfigParser() config.read('ipmi_pub.conf') @@ -291,7 +355,7 @@ def kill_child_processes(signum, frame): MQTT_USER = config.get('MQTT', 'MQTT_USER') MQTT_PASSWORD = config.get('MQTT', 'MQTT_PASSWORD') IPMI_SENS_TAGS = config.get('IPMI', 'IPMI_SENS_TAGS').split(',') - IPMI_SENS_TAGS = [(item).strip() for item in IPMI_SENS_TAGS] + IPMI_SENS_TAGS = [(item).strip() for item in IPMI_SENS_TAGS] IPMI_OPTIONS = config.get('IPMI', 'IPMI_OPTIONS') IPMI_RENAME_LABEL = json.loads(config.get('IPMI', 'IPMI_RENAME_LABEL')) TS = config.getfloat('Daemon', 'TS') @@ -301,6 +365,7 @@ def kill_child_processes(signum, frame): BMCIP_FILENAME = config.get('Daemon', 'BMCIP_FILENAME') BMC_USERNAME = config.get('Daemon', 'BMC_USERNAME') BMC_PASSWORD = config.get('Daemon', 'BMC_PASSWORD') + THREADS_PER_PROCESS = config.getint('Daemon', 'THREADS_PER_PROCESS', fallback=5) parser = argparse.ArgumentParser() parser.add_argument("runmode", choices=["run", "start", "stop", "restart"], help="Run mode") @@ -318,6 +383,7 @@ def kill_child_processes(signum, frame): parser.add_argument("-r", help="MQTT password") parser.add_argument("-o", help="Additional options for the IPMI command") parser.add_argument("-n", help="Rename IPMI labels (dictionary)") + parser.add_argument("-T", help="Threads per process", type=int) args = parser.parse_args() @@ -349,10 +415,14 @@ def kill_child_processes(signum, frame): IPMI_OPTIONS = args.o if args.n: IPMI_RENAME_LABEL = args.n + if args.T: + THREADS_PER_PROCESS = args.T logger = logging.getLogger("root") - handler = ConcurrentRotatingFileHandler(LOGFILE, mode='a', maxBytes=LOGFILE_SIZE_B, backupCount=BACKUP_COUNT) - log_formatter = logging.Formatter(fmt='%(levelname)s - %(asctime)s - %(name)s - %(message)s', datefmt='%d/%m/%Y %H:%M:%S') + handler = ConcurrentRotatingFileHandler(LOGFILE, mode='a', maxBytes=LOGFILE_SIZE_B, + backupCount=BACKUP_COUNT) + log_formatter = logging.Formatter(fmt='%(levelname)s - %(asctime)s - %(name)s - %(message)s', + datefmt='%d/%m/%Y %H:%M:%S') handler.setFormatter(log_formatter) logger.addHandler(handler) logger.setLevel(LOG_LEVEL) @@ -366,14 +436,12 @@ def kill_child_processes(signum, frame): daemon = Daemon(PID_FILENAME) - if args.runmode == 'stop': + if args.runmode == 'stop': print("Terminating daemon...") daemon.stop() sys.exit(0) elif args.runmode in ['run', 'start', 'restart']: print("Init workers") - original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) - original_sigterm_handler = signal.signal(signal.SIGTERM, kill_child_processes) if args.runmode == 'start': print("Daemonize..") @@ -381,16 +449,27 @@ def kill_child_processes(signum, frame): elif args.runmode == 'restart': print("Restarting Daemon..") daemon.restart() - else: - pass - pool = mp.Pool(len(ipmi_hosts)) - signal.signal(signal.SIGINT, original_sigint_handler) + # Group hosts for process/thread allocation + host_groups = [] + if THREADS_PER_PROCESS > 1: + # Calculate optimal number of processes based on hosts and threads + num_processes = max(1, len(ipmi_hosts) // THREADS_PER_PROCESS + + (1 if len(ipmi_hosts) % THREADS_PER_PROCESS else 0)) + host_groups = split_list(ipmi_hosts, num_processes) + logger.info(f"Using {num_processes} processes with up to {THREADS_PER_PROCESS} threads each " + f"for {len(ipmi_hosts)} hosts") + pool = mp.Pool(num_processes) + else: + # Fallback to original behavior - one process per host + host_groups = [[host] for host in ipmi_hosts] + logger.info(f"Using {len(ipmi_hosts)} processes with 1 thread each") + pool = mp.Pool(len(ipmi_hosts)) print("Starting jobs...") i = 1 - for hostinfo in ipmi_hosts: - pool.apply_async(worker, args=(hostinfo,)) + for host_group in host_groups: + pool.apply_async(process_worker, args=(host_group,)) if not (i % SLOWED_START_GROUP_SIZE): time.sleep(SLOWED_START_INTERVAL) i += 1 From bdb2fba0502cb88a73d82c0419e4c5c2d28cd4bb Mon Sep 17 00:00:00 2001 From: Francesco Beneventi Date: Tue, 29 Apr 2025 00:33:53 +0200 Subject: [PATCH 2/6] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 83e98a3..1d103e3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ *.log *.log.* *.bak +hosts_file +ipmi_pub.conf From 8e4133518c838546a8bb8ba1968019a14984b8dd Mon Sep 17 00:00:00 2001 From: Francesco Beneventi Date: Tue, 29 Apr 2025 00:40:17 +0200 Subject: [PATCH 3/6] Update README for thread-based parallelism support --- README.md | 14 +++++++++++++- example_ipmi_pub.conf | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 280f4f5..ae92f2d 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ Entries of the `.conf` file to be defined for this plugin: - **BMCIP_FILENAME**: The file containing the list of IPs and hostnames of the nodes to be monitored. - **BMC_USERNAME**: Username of the BMC user. - **BMC_PASSWORD**: Password of the BMC user. +- **THREADS_PER_PROCESS**: Number of threads per process for hybrid process/thread parallelism (default: 5). Setting to 1 will use the original process-only model. ### BMC IP file @@ -97,7 +98,7 @@ cat /etc/hosts | grep '\-bmc' | awk '{print $1 " " $3}' | tee bmc_ip_file ``` usage: ipmi_pub.py [-h] [-b B] [-p P] [-t T] [-s S] [-x X] [-l L] [-L L] - [-f F] [-U U] [-P P] [-m M] [-r R] [-o O] [-n N] + [-f F] [-U U] [-P P] [-m M] [-r R] [-o O] [-n N] [-T T] {run,start,stop,restart} positional arguments: @@ -119,6 +120,7 @@ optional arguments: -r R MQTT password -o O Additional options for the IPMI command -n N Rename IPMI labels (dictionary) + -T T Threads per process ``` ## Run @@ -129,6 +131,16 @@ Execute as: python ipmi_pub.py -U -P -f run ``` +### Thread-based parallelism + +The script now supports hybrid process/thread parallelism to optimize resource usage when monitoring many servers: + +```bash +python ipmi_pub.py -U -P -f -T 10 run +``` + +This will create process groups, each running up to 10 threads to monitor servers. This approach is more resource-efficient than the default process-only model when dealing with large numbers of servers. + ## Systemd This script is intended to be used as a service under systemd. SIGINT should be used as the signal to cleanly stop/kill the running script. diff --git a/example_ipmi_pub.conf b/example_ipmi_pub.conf index c1bacda..beb4dbd 100644 --- a/example_ipmi_pub.conf +++ b/example_ipmi_pub.conf @@ -19,5 +19,6 @@ PID_FILENAME = ipmi_pub.pid BMCIP_FILENAME = hosts_file BMC_USERNAME = BMC_PASSWORD = +THREADS_PER_PROCESS = 4 From 902547e82373da22902b1191bad4f85c5d00ef65 Mon Sep 17 00:00:00 2001 From: Francesco Beneventi Date: Tue, 6 May 2025 11:55:58 +0200 Subject: [PATCH 4/6] Add timeout configuration and improve argument parsing --- ipmi_pub.py | 68 +++++++++++++++-------------------------------------- 1 file changed, 19 insertions(+), 49 deletions(-) diff --git a/ipmi_pub.py b/ipmi_pub.py index dbdc8fc..cdd86e5 100644 --- a/ipmi_pub.py +++ b/ipmi_pub.py @@ -286,7 +286,7 @@ def thread_worker(hostinfo): """ Thread worker code """ - daemon = IpmiPub(hostinfo, tool_path='ipmitool', mqtt_base_topic=MQTT_TOPIC) + daemon = IpmiPub(hostinfo, tool_path='ipmitool', mqtt_base_topic=MQTT_TOPIC, timeout=TIMEOUT) return daemon.run() @@ -300,7 +300,7 @@ def process_worker(hostinfo_group): daemons = [] for hostinfo in hostinfo_group: - daemon = IpmiPub(hostinfo, tool_path='ipmitool', mqtt_base_topic=MQTT_TOPIC) + daemon = IpmiPub(hostinfo, tool_path='ipmitool', mqtt_base_topic=MQTT_TOPIC, timeout=TIMEOUT) daemons.append(daemon) def handle_signal(signum, frame): @@ -359,6 +359,7 @@ def split_list(lst, n): IPMI_OPTIONS = config.get('IPMI', 'IPMI_OPTIONS') IPMI_RENAME_LABEL = json.loads(config.get('IPMI', 'IPMI_RENAME_LABEL')) TS = config.getfloat('Daemon', 'TS') + TIMEOUT = config.get('Daemon', 'TIMEOUT', fallback="5") LOGFILE = config.get('Daemon', 'LOG_FILENAME') LOG_LEVEL = config.get('Daemon', 'LOG_LEVEL') PID_FILENAME = config.get('Daemon', 'PID_FILENAME') @@ -369,55 +370,24 @@ def split_list(lst, n): parser = argparse.ArgumentParser() parser.add_argument("runmode", choices=["run", "start", "stop", "restart"], help="Run mode") - parser.add_argument("-b", help="IP address of the MQTT broker") - parser.add_argument("-p", help="Port of the MQTT broker") - parser.add_argument("-t", help="MQTT topic") - parser.add_argument("-s", help="Sampling time (seconds)") - parser.add_argument("-x", help="pid filename") - parser.add_argument("-l", help="log filename") - parser.add_argument("-L", help="log level") - parser.add_argument("-f", help="BMC ip adresses filename") - parser.add_argument("-U", help="BMC username") - parser.add_argument("-P", help="BMC password") - parser.add_argument("-m", help="MQTT username") - parser.add_argument("-r", help="MQTT password") - parser.add_argument("-o", help="Additional options for the IPMI command") - parser.add_argument("-n", help="Rename IPMI labels (dictionary)") - parser.add_argument("-T", help="Threads per process", type=int) - + parser.add_argument("-b", dest="MQTT_BROKER", help="IP address of the MQTT broker") + parser.add_argument("-p", dest="MQTT_PORT", help="Port of the MQTT broker") + parser.add_argument("-t", dest="MQTT_TOPIC", help="MQTT topic") + parser.add_argument("-s", dest="TS", type=float, help="Sampling time (seconds)") + parser.add_argument("-x", dest="PID_FILENAME", help="pid filename") + parser.add_argument("-l", dest="LOGFILE", help="log filename") + parser.add_argument("-L", dest="LOG_LEVEL", help="log level") + parser.add_argument("-f", dest="BMCIP_FILENAME", help="BMC ip adresses filename") + parser.add_argument("-U", dest="BMC_USERNAME", help="BMC username") + parser.add_argument("-P", dest="BMC_PASSWORD", help="BMC password") + parser.add_argument("-m", dest="MQTT_USER", help="MQTT username") + parser.add_argument("-r", dest="MQTT_PASSWORD", help="MQTT password") + parser.add_argument("-o", dest="IPMI_OPTIONS", help="Additional options for the IPMI command") + parser.add_argument("-n", dest="IPMI_RENAME_LABEL", help="Rename IPMI labels (JSON dictionary string)") + parser.add_argument("-T", dest="THREADS_PER_PROCESS", type=int, help="Threads per process") + args = parser.parse_args() - if args.b: - MQTT_BROKER = args.b - if args.p: - MQTT_PORT = args.p - if args.t: - MQTT_TOPIC = args.t - if args.m: - MQTT_USER = args.m - if args.r: - MQTT_PASSWORD = args.r - if args.s: - TS = float(args.s) - if args.x: - PID_FILENAME = args.x - if args.l: - LOGFILE = args.l - if args.L: - LOG_LEVEL = args.L - if args.f: - BMCIP_FILENAME = args.f - if args.U: - BMC_USERNAME = args.U - if args.P: - BMC_PASSWORD = args.P - if args.o: - IPMI_OPTIONS = args.o - if args.n: - IPMI_RENAME_LABEL = args.n - if args.T: - THREADS_PER_PROCESS = args.T - logger = logging.getLogger("root") handler = ConcurrentRotatingFileHandler(LOGFILE, mode='a', maxBytes=LOGFILE_SIZE_B, backupCount=BACKUP_COUNT) From 0947035e28fbca763b5e4b73eda76195d704b771 Mon Sep 17 00:00:00 2001 From: Francesco Beneventi Date: Tue, 6 May 2025 12:11:18 +0200 Subject: [PATCH 5/6] fix default timeout value to 10 seconds --- ipmi_pub.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ipmi_pub.py b/ipmi_pub.py index cdd86e5..7a1d3f8 100644 --- a/ipmi_pub.py +++ b/ipmi_pub.py @@ -134,6 +134,8 @@ def run_cmd(self, cmd): if self.process.returncode != 0: logger.error("[%s] Error in run_cmd(): %s - cmd: %s - ret %s", mp.current_process().name, output, cmd, self.process.returncode) + if self.process.returncode == 124: + logger.error("[%s] Command timed out, current timeout: %s", mp.current_process().name, self.timeout) if self.terminate_event: return output except Exception: @@ -359,7 +361,7 @@ def split_list(lst, n): IPMI_OPTIONS = config.get('IPMI', 'IPMI_OPTIONS') IPMI_RENAME_LABEL = json.loads(config.get('IPMI', 'IPMI_RENAME_LABEL')) TS = config.getfloat('Daemon', 'TS') - TIMEOUT = config.get('Daemon', 'TIMEOUT', fallback="5") + TIMEOUT = config.get('Daemon', 'TIMEOUT', fallback="10") LOGFILE = config.get('Daemon', 'LOG_FILENAME') LOG_LEVEL = config.get('Daemon', 'LOG_LEVEL') PID_FILENAME = config.get('Daemon', 'PID_FILENAME') From b880f644888d455672e0d716b19738d8f7bac0d7 Mon Sep 17 00:00:00 2001 From: Francesco Beneventi Date: Tue, 6 May 2025 12:16:43 +0200 Subject: [PATCH 6/6] Fix logger name --- ipmi_pub.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipmi_pub.py b/ipmi_pub.py index 7a1d3f8..294afdf 100644 --- a/ipmi_pub.py +++ b/ipmi_pub.py @@ -390,7 +390,7 @@ def split_list(lst, n): args = parser.parse_args() - logger = logging.getLogger("root") + logger = logging.getLogger("examon") handler = ConcurrentRotatingFileHandler(LOGFILE, mode='a', maxBytes=LOGFILE_SIZE_B, backupCount=BACKUP_COUNT) log_formatter = logging.Formatter(fmt='%(levelname)s - %(asctime)s - %(name)s - %(message)s',