即使使用 RotatingFileHandler,Django 也会一次记录到多个文件?

har*_*k24 2 python django python-3.x django-rest-framework python-logging

我使用 Django 进行日志记录配置如下:

LOGGING = {
    'version':1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{asctime} {process:d} {thread:d} {levelname} {name} {module} {funcName} {message}',
            'style': '{',
        }
    },
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': BASE_DIR+'/logs/django_logs.log',
            'backupCount': 14,
            'maxBytes': 52428800,
            'formatter': 'verbose'
        }
    },
    'loggers': {
        '': {
            'handlers': ['file'],
            'level': 'INFO'
        }
    },
}
Run Code Online (Sandbox Code Playgroud)

我正在运行 16 个 django 进程,几个用于 websocket 的 daphne 和几个用于基于 django Rest 框架的正常 API 调用的 Gunicorn 进程。但是当我查看日志时,会同时记录多个文件。例如,django_logs.1 .... django.logs.14 同时登录。我是否必须添加其他内容来一次记录到一个文件,并仅在其大小超过日志文件的指定大小时才轮换它?

有关额外信息,我使用 python 3.6.8 并在每个项目文件中初始化记录器,如下所示:

import logging
logger = logging.getLogger(__name__)
Run Code Online (Sandbox Code Playgroud)

小智 6

来自docs.python.logging-cookbook

尽管日志记录是线程安全的,并且支持从单个进程中的多个线程记录到单个文件,但不支持从多个进程记录到单个文件,因为没有标准方法来序列化跨多个进程对单个文件的访问。 Python 中的进程。如果您需要从多个进程记录到单个文件,一种方法是让所有进程记录到一个 SocketHandler,并有一个单独的进程来实现从套接字读取数据并将日志记录到文件的套接字服务器。(如果您愿意,可以在现有进程之一中专门指定一个线程来执行此功能。)

食谱中也详细介绍了这种方法的完整示例。请参阅本节

该文档还建议了此方法的一些替代方案:

或者,您可以使用 aQueue和 aQueueHandler将所有日志记录事件发送到多进程应用程序中的进程之一

我已经测试了您的日志记录配置,当一个独特的进程记录到文件处理程序时,它按预期工作。文件应仅在maxBytes达到时旋转