Logging variable data with new format string

后端 未结 9 2226
别那么骄傲
别那么骄傲 2020-11-28 03:09

I use logging facility for python 2.7.3. Documentation for this Python version say:

the logging package pre-dates newer formatting options such as str

9条回答
  •  星月不相逢
    2020-11-28 03:14

    This was my solution to the problem when I found logging only uses printf style formatting. It allows logging calls to remain the same -- no special syntax such as log.info(__("val is {}", "x")). The change required to code is to wrap the logger in a StyleAdapter.

    from inspect import getargspec
    
    class BraceMessage(object):
        def __init__(self, fmt, args, kwargs):
            self.fmt = fmt
            self.args = args
            self.kwargs = kwargs
    
        def __str__(self):
            return str(self.fmt).format(*self.args, **self.kwargs)
    
    class StyleAdapter(logging.LoggerAdapter):
        def __init__(self, logger):
            self.logger = logger
    
        def log(self, level, msg, *args, **kwargs):
            if self.isEnabledFor(level):
                msg, log_kwargs = self.process(msg, kwargs)
                self.logger._log(level, BraceMessage(msg, args, kwargs), (), 
                        **log_kwargs)
    
        def process(self, msg, kwargs):
            return msg, {key: kwargs[key] 
                    for key in getargspec(self.logger._log).args[1:] if key in kwargs}
    

    Usage is:

    log = StyleAdapter(logging.getLogger(__name__))
    log.info("a log message using {type} substitution", type="brace")
    

    It's worth noting that this implementation has problems if key words used for brace substitution include level, msg, args, exc_info, extra or stack_info. These are argument names used by the log method of Logger. If you need to one of these names then modify process to exclude these names or just remove log_kwargs from the _log call. On a further note, this implementation also silently ignores misspelled keywords meant for the Logger (eg. ectra).

提交回复
热议问题