Python日志记录:属于一个请求的组日志 [英] Python Logging: Group logs which belong to one request

查看:147
本文介绍了Python日志记录:属于一个请求的组日志的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以对属于一个Web请求的python Web应用程序的日志进行分组?

Is there a way to group logs of a python web application which belong to one web request?

示例:

2015-02-11 13:06:32 myapp.middleware.MYAPPMiddleware: INFO     Login of user foo was successful
2015-02-11 13:06:32 myapp.middleware.MYAPPMiddleware: INFO     Login of user bar failed
2015-02-11 13:06:32 myapp.send_mails: INFO     failed to send mail to someone@example.com

以上日志行彼此无关.

The above log lines are unrelated to each other.

如何用Python方式解决这个问题?

How can you solve this the pythonic way?

推荐答案

日志条目的本质是相互独立的.
将它们连接在一起的正确方法是将一些上下文信息包含在条目中,以便以后查看日志时进行过滤.

Log entries in their essence are designed to be independent from each other.
The correct way to connect them together is to include some contextual information into the entries to filter by when looking through the logs later.

下面是一个Sharepoint日志记录的示例,其中包含以下信息:

Here's a example of a Sharepoint log record with such information:

Timestamp               Process             TID     Area                    Category                    EventID Level       Message     Correlation
02/26/2015 17:49:19.65  w3wp.exe (0x1F40)   0x2358  SharePoint Foundation   Logging Correlation Data    xmnv    Medium      Name=Request (POST:http://reserver2:80/pest/_vti_bin/sitedata.asmx) d1e2b688-e0b2-481e-98ce-497a11acab44

在Python logging文档中, 将上下文信息添加到日志记录输出中 建议使用以下两种方法之一:使用LoggerAdapterFilter.

In Python logging docs, Adding contextual information to your logging output recommends either of two methods: using a LoggerAdapter or a Filter.

LoggerAdapter的用法如下(示例基于文档中的示例):

LoggerAdapter is used like this (examples are based on those in the docs):

class AddConnIdAdapter(logging.LoggerAdapter):
    def process(self, msg, kwargs):
        return <augment_message(msg,arbitrary_info)>, kwargs
la = AddConnIdAdapter(<logger>,extra=<parameters, saved in self.extra>)
<...>
la.info(<message>)

Filter的用法如下:

#Either all messages should have custom fields
# or the Formatter used should support messages
# both with and without custom fields
logging.basicConfig(<...>,format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
class AddClientInfo(logging.Filter):
    #override __init__ or set attributes to specify parameters
    def filter(self, record):
        record.ip = <get_client_ip()>
        record.user = <get_client_name()>
        return True    #do not filter out anything
l=<logger()>
l.addFilter(AddClientInfo()) #can attach to either loggers or handlers
<...>
l.info('message')

如您所见,区别是LoggerAdapter是不透明的,而Filter是透明的.在示例中,前者修改消息文本,而后者设置自定义属性(实际上,编写它们需要使用Formatter的配合),但实际上,两者都可以.

As you can see, the difference is LoggerAdapter is non-transparent while Filter is transparent. In the examples, the former modifies the message text while the latter sets custom attributes (and actually writing them requires cooperation of the Formatter used) but in fact, both can do both.

因此,如果只需要将上下文添加到某些消息中,而前者更适合于扩展所记录的全部或大部分消息,则前者更为有用.

So, the former is more useful if you only need to add the context to some messages while the latter is more fit to augment all, or a large portion of, the messages being logged.

这篇关于Python日志记录:属于一个请求的组日志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆