企业级 Django 日志配置示例

settings.py 日志配置

复制代码
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

# 日志目录
LOG_DIR = os.path.join(BASE_DIR, "logs")
os.makedirs(LOG_DIR, exist_ok=True)

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,  # 不屏蔽已有的 logger
    'formatters': {
        'verbose': {  # 详细格式
            'format': '[{asctime}] [{levelname}] [{name}] '
                      '[PID:{process}] [TID:{thread}] '
                      '{message}',
            'style': '{',
            'datefmt': '%Y-%m-%d %H:%M:%S'
        },
        'simple': {  # 简单格式
            'format': '[{levelname}] {message}',
            'style': '{'
        },
        'json': {  # JSON 格式(方便 ELK/Splunk)
            'format': '{{"time": "{asctime}", "level": "{levelname}", '
                      '"logger": "{name}", "message": "{message}"}}',
            'style': '{',
            'datefmt': '%Y-%m-%dT%H:%M:%S'
        }
    },
    'handlers': {
        'console': {  # 控制台输出
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'info_file': {  # 普通业务日志
            'level': 'INFO',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join(LOG_DIR, 'app_info.log'),
            'when': 'midnight',  # 每天切割
            'backupCount': 30,   # 保留 30 天
            'encoding': 'utf-8',
            'formatter': 'verbose'
        },
        'error_file': {  # 错误日志
            'level': 'ERROR',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join(LOG_DIR, 'app_error.log'),
            'when': 'midnight',
            'backupCount': 60,
            'encoding': 'utf-8',
            'formatter': 'verbose'
        },
        'audit_file': {  # 审计日志(单独存)
            'level': 'INFO',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': os.path.join(LOG_DIR, 'audit.log'),
            'when': 'midnight',
            'backupCount': 180,  # 保留半年
            'encoding': 'utf-8',
            'formatter': 'json'
        }
    },
    'loggers': {
        'django': {  # Django 自带日志
            'handlers': ['console', 'info_file', 'error_file'],
            'level': 'INFO',
            'propagate': True
        },
        'audit': {  # 审计日志专用 logger
            'handlers': ['audit_file'],
            'level': 'INFO',
            'propagate': False
        },
        'myapp': {  # 业务日志
            'handlers': ['console', 'info_file', 'error_file'],
            'level': 'DEBUG',
            'propagate': False
        }
    }
}

基础路径和日志目录

复制代码
BASE_DIR = Path(__file__).resolve().parent.parent
LOG_DIR = os.path.join(BASE_DIR, "logs")
os.makedirs(LOG_DIR, exist_ok=True)
  • BASE_DIR:项目根目录路径。

  • LOG_DIR :日志文件存放目录(logs 文件夹)。

  • os.makedirs(..., exist_ok=True):如果目录不存在则创建,避免写日志时报错。

LOGGING 配置结构

Django 的 LOGGING 配置遵循 Python logging 模块的字典配置格式,主要分为:

  • version :固定为 1

  • disable_existing_loggersFalse 表示不屏蔽 Django 默认的日志器。

  • formatters:定义日志输出格式。

  • handlers:定义日志输出方式(控制台、文件等)。

  • loggers:定义具体的日志记录器(logger),指定用哪些 handler 和日志级别。

formatters(日志格式)

复制代码
'verbose': {  # 详细格式
    'format': '[{asctime}] [{levelname}] [{name}] '
              '[PID:{process}] [TID:{thread}] '
              '{message}',
    'style': '{',
    'datefmt': '%Y-%m-%d %H:%M:%S'
},
'simple': {  # 简单格式
    'format': '[{levelname}] {message}',
    'style': '{'
},
'json': {  # JSON 格式(方便 ELK/Splunk)
    'format': '{{"time": "{asctime}", "level": "{levelname}", '
              '"logger": "{name}", "message": "{message}"}}',
    'style': '{',
    'datefmt': '%Y-%m-%dT%H:%M:%S'
}
  • verbose:详细日志,包含时间、级别、logger 名称、进程 ID、线程 ID、消息。

  • simple:简化版,只显示级别和消息。

  • json:结构化 JSON 格式,方便日志收集系统(ELK、Splunk)解析。

handlers(日志输出方式)

复制代码
'console': {  # 控制台输出
    'level': 'DEBUG',
    'class': 'logging.StreamHandler',
    'formatter': 'simple'
},
'info_file': {  # 普通业务日志
    'level': 'INFO',
    'class': 'logging.handlers.TimedRotatingFileHandler',
    'filename': os.path.join(LOG_DIR, 'app_info.log'),
    'when': 'midnight',  # 每天切割
    'backupCount': 30,   # 保留 30 天
    'encoding': 'utf-8',
    'formatter': 'verbose'
},
'error_file': {  # 错误日志
    'level': 'ERROR',
    'class': 'logging.handlers.TimedRotatingFileHandler',
    'filename': os.path.join(LOG_DIR, 'app_error.log'),
    'when': 'midnight',
    'backupCount': 60,
    'encoding': 'utf-8',
    'formatter': 'verbose'
},
'audit_file': {  # 审计日志(单独存)
    'level': 'INFO',
    'class': 'logging.handlers.TimedRotatingFileHandler',
    'filename': os.path.join(LOG_DIR, 'audit.log'),
    'when': 'midnight',
    'backupCount': 180,  # 保留半年
    'encoding': 'utf-8',
    'formatter': 'json'
}
  • console:输出到终端,调试用。

  • info_file:业务日志,按天切割,保留 30 天。

  • error_file:错误日志,按天切割,保留 60 天。

  • audit_file:审计日志(安全相关),按天切割,保留半年,JSON 格式。

TimedRotatingFileHandler 会在每天午夜生成新文件,旧文件按 backupCount 保留。

loggers(日志记录器)

复制代码
'django': {  # Django 自带日志
    'handlers': ['console', 'info_file', 'error_file'],
    'level': 'INFO',
    'propagate': True
},
'audit': {  # 审计日志专用 logger
    'handlers': ['audit_file'],
    'level': 'INFO',
    'propagate': False
},
'myapp': {  # 业务日志
    'handlers': ['console', 'info_file', 'error_file'],
    'level': 'DEBUG',
    'propagate': False
}
  • django:Django 内部日志(SQL、请求等)。

  • audit:专门记录安全审计事件(登录、权限变更等)。

  • myapp:你的业务模块日志。

propagate 表示是否向上冒泡到父 logger,False 表示只用自己定义的 handlers。

使用方式

复制代码
import logging

# 业务日志
logger = logging.getLogger('myapp')
logger.info("用户访问首页")
logger.error("数据库连接失败", exc_info=True)

# 审计日志
audit_logger = logging.getLogger('audit')
audit_logger.info({
    "event": "login_success",
    "username": "admin",
    "ip": "192.168.1.10",
    "ua": "Mozilla/5.0 ..."
})

使用方法

1. 普通业务日志

复制代码
import logging
logger = logging.getLogger('myapp')

logger.info("用户访问首页")
logger.error("数据库连接失败", exc_info=True)

2. 审计日志(安全追踪)

复制代码
import logging
audit_logger = logging.getLogger('audit')

audit_logger.info({
    "event": "login_success",
    "username": user.username,
    "ip": request.META.get('REMOTE_ADDR'),
    "ua": request.META.get('HTTP_USER_AGENT')
})

审计日志会单独写入 logs/audit.log,且是 JSON 格式,方便后续接入 ELK/Splunk 分析。

企业级建议

  • 开发环境console 输出 DEBUG 级别,方便调试

  • 生产环境:文件日志为主,控制台只输出 WARNING 及以上

  • 日志切割 :用 TimedRotatingFileHandler 按天切割,防止单个文件过大

  • 安全日志:审计日志单独存储,且长期保留(半年或一年)

  • 集中化:生产环境建议把日志推送到 ELK、阿里云日志、腾讯 CLS 等平台

相关推荐
Teable任意门互动6 分钟前
多维表格本地化部署实践解析 企业如何实现数据自主可控路径
数据库·excel·钉钉·飞书·开源软件
You Only Live Once_211 分钟前
SQLite3部署与配置[WIN11]
数据库·sqlite
光泽雨11 分钟前
mysql体系结构
数据库·mysql
云飞云共享云桌面12 分钟前
8-10位研发3D(sw、ug、creo)画图如何共享一台工作站?
运维·服务器·网络·数据库·3d·电脑
TDengine (老段)18 分钟前
TDengine IDMP 事件 —— 事件模板
大数据·数据库·人工智能·时序数据库·tdengine·涛思数据
一只大袋鼠22 分钟前
数据库连接池从入门到精通(下):Druid 连接池使用与工具类封装
java·数据库·连接池
正在走向自律23 分钟前
时序数据库选型指南:在数据洪流中寻找坚实的锚点
数据库·时序数据库·apache iotdb
wljt26 分钟前
达梦数据库恢复数据
数据库·数据库开发
卓怡学长31 分钟前
基于 SpringBoot 的生活信息分享平台,从 0 到 1 完整实现(附源码 + 数据库)
java·数据库·spring boot·tomcat·maven
ID_1800790547332 分钟前
Python解析小红书(XHS)笔记评论 API,json数据返回参考
java·服务器·数据库