From f6d0ee103d6cc1825efb478af1960636d018f283 Mon Sep 17 00:00:00 2001 From: Luis Eduardo Bonatti Date: Wed, 2 Apr 2025 15:05:40 -0300 Subject: [PATCH] Configure code to use log format from software.conf This commit stardandizes the log format to be fetched from the software.conf file, it also have a check to use a default one in case the log format is not present in the file which can happen in a 24.09 to 25.09 upgrade. PASS: Performed and upgrade from stx10 -> stx11 and verified the logs. PASS: Fresh install of stx11 and verified the logs. PASS: Check software.conf have logging_default_format_string key and value. Story: 2011357 Task: 51915 Change-Id: Ied360551c9fc59c0e4f474ed94d1ba4a64065bd3 Signed-off-by: Luis Eduardo Bonatti --- software/scripts/upgrade_utils.py | 46 +++++++++++++++++++++--- software/service-files/software.conf | 3 ++ software/software/config.py | 8 +++-- software/software/constants.py | 4 +++ software/software/software_agent.py | 4 +-- software/software/software_controller.py | 8 +++-- software/software/software_functions.py | 15 +++----- software/software/utilities/utils.py | 20 ++++++++--- 8 files changed, 81 insertions(+), 27 deletions(-) diff --git a/software/scripts/upgrade_utils.py b/software/scripts/upgrade_utils.py index d3727bb2..156147ff 100644 --- a/software/scripts/upgrade_utils.py +++ b/software/scripts/upgrade_utils.py @@ -1,11 +1,12 @@ # -# Copyright (c) 2023-2024 Wind River Systems, Inc. +# Copyright (c) 2023-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # # This is an utility module used by standalone USM upgrade scripts # that runs on the FROM-side context but using TO-side code base # + import configparser import json import logging @@ -17,10 +18,19 @@ import sys import time import yaml +from oslo_config import cfg + from keystoneauth1 import exceptions from keystoneauth1 import identity from keystoneauth1 import session +LOG = logging.getLogger('main_logger') +CONF = cfg.CONF + +logging_default_format_string = None +software_conf_mtime = 0 +software_conf = '/etc/software/software.conf' + def get_token_endpoint(config, service_type="platform"): """Returns an endpoint and a token for a service @@ -169,13 +179,18 @@ def get_system_info(sysinv_client): def configure_logging(filename, log_level=logging.INFO): + read_log_config() + my_exec = os.path.basename(sys.argv[0]) - log_format = ('%(asctime)s: ' + my_exec + '[%(process)s]: ' - '%(filename)s(%(lineno)s): %(levelname)s: %(message)s') - log_datefmt = "%FT%T" + log_format = logging_default_format_string + log_format = log_format.replace('%(exec)s', my_exec) + formatter = logging.Formatter(log_format, datefmt="%FT%T") - logging.basicConfig(filename=filename, format=log_format, level=log_level, datefmt=log_datefmt) + LOG.setLevel(log_level) + main_log_handler = logging.FileHandler(filename) + main_log_handler.setFormatter(formatter) + LOG.addHandler(main_log_handler) def get_platform_conf(key): @@ -222,6 +237,27 @@ def get_secret_data_yaml(name, namespace): return None +def read_log_config(): + global software_conf_mtime + global software_conf + + if software_conf_mtime == os.stat(software_conf).st_mtime: + # The file has not changed since it was last read + return + + global logging_default_format_string + + # TODO(lbonatti) Remove this default_format when logging_default_format_string is present in stx11, + # when this becomes the N release. + default_format = ('%(asctime)s.%(msecs)03d USM - %(exec)s [%(process)s:%(thread)d]: %(filename)s(%(lineno)s): ' + '%(levelname)s: %(message)s') + config = configparser.ConfigParser(interpolation=None) + + config.read(software_conf) + software_conf_mtime = os.stat(software_conf).st_mtime + logging_default_format_string = config.get("DEFAULT", "logging_default_format_string", fallback=default_format) + + def get_available_gib_in_vg(): """Get the free space for cgts-vg volume group returns: Free space in GiB diff --git a/software/service-files/software.conf b/software/service-files/software.conf index bc2da986..deb81a11 100644 --- a/software/service-files/software.conf +++ b/software/service-files/software.conf @@ -1,3 +1,6 @@ +[DEFAULT] +logging_default_format_string = %(asctime)s.%(msecs)03d USM - %(exec)s [%(process)s:%(thread)d]: %(filename)s(%(lineno)s): %(levelname)s: %(message)s + [runtime] controller_multicast = 239.1.1.3 agent_multicast = 239.1.1.4 diff --git a/software/software/config.py b/software/software/config.py index 6a0f04d3..b393e1da 100644 --- a/software/software/config.py +++ b/software/software/config.py @@ -1,5 +1,5 @@ """ -Copyright (c) 2023 Wind River Systems, Inc. +Copyright (c) 2023-2025 Wind River Systems, Inc. SPDX-License-Identifier: Apache-2.0 @@ -25,6 +25,7 @@ alt_postgresql_port = 0 mgmt_if = None nodetype = None package_feed = None +logging_default_format_string = None platform_conf_mtime = 0 software_conf_mtime = 0 software_conf = constants.SOFTWARE_CONFIG_FILE_LOCAL @@ -98,8 +99,9 @@ def read_config(): global agent_port global alt_postgresql_port global package_feed + global logging_default_format_string - config = configparser.ConfigParser(defaults) + config = configparser.ConfigParser(defaults, interpolation=None) config.read(software_conf) software_conf_mtime = os.stat(software_conf).st_mtime @@ -113,6 +115,8 @@ def read_config(): agent_port = config.getint('runtime', 'agent_port') alt_postgresql_port = config.getint('runtime', 'alt_postgresql_port') package_feed = config.get("runtime", "package_feed") + logging_default_format_string = config.get("DEFAULT", "logging_default_format_string", + fallback=constants.LOG_DEFAULT_FORMAT) # The platform.conf file has no section headers, which causes problems # for ConfigParser. So we'll fake it out. diff --git a/software/software/constants.py b/software/software/constants.py index dd3d43c6..2de55e18 100644 --- a/software/software/constants.py +++ b/software/software/constants.py @@ -231,3 +231,7 @@ MAX_OSTREE_DEPLOY_RETRIES = 5 # Precheck timeout PRECHECK_RESULT_VALID_PERIOD = 300 + +# Logging +LOG_DEFAULT_FORMAT = ('%(asctime)s.%(msecs)03d USM - %(exec)s [%(process)s:%(thread)d]: ' + '%(filename)s(%(lineno)s): %(levelname)s: %(message)s') diff --git a/software/software/software_agent.py b/software/software/software_agent.py index 2e4067db..3bd42e07 100644 --- a/software/software/software_agent.py +++ b/software/software/software_agent.py @@ -1033,10 +1033,10 @@ class PatchAgent(PatchService): def main(): global pa - configure_logging() - cfg.read_config() + configure_logging() + pa = PatchAgent() if os.path.isfile(constants.INSTALL_LOCAL_FLAG): pa.install_local = True diff --git a/software/software/software_controller.py b/software/software/software_controller.py index 9e4b7874..92ae8a2f 100644 --- a/software/software/software_controller.py +++ b/software/software/software_controller.py @@ -12,6 +12,7 @@ sys.modules['osprofiler'] = None import configparser import gc import json +import logging import os from packaging import version import re @@ -82,7 +83,6 @@ from software.software_functions import package_dir from software.software_functions import repo_dir from software.software_functions import root_scripts_dir from software.software_functions import SW_VERSION -from software.software_functions import LOG from software.software_functions import audit_log_info from software.software_functions import repo_root_dir from software.software_functions import is_deploy_state_in_sync @@ -118,6 +118,8 @@ import xml.etree.ElementTree as ET CONF = oslo_cfg.CONF +LOG = logging.getLogger('main_logger') + pidfile_path = "/var/run/patch_controller.pid" sc = None @@ -4871,10 +4873,10 @@ def main(): default_config_files=['/etc/software/software.conf', ] ) - configure_logging() - cfg.read_config() + configure_logging() + # daemon.pidlockfile.write_pid_to_pidfile(pidfile_path) global thread_death diff --git a/software/software/software_functions.py b/software/software/software_functions.py index 7fd68450..dc73facf 100644 --- a/software/software/software_functions.py +++ b/software/software/software_functions.py @@ -25,6 +25,7 @@ from lxml import etree as ElementTree from xml.dom import minidom import software.apt_utils as apt_utils +import software.config as cfg from software.db.api import get_instance from software.release_verify import verify_files from software.release_verify import cert_type_all @@ -84,11 +85,8 @@ def configure_logging(logtofile=True, level=logging.INFO): if logtofile: my_exec = os.path.basename(sys.argv[0]) - log_format = '%(asctime)s: ' \ - + my_exec + '[%(process)s:%(thread)d]: ' \ - + '%(filename)s(%(lineno)s): ' \ - + '%(levelname)s: %(message)s' - + log_format = cfg.logging_default_format_string + log_format = log_format.replace('%(exec)s', my_exec) formatter = logging.Formatter(log_format, datefmt="%FT%T") LOG.setLevel(level) @@ -96,16 +94,13 @@ def configure_logging(logtofile=True, level=logging.INFO): main_log_handler.setFormatter(formatter) LOG.addHandler(main_log_handler) - try: - os.chmod(logfile, 0o640) - except Exception: - pass - auditLOG.setLevel(level) api_log_handler = logging.FileHandler(apilogfile) api_log_handler.setFormatter(formatter) auditLOG.addHandler(api_log_handler) + try: + os.chmod(logfile, 0o640) os.chmod(apilogfile, 0o640) except Exception: pass diff --git a/software/software/utilities/utils.py b/software/software/utilities/utils.py index bb48c7b8..21c769e9 100644 --- a/software/software/utilities/utils.py +++ b/software/software/utilities/utils.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2024 Wind River Systems, Inc. +# Copyright (c) 2023-2025 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # @@ -10,6 +10,7 @@ import os import psycopg2 from psycopg2.extras import RealDictCursor import subprocess +import sys import tempfile import yaml @@ -20,6 +21,7 @@ from software.utilities.constants import PLATFORM_PATH from software.utilities.constants import KEYRING_PERMDIR from software.utilities import constants +import software.config as cfg LOG = logging.getLogger('main_logger') SOFTWARE_LOG_FILE = "/var/log/software.log" @@ -39,10 +41,18 @@ ACTION_ACTIVATE_ROLLBACK = "activate-rollback" def configure_logging(): - log_format = ('%(asctime)s: ' + __name__ + '[%(process)s]: ' - '%(filename)s(%(lineno)s): %(levelname)s: %(message)s') - log_datefmt = "%FT%T" - logging.basicConfig(filename=SOFTWARE_LOG_FILE, format=log_format, level=logging.INFO, datefmt=log_datefmt) + cfg.read_config() + + my_exec = os.path.basename(sys.argv[0]) + + log_format = cfg.logging_default_format_string + log_format = log_format.replace('%(exec)s', my_exec) + formatter = logging.Formatter(log_format, datefmt="%FT%T") + + LOG.setLevel(logging.INFO) + main_log_handler = logging.FileHandler(SOFTWARE_LOG_FILE) + main_log_handler.setFormatter(formatter) + LOG.addHandler(main_log_handler) def execute_migration_scripts(from_release, to_release, action, port=None,