From ab89ca56c4557ce87e76aa41ee54bed333d9ca41 Mon Sep 17 00:00:00 2001 From: Michal Minar Date: Thu, 12 Sep 2013 12:14:33 +0200 Subject: logging improvements and fix Reduced length of tracing messages written to log by rendering just the first item of list, dict or set instead of whole argument. This will also improve execution time when running in debug mode. Fixed logging decorator of software job manager which previously rendered informations from uninteresting frame. --- src/python/lmi/providers/cmpi_logging.py | 51 +++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 14 deletions(-) (limited to 'src/python') diff --git a/src/python/lmi/providers/cmpi_logging.py b/src/python/lmi/providers/cmpi_logging.py index 1eb9e3a..ca24601 100644 --- a/src/python/lmi/providers/cmpi_logging.py +++ b/src/python/lmi/providers/cmpi_logging.py @@ -184,6 +184,41 @@ class CMPILogger(logging.getLoggerClass()): logging.setLoggerClass(CMPILogger) +def render_value(val): + """ + When logging values, we want to avoid excessively long messages caused + by rendering argument values like lists, dictionaries etc. + Let's shorten these iterable objects to just one or few items. + + :param val: Any value for rendering. + :returns: Representation string of value, possibly shortened. + :rtype: string + """ + if isinstance(val, list): + if len(val) < 2: + return repr(val) + else: + return "[%s, ... (%d more items)]" % ( + render_value(val[0]), len(val) - 1) + elif isinstance(val, dict): + if len(val) < 2: + return repr(val) + else: + key = next(iter(val)) + return '{%s: %s, ... (%d more items)}' % ( + render_value(key), render_value(val[key]), len(val) - 1) + elif isinstance(val, set): + if len(val) < 2: + return repr(val) + else: + return '{%s, ... (%d more items)}' % ( + render_value(val[0]), len(val) - 1) + elif isinstance(val, tuple): + return "(%s%s)" % ( + ", ".join(render_value(i) for i in val), + ", " if len(val) < 2 else '') + return repr(val) + def trace_function_or_method(is_method=False, frame_level=1): """ Factory for function and method decorators. Generated decorators @@ -211,18 +246,6 @@ def trace_function_or_method(is_method=False, frame_level=1): if not inspect.ismethod(func) and not inspect.isfunction(func): raise TypeError("func must be a function") - def _print_value(val): - """ - Used here for printing function arguments. Shortens the output - string, if that would be too long. - """ - if isinstance(val, list): - if len(val) < 2: - return str(val) - else: - return "[%s, ...]" % _print_value(val[0]) - return str(val) - module = func.__module__.split('.')[-1] frm = inspect.currentframe() for _ in range(frame_level): @@ -250,8 +273,8 @@ def trace_function_or_method(is_method=False, frame_level=1): "lineno" : lineno, "action" : "entering", "args" : ", ".join(chain( - (_print_value(a) for a in args), - ( "%s=%s"%(k, _print_value(v)) + (render_value(a) for a in args), + ( "%s=%s"%(k, render_value(v)) for k, v in kwargs.items()))) }) -- cgit From e4d72c3b72f2f363ec556c5f0ec6d94bd4f038ed Mon Sep 17 00:00:00 2001 From: Radek Novacek Date: Wed, 18 Sep 2013 08:00:08 +0200 Subject: Introduce toplevel openlmi config file Toplevel openlmi configuration file (/etc/openlmi/openlmi.conf) now contains common configuration options for all providers. Configuration for each provider could be overriden in provider-specific config (/etc/openlmi/$provider/$provider.conf). This patch also modify config file handling in python providers to include this config file. There is also support for C providers (in libopenlmicommon) for reading these config files and providing default configuration options. --- src/python/lmi/base/BaseConfiguration.py | 40 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'src/python') diff --git a/src/python/lmi/base/BaseConfiguration.py b/src/python/lmi/base/BaseConfiguration.py index 8790acf..275fc0f 100644 --- a/src/python/lmi/base/BaseConfiguration.py +++ b/src/python/lmi/base/BaseConfiguration.py @@ -72,9 +72,12 @@ class BaseConfiguration(Singleton): There should be only one instance of this class. """ - CONFIG_DIRECTORY_TEMPLATE = '/etc/openlmi/%(provider_prefix)s/' - CONFIG_FILE_PATH_TEMPLATE = \ - CONFIG_DIRECTORY_TEMPLATE + '%(provider_prefix)s.conf' + CONFIG_DIRECTORY_TEMPLATE_TOPLEVEL = '/etc/openlmi/' + CONFIG_DIRECTORY_TEMPLATE_PROVIDER = '/etc/openlmi/%(provider_prefix)s/' + CONFIG_FILE_PATH_TEMPLATE_TOPLEVEL = \ + CONFIG_DIRECTORY_TEMPLATE_TOPLEVEL + 'openlmi.conf' + CONFIG_FILE_PATH_TEMPLATE_PROVIDER = \ + CONFIG_DIRECTORY_TEMPLATE_PROVIDER + '%(provider_prefix)s.conf' PERSISTENT_PATH_TEMPLATE = '/var/lib/openlmi-%(provider_prefix)s/' SETTINGS_DIR = 'settings/' @@ -106,11 +109,17 @@ class BaseConfiguration(Singleton): return cls.DEFAULT_OPTIONS @classmethod - def config_directory(cls): - """ Base directory with configuration settings. """ - return cls.CONFIG_DIRECTORY_TEMPLATE % { + def config_directory_toplevel(cls): + """ Base directory with toplevel configuration settings. """ + return cls.CONFIG_DIRECTORY_TEMPLATE_TOPLEVEL + + @classmethod + def config_directory_provider(cls): + """ Base directory with provider specific configuration settings. """ + return cls.CONFIG_DIRECTORY_TEMPLATE_PROVIDER % { 'provider_prefix' : cls.provider_prefix() } + @classmethod def persistent_path(cls): """ Base directory with persistent settings. """ @@ -118,11 +127,17 @@ class BaseConfiguration(Singleton): 'provider_prefix': cls.provider_prefix() } @classmethod - def config_file_path(cls): - """ File path of configuration file. """ - return cls.CONFIG_FILE_PATH_TEMPLATE % { + def config_file_path_toplevel(cls): + """ File path of toplevel configuration file. """ + return cls.CONFIG_FILE_PATH_TEMPLATE_TOPLEVEL + + @classmethod + def config_file_path_provider(cls): + """ File path of provider specific configuration file. """ + return cls.CONFIG_FILE_PATH_TEMPLATE_PROVIDER % { 'provider_prefix' : cls.provider_prefix() } + @classmethod def mandatory_sections(cls): """ @@ -163,10 +178,11 @@ class BaseConfiguration(Singleton): def load(self): """ - Load configuration from config file path. - The file does not need to exist. + Load configuration from config files. Provider specific options + overrides toplevel openlmi configuration. + The files do not need to exist. """ - self.config.read(self.config_file_path()) + self.config.read([self.config_file_path_toplevel(), self.config_file_path_provider()]) for section in self.mandatory_sections(): if not self.config.has_section(section): self.config.add_section(section) -- cgit From 95e9bfccc44aaae4339c76078ced41e5cbfb3ef8 Mon Sep 17 00:00:00 2001 From: Radek Novacek Date: Tue, 17 Sep 2013 13:26:36 +0200 Subject: Priority of traces should be lower than priority of DEBUG log messages --- src/python/lmi/providers/cmpi_logging.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/python') diff --git a/src/python/lmi/providers/cmpi_logging.py b/src/python/lmi/providers/cmpi_logging.py index ca24601..4d780df 100644 --- a/src/python/lmi/providers/cmpi_logging.py +++ b/src/python/lmi/providers/cmpi_logging.py @@ -30,9 +30,9 @@ import os import sys # Custom logging levels -TRACE_WARNING = logging.INFO - 1 -TRACE_INFO = logging.INFO - 2 -TRACE_VERBOSE = logging.DEBUG +TRACE_WARNING = logging.DEBUG - 1 +TRACE_INFO = logging.DEBUG - 2 +TRACE_VERBOSE = logging.DEBUG - 3 # Mapping from level name to its number LOGGING_LEVELS = { @@ -41,10 +41,10 @@ LOGGING_LEVELS = { "warning" : logging.WARNING, "warn" : logging.WARNING, "info" : logging.INFO, + "debug" : logging.DEBUG, "trace_warning" : TRACE_WARNING, "trace_info" : TRACE_INFO, - "trace_verbose" : TRACE_VERBOSE, - "debug" : logging.DEBUG + "trace_verbose" : TRACE_VERBOSE } DEFAULT_LOGGING_CONFIG = { @@ -130,11 +130,13 @@ class CMPILogHandler(logging.Handler): self.cmpi_logger.log_warn(msg) elif record.levelno >= logging.INFO: self.cmpi_logger.log_info(msg) + elif record.levelno >= logging.DEBUG: + self.cmpi_logger.log_debug(record.filename, msg) elif record.levelno >= TRACE_WARNING: self.cmpi_logger.trace_warn(record.filename, msg) elif record.levelno >= TRACE_INFO: self.cmpi_logger.trace_info(record.filename, msg) - elif record.levelno >= logging.DEBUG: + elif record.levelno >= TRACE_VERBOSE: self.cmpi_logger.trace_verbose(record.filename, msg) class CMPILogger(logging.getLoggerClass()): -- cgit From dac5442bb5a5b7828ac36206d6c51b305576bc35 Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Thu, 19 Sep 2013 14:52:41 +0200 Subject: Fixed logging of debug messages. log_debug() takes only 'msg' as parameter. --- src/python/lmi/providers/cmpi_logging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/lmi/providers/cmpi_logging.py b/src/python/lmi/providers/cmpi_logging.py index 4d780df..c1e29c9 100644 --- a/src/python/lmi/providers/cmpi_logging.py +++ b/src/python/lmi/providers/cmpi_logging.py @@ -131,7 +131,7 @@ class CMPILogHandler(logging.Handler): elif record.levelno >= logging.INFO: self.cmpi_logger.log_info(msg) elif record.levelno >= logging.DEBUG: - self.cmpi_logger.log_debug(record.filename, msg) + self.cmpi_logger.log_debug(msg) elif record.levelno >= TRACE_WARNING: self.cmpi_logger.trace_warn(record.filename, msg) elif record.levelno >= TRACE_INFO: -- cgit