企业级 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 等平台

相关推荐
yzx9910138 小时前
Django 配置与安装完整指南
数据库·django·sqlite
Archie_IT10 小时前
「深入浅出」嵌入式八股文—P2 内存篇
c语言·开发语言·数据结构·数据库·c++·算法
奥尔特星云大使10 小时前
mysql逻辑备份跟物理备份的区别
数据库·mysql·逻辑备份·物理备份·逻辑备份呢
程序定小飞10 小时前
基于springboot的蜗牛兼职网的设计与实现
java·数据库·vue.js·spring boot·后端·spring
Go高并发架构_王工11 小时前
NoSQL与MySQL混合架构设计:从理论到实践(二)
数据库·mysql·nosql
jingfeng51411 小时前
MySQL数据类型
数据库·mysql
matlab的学徒11 小时前
PostgreSQL 安装与操作指南
数据库·postgresql
sweethhheart11 小时前
【typora激活使用】mac操作方式
前端·数据库·macos
启明真纳14 小时前
PostgreSQL 单库备份
数据库·postgresql
Amd79414 小时前
PostgreSQL备份不是复制文件?物理vs逻辑咋选?误删还能精准恢复到1分钟前?
数据库·postgresql