Python Flask 日志集成 logid 实现方案:基于 threading.local 与 Filter

纸上星河
纸上星河
发布时间:2026-10-15 | 5人浏览过
原创

本文详解如何在 Flask 应用中通过 threading.local 存储 logid,并利用 logging 模块的 Filter 功能自动将 logid 注入日志输出。方案使用 uuid.uuid1().time 生成趋势递增的唯一标识,无需手动修改每个日志打印点,实现请求上下文的自动关联与问题定位。

为了便于问题定位,常见的做法是在日志中引入 logid,以便关联同一个请求的上下文。这主要解决两个问题:一是 logid 作为“全局”变量如何保存和传递;二是如何让日志打印时自动携带 logid,避免在每个打印日志的地方手动传入参数。

logid 保存与传递机制

传统做法是将 logid 保存在 threading.local 中,确保同一线程内该值保持一致。在 before_app_request 钩子中生成 logid 并将其存入该线程局部变量即可。


import threading
 
from blueprint.hooks import hooks
 
thread_local = threading.local()
app = Flask()
app.thread_local = thread_local

import uuid
 
from flask import Blueprint
from flask import current_app as app
 
hooks = Blueprint('hooks', __name__)
 
@hooks.before_app_request
def before_request():
    """
    处理请求之前的钩子
    :return:
    """
    # 生成logid
    app.thread_local.logid = uuid.uuid1().time

由于需要一个数字类型的 logid,简单使用 uuid.uuid1().time 通常足以满足并发需求,它既保证不重复,又具有趋势递增的特性(通过 logid 即可判断请求的先后顺序)。

打印日志自动携带 logid

这是 Python 日志库自带的功能,可以通过 Filter 来实现这一需求。


import logging
 
# https://docs.python.org/3/library/logging.html#logrecord-attributes
log_format = "%(asctime)s %(levelname)s [%(threadName)s-%(thread)d] %(logid)s %(filename)s:%(lineno)d %(message)s"
file_handler = logging.FileHandler(file_name)
logger = logging.getLogger()
logid_filter = ContextFilter()
file_handler.addFilter(logid_filter)
file_handler.setFormatter(logging.Formatter(log_format))
logger.addHandler(file_handler)
 
class ContextFilter(logging.Filter):
    """
    logging Filter
    """
 
    def filter(self, record):
        """
        threading local 获取logid
        :param record:
        :return:
        """
        log_id = thread_local.logid if hasattr(thread_local, 'logid') else '-'
        record.logid = log_id
 
        return True

在 log_format 中使用了多个系统自带的占位符,但 %(logid)s 默认并不存在。每条日志在打印输出前都会经过 Filter 处理,利用这一特性,我们可以将 record.logid 赋值,最终打印出的日志便包含了 logid。

虽然最终实现了功能,但由于是通用化方案,实现起来略显复杂。其实官方教程中介绍了一种更简单的方式:injecting-request-information,看来平时多查阅官方文档很有必要。

以上就是 Python 如何使用 logging 为 Flask 增加 logid 的详细内容,更多关于 Python 为 Flask 增加 logid 的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表