企业级 Django 日志配置示例
settings.py
日志配置
import os
from pathlib import PathBASE_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_loggers:
False
表示不屏蔽 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 等平台