Django 用 Loguru 完美替换标准 Logging,实现优雅的日志管理方案

Django 用 Loguru 完美替换标准 Logging,实现优雅的日志管理方案

这篇文章将详细拆解如何将强大的 loguru 库深度集成到 Django 项目中,彻底解决原生 logging 配置冗长、难以维护的痛点。


为什么要进行方案替换

Django 默认的日志配置通过 LOGGING 字典实现,嵌套层级多且语法繁琐。相比之下,loguru 提供了更直观的 API 和自动化的日志轮转管理。

核心技术要点

  • 全量拦截 :通过自定义 InterceptHandler 类,将 Django 内置、Gunicorn 容器以及第三方库产生的标准 logging 消息全部重定向至 loguru

  • 精准溯源 :利用 sys._getframe 动态查找调用栈,确保日志中显示的文件名和行号是真实的业务逻辑位置,而非拦截器本身。

  • 自动化策略:配置文件输出时,只需一行代码即可实现凌晨定时切割日志(rotation)和 30 天自动清理(retention)。

  • 并发安全 :开启 enqueue=True 选项,利用多线程/进程安全的队列机制,防止高并发下日志写入冲突。

部署实践:一键接管 Django 日志

在项目中创建日志工具模块后,只需在 settings.py 顶部导入,并设置 LOGGING_CONFIG = None 即可禁用 Django 原生逻辑。

Python

复制代码
import os
import sys
import logging
from pathlib import Path
from loguru import logger

# 路径初始化
BASE_DIR = Path(__file__).resolve().parent.parent
log_dir = os.path.join(BASE_DIR, "logs")
log_file_path = os.path.join(log_dir, "dt_test.log")
if not os.path.exists(log_dir):
    os.makedirs(log_dir)

# 拦截器定义:核心在于深度(depth)的计算
class InterceptHandler(logging.Handler):
    def emit(self, record):
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno
        frame, depth = sys._getframe(6), 6
        while frame and frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1
        logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())

# 彻底接管配置
LOGGING_CONFIG = None

def setup_loguru(debug_mode: bool = True):
    logger.remove()
    log_format = "{time:YYYY-MM-DD HH:mm:ss,SSS} | {level: <8} | {name} [{module}.{function}:{line}] | {message}"
    
    # 控制台调试输出
    if debug_mode:
        logger.add(sys.stdout, level="DEBUG", format=log_format, enqueue=True)

    # 文件持久化配置:支持每天凌晨切割与压缩
    logger.add(
        log_file_path, level="DEBUG", format=log_format, rotation="00:00", 
        retention="30 days", encoding="utf-8", enqueue=True, compression="zip"
    )

    # 重定向系统级日志
    logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
    for name in ["django", "django.server", "gunicorn.access", "gunicorn.error"]:
        _log = logging.getLogger(name)
        _log.handlers = [InterceptHandler()]
        _log.propagate = False

setup_loguru()

放在settings.py顶部或者原来日志配置信息全部删除后的地方

效果

相关推荐
markfeng81 天前
Python+Django+H5+MySQL项目搭建
python·django
QQ4022054962 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
百锦再2 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
starlaky2 天前
Django入门笔记
笔记·django
QQ5110082852 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php
WeiXin_DZbishe2 天前
基于django在线音乐数据采集的设计与实现-计算机毕设 附源码 22647
javascript·spring boot·mysql·django·node.js·php·html5
B站计算机毕业设计超人2 天前
计算机毕业设计Django+Vue.js高考推荐系统 高考可视化 大数据毕业设计(源码+LW文档+PPT+详细讲解)
大数据·vue.js·hadoop·django·毕业设计·课程设计·推荐算法
计算机程序猿学长2 天前
大数据毕业设计-基于django的音乐网站数据分析管理系统的设计与实现(源码+LW+部署文档+全bao+远程调试+代码讲解等)
大数据·django·课程设计
B站计算机毕业设计超人2 天前
计算机毕业设计Django+Vue.js音乐推荐系统 音乐可视化 大数据毕业设计 (源码+文档+PPT+讲解)
大数据·vue.js·hadoop·python·spark·django·课程设计
B站_计算机毕业设计之家2 天前
电影知识图谱推荐问答系统 | Python Django系统 Neo4j MySQL Echarts 协同过滤 大数据 人工智能 毕业设计源码(建议收藏)✅
人工智能·python·机器学习·django·毕业设计·echarts·知识图谱