Difference between revisions of "Enhanced-context-logger-oslo"
(→Blueprint Design for (enhanced-context-logger)) |
(→Proposed Design) |
||
Line 6: | Line 6: | ||
The idea is to introduce a placeholder for sub-contextual information. The logic would run based on the presence of such placeholder. The classes that would be enhanced in the process would be the '''openstack.common.log.ContextAdapter''' and '''openstack.common.log.ContextFormatter''' | The idea is to introduce a placeholder for sub-contextual information. The logic would run based on the presence of such placeholder. The classes that would be enhanced in the process would be the '''openstack.common.log.ContextAdapter''' and '''openstack.common.log.ContextFormatter''' | ||
− | ==== Proposed modification to the ContextAdapter ==== | + | ==== Proposed modification to the '''ContextAdapter''' ==== |
Add a placeholder named "sub_context" within the "extra", and if found unroll it into the "extra" like below: | Add a placeholder named "sub_context" within the "extra", and if found unroll it into the "extra" like below: | ||
Line 17: | Line 17: | ||
− | ==== Proposed modification to the ContextFormatter ==== | + | ==== Proposed modification to the '''ContextFormatter''' ==== |
self._fmt += " " + CONF.logging_debug_format_suffix | self._fmt += " " + CONF.logging_debug_format_suffix | ||
Line 24: | Line 24: | ||
'''for k in sub_context:''' | '''for k in sub_context:''' | ||
'''self._fmt += " [" + k + ":%(" + k + ")s]"''' | '''self._fmt += " [" + k + ":%(" + k + ")s]"''' | ||
+ | |||
+ | |||
+ | === Proposed usage of this enhanced logger === | ||
+ | Within a driver code, one would add the following at an appropriate place based on the information they want to add to the logger | ||
+ | |||
+ | def _enhance_context(self, func): | ||
+ | "This decorator enhances the context with a module specific contextual information" | ||
+ | argnames = func.func_code.co_varnames[:func.func_code.co_argcount] | ||
+ | |||
+ | def enhance_process(*args,**kwargs): | ||
+ | if 'kwargs' in argnames: | ||
+ | pkwargs = args[argnames.index('kwargs')] | ||
+ | if 'extra' not in pkwargs: | ||
+ | pkwargs['extra'] = {} | ||
+ | extra = pkwargs['extra'] | ||
+ | if 'sub_context' not in extra: | ||
+ | extra['sub_context'] = {} | ||
+ | sub_context = extra['sub_context'] | ||
+ | sub_context.update({"my_context": self._my_context_value}) | ||
+ | return func(*args, **kwargs) | ||
+ | |||
+ | return enhance_process | ||
+ | |||
+ | def _enhancelogger(self): | ||
+ | setattr(logging.ContextAdapter, 'process', self._enhance_context(logging.ContextAdapter.process)) |
Revision as of 21:51, 4 February 2014
Contents
Blueprint Design for (enhanced-context-logger)
Problem Statement
Currently, the logger does not provide any means to the drivers or consumers to add any additional contextual information other than the one that has been baked into the logger e.g. instanceId. The blueprint is going to add the flexibility to the logger, so that if needed the consumer of the logger could add some contextual data that can then show up in the logs without changing the individual log statements throughout the code.
Proposed Design
The idea is to introduce a placeholder for sub-contextual information. The logic would run based on the presence of such placeholder. The classes that would be enhanced in the process would be the openstack.common.log.ContextAdapter and openstack.common.log.ContextFormatter
Proposed modification to the ContextAdapter
Add a placeholder named "sub_context" within the "extra", and if found unroll it into the "extra" like below:
extra.update({"version": self.version}) if extra.get('sub_context', None): sub_context = extra.get('sub_context', None) for k in sub_context: extra.update({k:sub_context[k]}) extra['extra'] = extra.copy()
Proposed modification to the ContextFormatter
self._fmt += " " + CONF.logging_debug_format_suffix if record.__dict__.get('sub_context', None): sub_context = record.__dict__.get('sub_context', None) for k in sub_context: self._fmt += " [" + k + ":%(" + k + ")s]"
Proposed usage of this enhanced logger
Within a driver code, one would add the following at an appropriate place based on the information they want to add to the logger
def _enhance_context(self, func): "This decorator enhances the context with a module specific contextual information" argnames = func.func_code.co_varnames[:func.func_code.co_argcount] def enhance_process(*args,**kwargs): if 'kwargs' in argnames: pkwargs = args[argnames.index('kwargs')] if 'extra' not in pkwargs: pkwargs['extra'] = {} extra = pkwargs['extra'] if 'sub_context' not in extra: extra['sub_context'] = {} sub_context = extra['sub_context'] sub_context.update({"my_context": self._my_context_value}) return func(*args, **kwargs)
return enhance_process
def _enhancelogger(self): setattr(logging.ContextAdapter, 'process', self._enhance_context(logging.ContextAdapter.process))