You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python的Loguru中自定义JSON日志结构(FastAPI场景)

在FastAPI中自定义Loguru的JSON日志结构

核心思路:用自定义格式化函数替代默认序列化

没必要去重写Loguru内部的_serialize_record私有方法,直接通过官方提供的format参数传入自定义逻辑,就能生成你需要的极简JSON结构,既稳定又避免依赖内部实现。

具体实现步骤

1. 编写自定义格式化函数

创建一个函数接收Loguru的记录对象,提取所需字段并生成目标JSON字符串:

import json
from loguru import logger
from datetime import datetime

def custom_json_formatter(record):
    # 把时间格式化为你要的"5:30pm"样式
    formatted_time = datetime.fromtimestamp(record["time"]).strftime("%I:%M%p").lower()
    # 构建仅包含必要字段的日志结构
    log_content = {
        "time": formatted_time,
        "error": record["message"]
    }
    return json.dumps(log_content)

2. 替换默认日志Handler

在FastAPI启动前,先移除Loguru自带的默认输出,再添加使用自定义格式的Handler:

from fastapi import FastAPI

# 清除默认日志输出
logger.remove()
# 添加自定义Handler,指定输出格式和位置
logger.add(
    sink="app_errors.log",  # 可以是文件、sys.stdout等输出目标
    format=custom_json_formatter,
    level="ERROR"  # 按需设置日志级别,比如只记录ERROR级别的日志
)

app = FastAPI()

@app.get("/test-error")
async def trigger_error():
    logger.error("Type error")  # 输出日志将是 {"time": "05:30pm", "error": "Type error"}
    return {"status": "error triggered"}

3. 按需扩展结构

如果需要针对不同日志级别调整结构,直接在格式化函数里修改即可:

def custom_json_formatter(record):
    formatted_time = datetime.fromtimestamp(record["time"]).strftime("%I:%M%p").lower()
    log_content = {"time": formatted_time}
    
    if record["level"].name == "ERROR":
        log_content["error"] = record["message"]
    elif record["level"].name == "INFO":
        log_content["info"] = record["message"]
    
    return json.dumps(log_content)

为什么不推荐重写_serialize_record?

_serialize_record是Loguru的内部私有方法,其实现逻辑可能随版本更新变化,直接依赖它会导致代码兼容性差。而使用官方提供的format参数是符合框架设计意图的标准用法,无需修改源码就能实现需求。

内容的提问来源于stack exchange,提问作者shaswat kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:33:09