向Flask的app.logger提供额外的信息 [英] Provide extra information to Flask's app.logger
问题描述
Flask 0.10的默认调试日志格式是
debug_log_format =
'------------------- -------------------------------------------------- ---- \\\
%$ b $%(levelname)s%(module)s [%(pathname)s:%(lineno)d]:\\\
%(message)s
\\ \
------------------------------------------------ -------------------------'
如何将其更改为:
'------------ -------------------------------------------------- ----------- \%%
$ p $
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
pre>
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()
通过覆盖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 usingrecord.work_id
.But the
app.logger
is created bycreate_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, likeapp.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屋!