Подтвердить что ты не робот

Почему приложение Flask не создает никаких журналов при размещении в Gunicorn?

Я пытаюсь добавить журнал в веб-приложение, которое использует флажок.

При размещении с использованием встроенного сервера (т.е. python3 server.py) выполняется ведение журнала. При размещении с использованием Gunicorn файл журнала не создается.

Самый простой код, который воспроизводит проблему, следующий:

#!/usr/bin/env python

import logging
from flask import Flask
flaskApp = Flask(__name__)


@flaskApp.route('/')
def index():
    flaskApp.logger.info('Log message')
    print('Direct output')
    return 'Hello World\n'


if __name__ == "__main__":
    logHandler = logging.FileHandler('/var/log/demo/app.log')
    logHandler.setLevel(logging.INFO)
    flaskApp.logger.addHandler(logHandler)
    flaskApp.logger.setLevel(logging.INFO)
    flaskApp.run()

Приложение вызывается с использованием:

gunicorn server:flaskApp -b :80 -w 4
    --access-gfile /var/log/demo/access.log
    --error-logfile /var/log/demo/error.log

При выполнении запроса на домашнюю страницу сайта происходит следующее:

  • Я получаю ожидаемый HTTP 200 "Hello World\n" в ответ.

  • В /var/log/demo/access.log есть трассировка запроса.

  • /var/log/demo/error.log остается неизменным (есть только события загрузки).

  • В терминале есть строка "Прямой выход".

  • Нет '/var/log/demo/app.log'. Если я создаю файл перед запуском приложения, файл не будет изменен.

Обратите внимание, что:

  • Доступ к каталогу /var/log/demo можно получить (чтение, запись, выполнение) всеми, так что это не проблема с разрешениями.

  • Если я добавлю StreamHandler в качестве второго обработчика, по-прежнему нет следа сообщения "Сообщение журнала" ни в терминале, ни в файлах журнала Gunicorn.

  • Gunicorn устанавливается с помощью pip3 install gunicorn, поэтому не должно быть никакого несоответствия с версиями Python.

Что происходит?

4b9b3361

Ответ 1

Когда вы используете python3 server.py, вы запустите server3.py script.

Когда вы используете gunicorn server:flaskApp ..., вы запускаете запуск gunicorn script, который затем импортирует модуль server и ищет переменную flaskApp в этом модуле.

Поскольку server.py импортируется, __name__ var будет содержать "server", а не "__main__", и поэтому код установки обработчика журнала не запускается.

Вы можете просто переместить код настройки обработчика журнала за пределы if __name__ == "__main__":. Но убедитесь, что вы держите flaskApp.run() там, так как вы не хотите, чтобы это было запущено, когда увольняющий противник импортировал server.

Подробнее о что делает if __name__ == "__main__":?

Ответ 2

Этот подход работает для меня: импортируйте модуль протоколирования Python и добавьте к нему обработчики ошибок gunicorn. Затем ваш регистратор войдет в файл журнала ошибок gunicorn:

import logging

app = Flask(__name__)

gunicorn_error_logger = logging.getLogger('gunicorn.error')
app.logger.handlers.extend(gunicorn_error_logger.handlers)
app.logger.setLevel(logging.DEBUG)
app.logger.debug('this will show in the log')

My Gunicorn startup script настроен для вывода записей журнала в файл следующим образом:

gunicorn main:app \
    --workers 4 \
    --bind 0.0.0.0:9000 \
    --log-file /app/logs/gunicorn.log \
    --log-level DEBUG \
    --reload