国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

FastAPI 實戰秘籍:從零構建高性能 API-日志篇

開發
?日志(Logging)在軟件開發和系統運維中扮演著至關重要的角色,它記錄了系統運行時的各種事件、狀態和錯誤信息。

接上文《FastAPI 實戰秘籍:從零構建高性能 API -配置篇

日志(Logging)在軟件開發和系統運維中扮演著至關重要的角色,它記錄了系統運行時的各種事件、狀態和錯誤信息。

作用:

  • 問題排查與調試
  • 監控系統健康狀態
  • 安全審計與合規
  • 性能分析與優化
  • 用戶行為分析
  • 數據恢復與回溯

日志級別和應用場景:

  • DEBUG 開發調試細節(變量值、流程分支)
  • INFO 常規運行狀態(服務啟動、關鍵業務事件)
  • WARN 非預期但可恢復的問題(低磁盤空間、降級操作)
  • ERROR 需要干預的錯誤(外部API失敗、數據庫連接中斷)
  • FATAL 導致服務崩潰的嚴重錯誤(無法恢復的異常)

在我們web開發過程中一般通過app.log記錄全部日志,通過error.log記錄ERROR級別以上的日志,能夠快速定位、排查問題。

APP日志

在通過fastapi日志模塊中,我們使用標準模塊logging。通過配置文件配置日志文件,等級、文件大小輪轉、備份日志文件數目等。

# config/config.yml

logging:
level:"INFO"
log_path:"logs/app.log"
error_path:"logs/error.log"
rotate_size:10# 日志文件輪轉大小 單位M
back_files:5# 多保留n個備份

在配置解析腳本中config.py:

# config/config.py

class LoggingConfig(BaseModel):
    level: str = "INFO"
    log_path: str = "logs/app.log"
    error_path: str = "logs/error.log"
    rotate_size: int = 10
    back_files: int = 5

修改主配置模型:

# config/config.py

# 主配置模型中嵌套Logging
class Settings(BaseSettings):
    ...
    logging: LoggingConfig

在core目錄下創建logger.py模塊,定義日志句柄,格式,處理方式等。

import logging
import os
import queue
from enum import Enum
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler, QueueHandler, QueueListener
from typing import Dict, Callable, Optional

from config.config import BASE_DIR, get_settings

# 初始化配置
settings = get_settings()
logger = logging.getLogger(settings.app.name)

# 常量定義
LOG_FORMAT = "%(asctime)s - %(module)s - %(funcName)s - line:%(lineno)d - %(levelname)s - %(message)s"
LOG_ACCESS_FILE = os.path.join(BASE_DIR, settings.logging.log_path)
LOG_PATH = os.path.dirname(LOG_ACCESS_FILE)
HANDLER_TYPE = "rotate_file"

# 確保日志目錄存在
os.makedirs(LOG_PATH, exist_ok=True)


class LoggerLevel(Enum):
    """日志級別枚舉類"""
    DEBUG = ("DEBUG", logging.DEBUG)
    INFO = ("INFO", logging.INFO)
    WARNING = ("WARNING", logging.WARNING)
    ERROR = ("ERROR", logging.ERROR)
    CRITICAL = ("CRITICAL", logging.CRITICAL)

    @property
    def level(self) -> int:
        """獲取日志級別數值"""
        return self.value[1]

    @classmethod
    def get_by_config(cls, level_str: str) -> Optional['LoggerLevel']:
        """根據配置字符串獲取日志級別枚舉"""
        return next((log for log in cls if log.value[0] == level_str), None)


class LoggerFactory:
    """日志工廠類,集中管理日志處理器創建"""

    HANDLERS: Dict[str, Callable] = {
        "default": "_create_default_handler",
        "queue": "_create_queue_handler",
        "rotate_file": "_create_rotate_file_handler",
        "timed_rotate_file": "_create_timed_rotate_file_handler"
    }

    @classmethod
    def get_logger(cls) -> logging.Logger:
        """根據配置獲取適當的日志處理器"""
        handler_method = getattr(cls, cls.HANDLERS.get(HANDLER_TYPE, "_create_default_handler"))
        handler = handler_method()
        return cls._setup_logger(handler)

    @classmethod
    def _setup_logger(cls, handler: logging.Handler) -> logging.Logger:
        """配置日志記錄器"""
        # 清除現有處理器
        for h in logger.handlers[:]:
            logger.removeHandler(h)
            h.close()

        # 設置日志級別
        logger_level = LoggerLevel.get_by_config(settings.logging.level)
        logger.setLevel(logger_level.level if logger_level else logging.DEBUG)

        # 添加處理器
        handler.setFormatter(logging.Formatter(LOG_FORMAT))
        logger.addHandler(handler)
        return logger

    @classmethod
    def _create_default_handler(cls) -> logging.FileHandler:
        """創建默認文件處理器"""
        print("使用默認文件日志處理器")
        return logging.FileHandler(LOG_ACCESS_FILE, delay=True, encoding="utf-8")

    @classmethod
    def _create_queue_handler(cls) -> QueueHandler:
        """創建隊列日志處理器"""
        print("使用異步隊列日志處理器")
        log_queue = queue.Queue(-1)  # 無限大小隊列
        file_handler = logging.FileHandler(LOG_ACCESS_FILE, delay=True, encoding="utf-8")

        # 創建并啟動隊列監聽器
        listener = QueueListener(
            log_queue,
            file_handler,
            respect_handler_level=True
        )
        listener.start()

        return QueueHandler(log_queue)

    @classmethod
    def _create_rotate_file_handler(cls) -> RotatingFileHandler:
        """創建按文件大小輪轉的處理器"""
        print("使用文件大小輪轉日志處理器")
        return RotatingFileHandler(
            LOG_ACCESS_FILE,
            maxBytes=settings.logging.rotate_size * 1024 * 1024,
            backupCount=settings.logging.back_files,
            encoding="utf-8"
        )

    @classmethod
    def _create_timed_rotate_file_handler(cls) -> TimedRotatingFileHandler:
        """創建按時間輪轉的處理器"""
        print("使用時間輪轉日志處理器")
        return TimedRotatingFileHandler(
            LOG_ACCESS_FILE,
            when='midnight',
            interval=1,
            backupCount=settings.logging.back_files,
            encoding="utf-8"
        )


def get_logger() -> logging.Logger:
    """獲取配置好的日志記錄器"""
    return LoggerFactory.get_logger()

上面腳本中HANDLER_TYPE沒設置在配置文件中,僅開發人員能夠修改。 logging中 大概有四種處理器:

  • FileHandler 阻塞寫入日志文件
  • QueueHandler 非阻塞隊列寫入日志
  • RotatingFileHandler 文件大小輪轉
  • TimedRotatingFileHandler 時間間隔輪轉

在__init__.py定義暴露方法:

from core.logger import get_logger
__all__ = [get_logger]

測試日志:

# main.py

def create_app():
    """啟動項目"""

    ...

    @app.get("/{form_id}")
    async def root(form_id: int = Path(..., gt=0)):
        get_logger().info(" ===aaa===")
        return {"message": form_id}

    return app

啟動服務,我們可以看到輸出的日志內容。

效果如下:

ERROR日志

為了更好的處理線上問題,排查問題。除了項目日志app.log外,系統異常報錯的日志記錄到error.log中。

Fastapi中可以通過裝飾器@app.exception_handler(Exception)記錄全局異常。

文檔地址:https://fastapi.tiangolo.com/zh/tutorial/handling-errors/#_4

在core包中,我們創建模塊exception.py。 在其中通過依賴注入的方式設置全局異常。

# core/exception.py

...
def register_exception(app: FastAPI):
    """
    異常捕捉
    """

    @app.exception_handler(CustomException)
    asyncdef custom_exception_handler(request: Request, exc: CustomException):
        """
        自定義異常
        """
        _logger.error(
            f"Path: {request.url.path}\n"
            f"Method: {request.method}\n"
            f"Client: {request.client.host if request.client else 'unknown'}\n"
            f"Exception: {type(exc).__name__}",
            exc_info=(type(exc), exc, exc.__traceback__)
        )

        return JSONResponse(
            status_code=exc.status_code,
            cnotallow={"message": exc.msg, "code": exc.code},
        )

    @app.exception_handler(HTTPException)
    asyncdef unicorn_exception_handler(request: Request, exc: HTTPException):
        """
        重寫HTTPException異常處理器
        """
        _logger.error(
            f"Path: {request.url.path}\n"
            f"Method: {request.method}\n"
            f"Client: {request.client.host if request.client else 'unknown'}\n"
            f"Exception: {type(exc).__name__}",
            exc_info=(type(exc), exc, exc.__traceback__)
        )
        return JSONResponse(
            status_code=exc.status_code,
            cnotallow={
                "code": exc.status_code,
                "message": exc.detail,
            }
        )
      ...

代碼倉庫 https://github.com/pyzxs/zadmin。

在__init__.py中設置暴露函數:

from core.exception import register_exception
from core.logger import get_logger

__all__ = [get_logger,register_exception]

在main.py的啟動腳本中設置:

# main.py

from core import get_logger, register_exception

def create_app():
    ...
    register_exception(app)
    ...

測試異常處理:

@app.get("/{form_id}")
    async def root(form_id: int = Path(..., gt=0)):
        # raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
        # raise CustomException("CustomException")
        # raise ValueError("ValueError")
        
        return {"message": form_id}

    return app

運行測試, 該路由地址中定義{form_id:int}是整形,如果輸入字符串就會拋出RequestValidationError,在error.log中會記錄異常的追溯。

效果如下:

現在項目的日志模塊就定義好了。你可以在調試的代碼中通過get_logger().debug()后info()調試代碼了。同時系統exception報錯也會記錄到error.log中。幫助你盡快定位異常。

責任編輯:趙寧寧 來源: 程序員老朱
相關推薦

2025-12-02 09:14:18

FastAPIweb開發

2025-12-03 06:35:00

FastAPI中間件開發

2025-12-03 10:00:00

依賴注入FastAPI?代碼

2025-09-08 06:10:00

FastAPI開發web

2025-09-09 07:00:00

數據庫FastAPI開發

2025-06-03 08:15:00

微服務架構異步任務隊列

2017-07-11 15:26:57

LocalMQ RocketMQ高性能

2023-11-06 08:32:17

FastAPIPython

2025-12-03 06:20:00

FastAPI代碼Python

2021-10-14 09:51:17

架構運維技術

2018-05-08 18:26:49

數據庫MySQL性能

2019-09-03 09:41:48

運維架構技術

2025-05-26 09:25:00

Web 接口開發Redis

2025-04-07 05:00:00

2025-01-13 12:23:51

2024-11-25 09:10:03

2011-10-25 13:13:35

HPC高性能計算Platform

2011-10-21 14:20:59

高性能計算HPC虛擬化

2023-08-23 10:16:47

日志系統

2022-12-09 08:40:56

高性能內存隊列
點贊
收藏

51CTO技術棧公眾號

在线观看免费一区二区| 欧美精品xxx| 欧美一级高清免费播放| 四虎在线观看| 黄色一级大片在线免费看产| 黄色小视频在线观看| av超碰在线观看| 国产在线高清视频| 无码一区二区三区视频| 欧美日韩在线播| 日韩精品免费一线在线观看| 日产精品久久久一区二区福利| 91色在线观看| jizz大全欧美jizzcom| 久久精品亚洲一区二区三区浴池| 成人午夜在线视频一区| 在线国产小视频| 免费黄色av电影| 老牛精品亚洲成av人片| 亚洲欧美日本精品| 成人短视频app| 欧美日本国产一区| 99在线影院| 日本在线观看| 色婷婷在线播放| 蜜桃一区二区三区| 国产精品久久久久aaaa| 欧美日韩中文字幕| 美女少妇精品视频| 成人区一区二区| 欧美亚洲国产成人| 中文字幕中文字幕在线中高清免费版| 成人欧美大片| 又黄又爽在线免费观看| 国产精品无码专区av在线播放| 国产精品一区2区3区| 性久久久久久久久| 91在线观看免费高清| 中文字幕21页在线看| 国产99久久久精品| 亚洲人在线视频| 国产高潮呻吟久久久| 久草在线成人| 国产精品99久久久久久www| 国产精品一卡二卡三卡| 免费成人蒂法| 久久夜色精品亚洲噜噜国产mv | 色97色成人| 91高清视频在线| 国产亚洲欧美日韩精品一区二区三区 | 亚洲精品视频啊美女在线直播| 久久一留热品黄| 亚洲色图五月天| 1卡2卡3卡精品视频| 女人天堂av在线播放| 国产精品视频yy9099| 日韩精品福利| 欧美国产日韩亚洲一区| 在线观看免费版| 欧美日韩免费高清一区色橹橹| 久草免费在线| 欧美综合一区第一页| 久久午夜激情| 欧美巨大黑人极品精男| caoporn97在线视频| 888久久久| 亚洲福利视频导航| 污色网站在线观看| 一二三四区精品视频| 青青青在线播放| 欧美日韩在线视频一区| 中国一级黄色录像| 欧美日韩视频免费看| 91视频国产精品| 激情欧美一区二区| 欧美偷拍视频| 欧美成人国产一区二区| 成人精品天堂一区二区三区| 欧美极品jizzhd欧美| 亚洲青青青在线视频| 僵尸再翻生在线观看| 国产伦精品免费视频| 欧美二区在线看| 91视频免费观看| 18videosex性欧美麻豆| 成人激情视频免费在线| 2020国产精品| 男女羞羞在线观看| 成人午夜黄色影院| 亚洲码国产岛国毛片在线| 欧美videos粗暴| 一区二区在线不卡| 亚洲乱码中文字幕综合| 日韩一级特黄| av免费在线播放网站| 在线日韩日本国产亚洲| 先锋在线亚洲| 日韩中文字幕在线视频| 麻豆视频一区二区| а天堂中文在线官网| 欧美视频小说| 欧美成人性战久久| 国产一区二区美女| 精品人人视频| 热久久最新网址| 亚洲欧美日韩爽爽影院| 丁香啪啪综合成人亚洲小说| 国产情侣一区在线| 又黄又爽毛片免费观看| 国产精品日日摸夜夜添夜夜av| 国产喷白浆一区二区三区| 亚洲精品国产setv| 在线小视频网址| 国产精品久久久久久免费观看| 91传媒视频在线播放| 蜜桃视频一区二区| 成人毛片免费| www.久草.com| 久久99精品国产99久久| 尤物yw午夜国产精品视频明星 | 日韩欧美一级| 少妇精品放荡导航| 国产综合av一区二区三区| 国产亚洲aⅴaaaaaa毛片| 国产精品高潮呻吟| 免费看黄色91| 午夜先锋成人动漫在线| 超碰97在线免费观看| www.男人天堂网| 99re在线观看| 欧美黑人巨大xxx极品| 精品视频资源站| 2020国产精品自拍| 91tv官网精品成人亚洲| 成人在线爆射| 免费黄网站在线| 天天草夜夜草| 男女视频网站在线观看| 国产精品一区二区不卡视频| 精品中文字幕在线观看| 欧美一级日韩不卡播放免费| 夜夜嗨av一区二区三区中文字幕| 国产精品影视在线| 国产麻豆综合| 欧美精品自拍| 欧美在线免费看视频| 91九色鹿精品国产综合久久香蕉| 亚洲夜夜综合| 国产资源在线观看| 91麻豆福利| 亚洲成人av免费看| 日本韩国欧美在线观看| 一个色的综合| 亚洲国产综合自拍| 国产三区二区一区久久| 国产91社区| 岛国视频一区免费观看| 国产精品美女无圣光视频| 国产专区欧美专区| 欧美激情免费在线| 日本视频久久久| 欧美12av| 亚洲成人av免费看| 欧美白人做受xxxx视频| 国产偷倩在线播放| 黄在线观看免费网站ktv| 日韩高清一区| 国内成人精品| 久久国产高清| 成人av网站在线观看| 亚洲综合在线第一页| 亚洲精品一区二区三区香蕉 | 男女性激情视频在线观看| 国产特黄在线| 99久久久国产| 免费精品视频最新在线| 亚洲精品va在线观看| 日韩成人中文电影| 国产精品爽爽ⅴa在线观看| 中文字幕人成一区| 亚洲精品一区二区三| 欧美国产日本高清在线| 亚洲成a人v欧美综合天堂| 精品亚洲porn| 国产一在线精品一区在线观看| 国产中文字幕在线看| 精品少妇在线视频| 91成人免费看| 欧美激情亚洲一区| 国产精品久久久久久免费观看| 国产99久久九九精品无码| 欧美风狂大伦交xxxx| 色婷婷综合久久久久中文字幕| 亚洲欧洲精品一区二区三区波多野1战4 | 日韩国产精品久久| 欧美激情一二三区| 国产不卡精品在线| 色婷婷精品视频| 色老头在线一区二区三区| 国产直播在线|