Python如何使用logging為Flask增加logid
我們為瞭問題定位,常見做法是在日志中加入 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 # 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的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- None Found