用户登录
用户注册

分享至

Python如何使用logging为Flask增加logid

  • 作者: 飘在天空的羽
  • 来源: 51数据库
  • 2021-08-17

我们为了问题定位,常见做法是在日志中加入 logid,用于关联一个请求的上下文。这就涉及两个问题:1. logid 这个“全局”变量如何保存传递。2. 如何让打印日志的时候自动带上 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
 
# http://www.all.com/files/Articles/416/0/183/183783_20210624102345348.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 了。

虽然最终实现了,但因为是通用化方案,所以有些复杂了。其实官方教程中介绍了一种更加简单的方式:,看来没事还得多看看官方文档。

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

软件
前端设计
程序设计
Java相关