[Python-Dev] Passing contextual information when logging

Vinay Sajip vinay_sajip at yahoo.co.uk
Fri Jan 11 16:57:14 CET 2008


Nick Coghlan <ncoghlan <at> gmail.com> writes:

> It looks pretty good (and useful) to me, but I have a couple of questions.
> 
> When you talk about stacking in the constructor docstring, do you mean 
> something like having LoggerAdapterA delegating to LoggerAdapterB which 
> in turn delegates to the real logger?
> 
> If that's what you mean, then I think the process() method will need to 
> be changed to handle the case where there is already an "extras" entry 
> in the keyword arguments. If that's not what you mean... then please 
> explain because I don't have any other ideas :)
> 
> I was also going to suggest modifying the constructor to accept keyword 
> arguments, but realised that case can be adequately handled just by 
> using a dict:
> 
>    logger_with_extra = LoggerAdapter(logger, dict(attr1=5, attr2=True))
> 

Hi Nick,

Thanks for the feedback. The stacking is a bit of a corner case, so maybe I
should take that comment out of the docstring - but that's what I meant by
stacking. A set of stacked adapters could work by e.g. appending or prepending
their contextual info to the message, or by manipulating the "extra" keyword
argument to the base logger. The example implementation uses the "extra"
method, but if another adapter was to be stacked on top of that one, its
process method would need to check the passed in kwargs for key "extra" and
replace it with some merged version of the two sets of contexts - its own and
that of the underlying logger.

Another point about the "extra" method is that it lends itself to working with
a Formatter whose format string can hold user-defined placeholders like %(ip)s
in the example. This will work well in some scenarios, but in other scenarios
(where it may be desired to share formatters across various handlers, or
because stacking is desired and there's no way for one formatter to know all
the placeholders) it makes sense to just manipulate msg in the process method,
for example:

    def process(self, msg, kwargs):
        prefix = "IP: %(ip)-15s User: %(user)-8s" % self.extra
        return "%s %s" % (prefix, msg), kwargs

When I check it in I will elaborate on the class docstring to explain the usage
in a bit more detail, as well as of course detailing it in the docs in a
separate section entitled "Passing contextual information to the log" (or
similar).

Best regards,


Vinay Sajip



More information about the Python-Dev mailing list