Python记录:这属于一个请求组日志(Python Logging: Group logs whi

2019-10-21 20:51发布

有没有一种方法,以属于一个web请求一个Python Web应用程序的组日志?

例:

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

上述日志行是相互无关的。

你怎么能解决这个问题的Python的方式?

Answer 1:

究其实质日志条目被设计成相互独立的。
将它们连接在一起,正确的方法是包括一些上下文信息到项目通过日志看后,当进行过滤。

这里有这样的信息在SharePoint日志记录的例子:

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

LoggerAdapter使用这样的(例子是基于那些在文档中):

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使用),但实际上,这两个都可以做。

所以,前者是比较有用的,如果你只需要上下文添加到一些消息,而后者更适合于增加的全部或大部分,被记录的消息。



Answer 2:

您可以随机UUID分配到init方法每个请求,并将其添加到所有日志消息。

例如,在龙卷风:

class MainRequestHandler(RequestHandler):
    def __init__(self, application, request):
        super(MainRequestHandler, self).__init__(application, request)
        self.uuid = uuid.uuid4()
        logging.info("%s | %s %s %s",
                     self.uuid,
                     request.method,
                     request.full_url(),
                     request.remote_ip)

作为结果,你将能够通过这个UUID到grep日志找到属于单独的请求的所有消息。



文章来源: Python Logging: Group logs which belong to one request