Как вести журнал в файл с помощью Django и Gunicorn? Использование TimedRotatingFileHandler пропускает логи

У меня есть приложение Django, которое регистрирует INFO с помощью TimedRotatingFileHandler. На сервере разработки он работает нормально, но при запуске в продакшене с помощью gunicorn не все строки журнала попадают в файл. Я также использую консольный обработчик, который корректно записывает все, и похоже, что файл, используемый TimedRotatingFileHandler, содержит только некоторые из этих строк и отбрасывает многое из того, что появляется из консольного логгера

Также он демонстрирует другое странное поведение; мой dictConfig регистрации имеет полуночное вращение. Я ожидал, что mylog.log будет писаться до полуночи, а затем его содержимое будет ротироваться в файл mylog.log. Это поведение при запуске на сервере разработки, который поставляется вместе с Django. Что происходит при запуске моего приложения с gunicorn, так это то, что оно постоянно пишет как в файл mylog.log, так и в файл mylog.log.2022-02-01. Содержимое mylog.log не появляется в другом файле. Это похоже на то, что журнал распределяется между mylog.log и mylog.log.2022-02-01 в течение дня...

Моя конфигурация:

    'handlers': {
        'console': {
            'level': 'INFO',
            'formatter': 'verbose',
            'class': 'logging.StreamHandler',
        },
        'file': {
            'level': 'INFO',
            'formatter': 'verbose',
            'filename': mylog.log,
            'when': 'midnight',
            'encoding': 'utf-8',
            'backupCount': 7,
            'class': 'logging.handlers.TimedRotatingFileHandler',
        },
    },
    'loggers': {
        '': {
            'handlers': ['console', 'file'],
            'level': level,
        },
    },

Проблема связана с тем, что рабочие gunicorn выполняются в другом процессе, а TimedRotatingFileHandler не работает с многопроцессорностью? Или плохая конфигурация?

Каков "стандартный" или предлагаемый способ вести журнал в файл внутри обработчика запроса в Django, в то время как приложение работает на gunicorn?

Возможно, это потому, что Python не поддерживает координацию между записью в один файл из нескольких процессов, поэтому материал может быть перезаписан. Я бы использовал либо SocketHandler, либо QueueHandler для всех модулей Django и вашего webapp, и имел бы отдельный процесс, слушающий {либо приемник сокета, либо QueueListener), который пишет в TimedRotatingFileHandler. В официальной документации есть поваренная книга , в которой приведены рецепты для сценария с несколькими процессами, включая рабочий код для приемников сокетов и т.д., который вы можете адаптировать под свои конкретные нужды. Я использую Supervisor для поддержания запущенного процесса слушателя.

Вернуться на верх