tornado日志使用详解
1.需求
将http访问记录,程序自定义日志输出到文件,按天分割,保留最近30天的日志。
2.使用示例
init_logging("%s/QYK.%s.%s.log" % (log_path, tornado.options.options.mode, tornado.options.options.port))
def init_logging(log_file):
# 使用TimedRotatingFileHandler处理器
file_handler = TimedRotatingFileHandler(log_file, when="d", interval=1, backupCount=30)
# 输出格式
log_formatter = logging.Formatter(
"%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] [%(lineno)d] %(message)s"
)
file_handler.setFormatter(log_formatter)
# 将处理器附加到根logger
root_logger = logging.getLogger()
root_logger.addHandler(file_handler)
logging.info('测试日志输出')
运行后日志文件内容:
tornado中会将logging的输出级别设置为info
3.http访问日志
tornado中http访问的日志是由access_log处理器完成的,access_log继承了根logger,因此,
access_log处理器也会将日志输出到示例中的日志文件中,如下所示:
import logging
import datetime
class Test1Handler(ApiHandler):
async def get(self, *args, **kwargs):
self.return_success_response()
return
运行后日志文件内容:
查看tornado源码tornado\web.py,可以看到access_log的输出格式:
def log_request(self, handler):
"""Writes a completed HTTP request to the logs.
By default writes to the python root logger. To change
this behavior either subclass Application and override this method,
or pass a function in the application settings dictionary as
``log_function``.
"""
if "log_function" in self.settings:
self.settings["log_function"](handler)
return
if handler.get_status() < 400:
log_method = access_log.info
elif handler.get_status() < 500:
log_method = access_log.warning
else:
log_method = access_log.error
request_time = 1000.0 * handler.request.request_time()
log_method("%d %s %.2fms", handler.get_status(),
handler._request_summary(), request_time)
如何自定义http访问日志的输出格式呢?通过源码,可知有两种方法可以解决这个问题
1)我们可以在Application中自定义一个log_function即可
def log_func(handler):
if handler.get_status() < 400:
log_method = access_log.info
elif handler.get_status() < 500:
log_method = access_log.warning
else:
log_method = access_log.error
request_time = 1000.0 * handler.request.request_time()
log_method("%d %s %s (%s) %s %s %.2fms",
handler.get_status(), handler.request.method,
handler.request.uri, handler.request.remote_ip,
handler.request.headers["User-Agent"],
handler.request.arguments,
request_time)
class QYKApplication(tornado.web.Application):
def __init__(self, config, webpack_setting, _redis, session_class):
settings = dict()
settings["log_function"] = log_func
运行后日志文件内容:
在输出格式中,增加了访问url,ip,代理服务器,参数等信息
2)重写RequestHandler的_request_summary方法
def _request_summary(self):
return "%s %s (%s) %s\n%s" % (self.request.method, self.request.uri,
self.request.remote_ip, self.request.headers["User-Agent"],
self.request.arguments)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2016-10-15 持续集成详解