From a51aad8d600a8b0bb662aefb65ab0e8266551ab0 Mon Sep 17 00:00:00 2001 From: Julien Fortin Date: Wed, 3 May 2023 16:19:57 +0200 Subject: [PATCH] add support for systemd logging New CLI option: --systemd will enabled journalctl logging when ifupdown2 is run in a systemd context Signed-off-by: Julien Fortin --- debian/control | 2 +- ifupdown2/__main__.py | 4 ++++ ifupdown2/ifupdown/argv.py | 2 ++ ifupdown2/lib/log.py | 29 ++++++++++++++++++++++++----- ifupdown2/sbin/start-networking | 10 +++++----- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/debian/control b/debian/control index 236ae57..ed87b39 100644 --- a/debian/control +++ b/debian/control @@ -17,7 +17,7 @@ Architecture: all Provides: ifupdown Conflicts: ifupdown Replaces: ifupdown -Depends: ${python3:Depends}, ${misc:Depends}, iproute2, python3-six, python3-setuptools +Depends: ${python3:Depends}, ${misc:Depends}, iproute2, python3-six, python3-setuptools, python3-systemd Suggests: isc-dhcp-client, bridge-utils, ethtool, python3-gvgen, python3-mako Description: Network Interface Management tool similar to ifupdown ifupdown2 is ifupdown re-written in Python. It replaces ifupdown and provides diff --git a/ifupdown2/__main__.py b/ifupdown2/__main__.py index d720529..b91617c 100755 --- a/ifupdown2/__main__.py +++ b/ifupdown2/__main__.py @@ -108,6 +108,10 @@ def stand_alone(): except NetlinkListenerWithCacheErrorNotInitialized: status = Status.Client.STATUS_NLERROR LogManager.get_instance().write("exit status %s" % status) + + if status != 0: + LogManager.get_instance().report_error_to_systemd() + return status diff --git a/ifupdown2/ifupdown/argv.py b/ifupdown2/ifupdown/argv.py index 47c0d63..cee958a 100644 --- a/ifupdown2/ifupdown/argv.py +++ b/ifupdown2/ifupdown/argv.py @@ -151,6 +151,7 @@ class Parse: """ common arg parser for ifup and ifdown """ argparser.add_argument('-f', '--force', dest='force', action='store_true', help='force run all operations') argparser.add_argument('-l', '--syslog', dest='syslog', action='store_true') + argparser.add_argument('--systemd', dest='systemd', action='store_true', help="enable journalctl logging") group = argparser.add_mutually_exclusive_group(required=False) group.add_argument('-n', '--no-act', dest='noact', action='store_true', help="print out what would happen, but don't do it") @@ -231,6 +232,7 @@ class Parse: 'Useful when your state file is corrupted or you want down to use the latest ' 'from the interfaces file') argparser.add_argument('-l', '--syslog', dest='syslog', action='store_true') + argparser.add_argument('--systemd', dest='systemd', action='store_true', help="enable journalctl logging") argparser.add_argument('-f', '--force', dest='force', action='store_true', help='force run all operations') argparser.add_argument('-s', '--syntax-check', dest='syntaxcheck', action='store_true', help='Only run the interfaces file parser') diff --git a/ifupdown2/lib/log.py b/ifupdown2/lib/log.py index 5d83afe..6a6f3e6 100644 --- a/ifupdown2/lib/log.py +++ b/ifupdown2/lib/log.py @@ -29,6 +29,8 @@ import logging import logging.handlers from datetime import date, datetime +from systemd.journal import JournalHandler + try: from ifupdown2.ifupdown.utils import utils @@ -83,10 +85,13 @@ class LogManager: self.__root_logger = logging.getLogger() self.__root_logger.name = self.LOGGER_NAME + self.new_dir_path = None + self.__debug_handler = None self.__socket_handler = None self.__syslog_handler = None self.__console_handler = None + self.__journald_handler = None self.daemon = None @@ -172,16 +177,16 @@ class LogManager: # create new log directory to store eni and debug logs # format: network_config_ifupdown2_1_Aug-17-2021_23:42:00.000000 - new_dir_path = "%s/%s%s_%s" % ( + self.new_dir_path = "%s/%s%s_%s" % ( self.LOGGING_DIRECTORY, self.LOGGING_DIRECTORY_PREFIX, last_id + 1, "%s_%s" % (date.today().strftime("%b-%d-%Y"), str(datetime.now()).split(" ", 1)[1]) ) - self.__create_dir(new_dir_path) + self.__create_dir(self.new_dir_path) # start logging in the new directory - self.__debug_handler = logging.FileHandler("%s/ifupdown2.debug.log" % new_dir_path, mode="w+") + self.__debug_handler = logging.FileHandler("%s/ifupdown2.debug.log" % self.new_dir_path, mode="w+") self.__debug_handler.setFormatter(logging.Formatter(self.__debug_fmt)) self.__debug_handler.setLevel(logging.DEBUG) @@ -191,9 +196,9 @@ class LogManager: self.__root_logger.debug("persistent debugging is initialized") # cp ENI and ENI.d in the log directory - shutil.copy2("/etc/network/interfaces", new_dir_path) + shutil.copy2("/etc/network/interfaces", self.new_dir_path) try: - shutil.copytree("/etc/network/interfaces.d/", "%s/interfaces.d" % new_dir_path) + shutil.copytree("/etc/network/interfaces.d/", "%s/interfaces.d" % self.new_dir_path) except Exception: pass @@ -250,6 +255,12 @@ class LogManager: """ Remove console handler from root logger """ self.__root_logger.removeHandler(self.__console_handler) + def enable_systemd(self): + """ Add journalctl handler to root logger """ + self.__journald_handler = JournalHandler() + self.__journald_handler.setFormatter(logging.Formatter(self.__fmt)) + self.__root_logger.addHandler(self.__journald_handler) + def enable_syslog(self): """ Add syslog handler to root logger """ if self.__syslog_handler and self.__syslog_handler not in self.__root_logger.handlers: @@ -322,6 +333,9 @@ class LogManager: def start_standalone_logging(self, args): self.__root_logger.name = self.LOGGER_NAME + if hasattr(args, "systemd") and args.systemd: + self.enable_systemd() + if hasattr(args, "syslog") and args.syslog: self.enable_syslog() self.disable_console() @@ -360,3 +374,8 @@ class LogManager: def root_logger(self): return self.__root_logger + + def report_error_to_systemd(self): + if self.__journald_handler: + self.__journald_handler.setFormatter(logging.Formatter("%(message)s")) + self.__root_logger.error(">>> Full logs available in: %s <<<" % self.new_dir_path) diff --git a/ifupdown2/sbin/start-networking b/ifupdown2/sbin/start-networking index 2deb5e9..8f790a0 100755 --- a/ifupdown2/sbin/start-networking +++ b/ifupdown2/sbin/start-networking @@ -92,7 +92,7 @@ ifup_hotplug () { done) if [ -n "$ifaces" ] then - ifup $ifaces "$@" || true + ifup $ifaces "$@" --systemd || true fi fi } @@ -101,7 +101,7 @@ ifup_mgmt () { ifaces=$(ifquery --list --allow=mgmt 2>/dev/null) if [ -n "$ifaces" ]; then echo "bringing up mgmt class interfaces" - ifup --allow=mgmt + ifup --allow=mgmt --systemd fi } @@ -127,7 +127,7 @@ start) perfoptions=$(perf_options) echo ${NAME}':' "Configuring network interfaces" ifup_mgmt - ifup -a $EXTRA_ARGS $exclusions $perfoptions + ifup -a $EXTRA_ARGS $exclusions $perfoptions --systemd ifup_hotplug $HOTPLUG_ARGS $EXTRA_ARGS $exclusions ;; stop) @@ -148,7 +148,7 @@ stop) exclusions=$(process_exclusions) echo ${NAME}':' "Deconfiguring network interfaces" - ifdown -a $EXTRA_ARGS $exclusions + ifdown -a $EXTRA_ARGS $exclusions --systemd ;; reload) @@ -157,7 +157,7 @@ reload) exclusions=$(process_exclusions) echo ${NAME}':' "Reloading network interfaces configuration" - ifreload -a $EXTRA_ARGS $exclusions + ifreload -a $EXTRA_ARGS $exclusions --systemd ;; *)