如何解决Django控制台logging日志输出多余空行的问题
问题根本原因
- 日志Handler重复注册:Django主进程已为root logger配置了控制台输出Handler,子进程启动时调用
logging.basicConfig会额外新增一个指向stderr的StreamHandler,同一条日志会被两个Handler分别输出,各带一个默认换行符,就会出现隔行空行的问题。同时你配置了disable_existing_loggers=False,子进程会继承主进程的所有Logger配置,进一步加剧Handler重复叠加的问题。 - 第三方日志输出干扰:你贴出的异常日志里的
2021-08-24 11:30:58+0200 [-]是Twisted框架的默认日志格式,Twisted自身的日志输出也会往控制台打印内容,空行大多来自Twisted输出的无内容日志行。 - 输出流冲突:Django默认的StreamHandler输出到stdout,子进程的Handler输出到stderr,两个流同时往控制台输出时缓冲刷新不同步,也会产生多余换行。
解决步骤
1. 子进程启动时先清空已继承的日志Handler
修改子进程的日志配置代码,先清空所有旧Handler再配置新的,避免重复输出:
import logging import sys # 清空root logger继承自主进程的所有Handler for handler in logging.root.handlers[:]: logging.root.removeHandler(handler) # 再配置子进程自身的日志规则 logging.basicConfig( level=logging.DEBUG, format="%(name)s - %(levelname)s - %(message)s", stream=sys.stderr ) logging.getLogger("Player").setLevel(logging.DEBUG)
2. 调整Django settings的日志配置
在Django的LOGGING配置中新增Logger规则,屏蔽不需要的第三方日志输出、避免重复传播:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'simple': { 'format': '%(name)s - %(levelname)s - %(message)s', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'formatter': 'simple', # 统一输出到stderr,和子进程日志流保持一致避免冲突 'stream': 'ext://sys.stderr' }, }, 'root': { 'handlers': ['console'], 'level': 'DEBUG', }, 'loggers': { # 禁止Player模块的日志向上传播到root logger,避免重复输出 'Player': { 'handlers': [], 'propagate': False, 'level': 'DEBUG', }, # 屏蔽Twisted的日志输出,解决格式为xxxx-xx-xx [-] 的空行问题 'twisted': { 'handlers': [], 'propagate': False, } } }
3. 可选:修改Handler的行结束符
如果做完前两步还有多余空行,可以自定义StreamHandler的行结束符,取消默认的自动换行:
# 在console handler的配置中新增terminator参数 'console': { 'class': 'logging.StreamHandler', 'formatter': 'simple', 'stream': 'ext://sys.stderr', # 若日志内容本身已带换行,可将结束符设为空字符串 'terminator': '' }
内容的提问来源于stack exchange,提问作者Ehsan
相关产品推荐
相关产品推荐

