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

相关推荐
luoluoal12 小时前
基于python的爬虫的贵州菜价可视化系统(源码+文档)
python·mysql·django·毕业设计·源码
老华带你飞12 小时前
考试管理系统|基于java+ vue考试管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
九皇叔叔12 小时前
MySQL 数据库 MVCC 与锁如何联手解决脏读、不可重复读、幻读
数据库·mysql
WZTTMoon12 小时前
Spring Boot OAuth2 授权码模式开发实战
大数据·数据库·spring boot
AI题库13 小时前
PostgreSQL 18 从新手到大师:实战指南 - 1.1 PostgreSQL 18简介
数据库·postgresql
好记忆不如烂笔头abc13 小时前
Ubuntu 20.04.6上实现远程桌面连接
服务器·网络·数据库
今晚务必早点睡13 小时前
Redis——快速入门第七课:Redis 为什么这么快?
数据库·redis·缓存
EterNity_TiMe_13 小时前
从 0 到 1:Llama 3-8B 在昇腾 Atlas 800T 上的推理调优与算力榨干指南
数据库·llama·昇腾·atlas 800t·实战部署
talenteddriver13 小时前
mysql: MySQL中between子句和limit子句的区别
前端·javascript·数据库
不会kao代码的小王13 小时前
BoostKit 数据库优化原理分析从 MySQL 到 MariaDB 的性能突破
数据库·mysql·mariadb