向Flask的app.logger提供额外的信息 [英] Provide extra information to Flask's app.logger

查看:202
本文介绍了向Flask的app.logger提供额外的信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Flask 0.10的默认调试日志格式

  debug_log_format = 
'------------------- -------------------------------------------------- ---- \\\
%$ b $%(levelname)s%(module)s [%(pathname)s:%(lineno)d]:\\\
%(message)s
\\ \
------------------------------------------------ -------------------------'

如何将其更改为:

 '------------ -------------------------------------------------- ----------- \%%
work_id%(levelname)s in%(module)s [%(pathname)s:%(lineno)d]:\\\
%(消息)s
\\\
---------------------------------------- ---------------------------------'

其中 work_id 是每个请求的随机生成的UUID。



<如果记录器是由我自己创建的,我可以使用 logging.LoggerA dapter 并提供额外的信息作为字典 {'work_id':some_uuid} ,那么我可以在日志记录中使用 record.work_id



但是 app.logger 是由 create_logger()在Flask的 logging.py 中,是否必须修改Flask源文件来实现我想要的功能?



我也想过用自己的记录器覆盖 app.logger ,比如 app.logger = my_logger ,它看起来不对。

解决方案

通过Flask.debug_log_format



只要做到这一点:

  app.debug = True 
app.debug_log_format = ------------------------------------------------- ------------------------
%(worker_id)s(levelname)s in%(module)s [%(pathname)s: %(LINENO )d]:\\\
%(message)s
---------------------------------- ---------------------------------------
app.logger。 log(test,extra = {worker_id:request.your_uuid_property)

(b)

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b#请用您的实际属性替换request.uuid
log = lambda msg:app.logger.info(msg,extra = {'worker_id':request.uuid})

@ app.route(/)
def hello():
log(hello world)
returnHello World!

if __name__ ==__main__:
app.debug_log_format =----------------------- --------------------------------------------------
%(worker_id)s%(module)s [%(pathname)s:%(lineno)d]:
%(message)s
-------- -------------------------------------------------- ---------------
app.debug = True
log(hello world)
app.run()

通过标准日志模块的Handler和Formatter



Flask以任何方式使用日志记录,因此您可以使用 logging.Handler logging.Formatter 来实现Flask之外的功能。通用示例可在此处找到。日志配置的高级主题可以在 doc < a>,然后在食谱

中输入

针对您的问题的量身定制的示例是:

 导入记录$ b $ from瓶子导入Flask 
app = Flask(__ name__)
$ b $ class CustomFormatter(logging.Formatter):
def format(self,record):
record.worker_id =request.uuid取而代之的是你的变量
return super(CustomFormatter,self).format(record)
$ b $ app_route(/)
def hello():
app.logger.info(hello world)
返回Hello World!

if __name__ ==__main__:
custom_format =------------------------- ------------------------------------------------
%(worker_id)s%(module)s [%(pathname)s:%(lineno)d]:
%(message)s
----------- -------------------------------------------------- -------------
app.debug = True
ch = logging.StreamHandler()
ch.setFormatter(CustomFormatter(fmt = custom_format) )
app.logger.addHandler(ch)
app.logger.debug(hello world)
app.run()
pre>

通过覆盖logging.Logger类

可以实现相同的目标通过覆盖默认的记录器类。结合烧瓶请求上下文堆栈,您将能够在日志中获得您自己的字段:

 导入日志记录$ b $从瓶子导入Flask 
app = Flask(__ name__)
from烧瓶导入_request_ctx_stack

CUSTOM_FORMAT =---------------------------------- ---------------------------------------
%(worker_id)s% (module)s [%(pathname)s:%(lineno)d]:
%(message)s
------------------- -------------------------------------------------- ----
$ b $ class MyLogger(logging.Logger):
def makeRecord(self,name,level,fn,lno,msg,args,exc_info,func = None, extra = None):
ctx = _request_ctx_stack.top
custom_extra = dict(
worker_id =request.uuid

如果ctx不是None:
url = ctx.request.url#请用您自己的字段替换这个
custom_extra [w orker_id] = url

如果不是extra:
extra.update(custom_extra)
else:
extra = custom_extra
return super(MyLogger ,self).makeRecord(name,level,fn,lno,msg,args,exc_info,func = func,extra = extra)

logging.setLoggerClass(MyLogger)

@ app.route(/)
def hello():
app.logger.info(hello world)
returnHello World!
$ b $ if if __name__ ==__main__:
app.debug_log_format = CUSTOM_FORMAT
app.debug = True
app.logger.debug(hello world)
app.run()


The default debug log format for Flask 0.10 is

debug_log_format =
'-------------------------------------------------------------------------\n%
%(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s
\n-------------------------------------------------------------------------'

How do I change it to this:

'-------------------------------------------------------------------------\n%
work_id %(levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s
\n-------------------------------------------------------------------------'

where work_id is a randomly generated UUID for each request.

If the logger is created by myself, I can just use a logging.LoggerAdapter and provide the extra information as a dict {'work_id': some_uuid}, then I can access it in the log record using record.work_id.

But the app.logger is created by create_logger() in Flask'slogging.py, do I have to modify the Flask source to achieve what I want?

I also thought just override app.logger with my own logger, like app.logger = my_logger, it doesn't seem right.

解决方案

Via Flask.debug_log_format

Just do this:

app.debug = True
app.debug_log_format = """-------------------------------------------------------------------------
%(worker_id)s (levelname)s in %(module)s [%(pathname)s:%(lineno)d]:\n%(message)s
-------------------------------------------------------------------------"""
app.logger.log("test", extra={"worker_id": request.your_uuid_property)

Example:

import logging
from flask import Flask, request
app = Flask(__name__)

# please replace "request.uuid" with your actual property
log = lambda msg: app.logger.info(msg, extra={'worker_id': "request.uuid" })

@app.route("/")
def hello():
    log("hello world")
    return "Hello World!"

if __name__ == "__main__":
    app.debug_log_format = """-------------------------------------------------------------------------
    %(worker_id)s in %(module)s [%(pathname)s:%(lineno)d]:
    %(message)s
    -------------------------------------------------------------------------"""
    app.debug = True
    log("hello world")
    app.run()

Via Handler and Formatter of standard logging module

Flask uses logging any way, so you can use logging.Handler and logging.Formatter to achieve outside Flask. A generic example can be found here. Advanced topic of logging configuration can be found in the doc and in the cookbook

A tailored example regarding your question is:

import logging
from flask import Flask
app = Flask(__name__)

class CustomFormatter(logging.Formatter):
    def format(self, record):
        record.worker_id = "request.uuid" # replace this with your variable 
        return super(CustomFormatter,self).format(record)

@app.route("/")
def hello():
    app.logger.info("hello world")
    return "Hello World!"

if __name__ == "__main__":
    custom_format = """-------------------------------------------------------------------------
    %(worker_id)s in %(module)s [%(pathname)s:%(lineno)d]:
    %(message)s
    -------------------------------------------------------------------------"""
    app.debug = True
    ch = logging.StreamHandler()
    ch.setFormatter(CustomFormatter(fmt=custom_format))
    app.logger.addHandler(ch)
    app.logger.debug("hello world")
    app.run()

Via overriding logging.Logger class

The same objective can be achieved by override the default logger class. Combining the flask request context stack, you would be able to get your own field in the log:

import logging
from flask import Flask
app = Flask(__name__)
from flask import _request_ctx_stack

CUSTOM_FORMAT = """-------------------------------------------------------------------------
%(worker_id)s in %(module)s [%(pathname)s:%(lineno)d]:
%(message)s
-------------------------------------------------------------------------"""

class MyLogger(logging.Logger):
    def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
        ctx = _request_ctx_stack.top
        custom_extra = dict(
            worker_id="request.uuid"
        )
        if ctx is not None:
            url = ctx.request.url # please replace this with your own field
            custom_extra["worker_id"] = url

        if extra is not None:
            extra.update(custom_extra)
        else:
            extra = custom_extra
        return super(MyLogger,self).makeRecord(name, level, fn, lno, msg, args, exc_info, func=func, extra=extra)

logging.setLoggerClass(MyLogger)

@app.route("/")
def hello():
    app.logger.info("hello world")
    return "Hello World!"

if __name__ == "__main__":
    app.debug_log_format = CUSTOM_FORMAT
    app.debug = True
    app.logger.debug("hello world")
    app.run()

这篇关于向Flask的app.logger提供额外的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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