Когда FLASK_ENV=разработка, Werkzeug не регистрирует HTTP-запросы

#python #flask #logging #flask-restful

#python #flask #ведение журнала #flask-restful

Вопрос:

Я работаю над простым API-интерфейсом Flask-RESTful, в котором я новичок, и столкнулся с некоторыми проблемами с протоколированием.

При export FLASK_ENV=development этом регистратор Werkzeug не регистрирует никаких HTTP-запросов, таких как GET, POST и т.д. Когда export FLASK_ENV=production все нормально, и пара простых журналов может выглядеть так:

 2020-12-30 14:01:03,723 | INFO | werkzeug | 127.0.0.1 - - [30/Dec/2020 14:01:03] "GET /list/2 HTTP/1.1" 200 -
2020-12-30 14:01:03,742 | INFO | werkzeug | 127.0.0.1 - - [30/Dec/2020 14:01:03] "PUT /list/2 HTTP/1.1" 201 -
2020-12-30 14:01:03,749 | INFO | werkzeug | 127.0.0.1 - - [30/Dec/2020 14:01:03] "DELETE /list/2 HTTP/1.1" 204 -
 

Основная проблема, вероятно, исходит от my logging.dictConfig in my logger.py , поскольку при использовании простого logging.basicConfig логи создаются как обычно. Мой logger.py выглядит так:

 import logging as log
from logger.config import dictConfig

dictConfig(
    {
        "version": 1,
        "formatters": {
            "precise": {
                "format": "%(asctime)s | %(levelname)s | %(name)s | %(module)s | %(message)s"
            },
            "brief": {"format": "%(asctime)s | %(levelname)s | %(message)s"},
        },
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
                "stream": "ext://sys.stdout",
                "formatter": "brief",
                "level": "WARNING",
            },
            "file": {
                "class": "logging.handlers.RotatingFileHandler",
                "formatter": "precise",
                "filename": "logs/api.log",
                "maxBytes": 1024 ** 2,
                "backupCount": 1,
            },
        },
        "root": {"level": "DEBUG", "handlers": ["console", "file"]},
    }
)
 

В моем __init__.py I import log это означает, что я могу создавать журналы с помощью log.info() etc. in create_app() или других модулей.

Однако, согласно документации Flask(https://flask.palletsprojects.com/en/1.1.x/logging /), это также может быть вызвано временем моей конфигурации:

Базовая конфигурация
Если вы хотите настроить ведение журнала для своего проекта, вы должны сделать это как можно скорее при запуске программы. Если app.logger к is обращаются до настройки ведения журнала, он добавит обработчик по умолчанию. Если возможно, настройте ведение журнала перед созданием объекта приложения.

И я заметил, что Werkzeug регистрирует что-то перед любым из моих журналов, когда export FLASK_ENV=development . Я просто удивлен, что это может быть так, поскольку при использовании logging.basicConfig для его настройки он работает как шарм. И первое, что я делаю __init__.py , это импортирую регистратор; это означает, что я не могу сделать это раньше..

Ответ №1:

Я только что столкнулся с той же проблемой, и, пытаясь обойти ее, я обнаружил неидеальное, но работоспособное решение.

  1. Установите пакет logging_tree . Используется logging_tree.printout() для печати полного дерева регистрации.
  2. Для меня в рабочей среде logger "werkzeug" имеет желаемую конфигурацию, но в случае среды разработки тот же регистратор не имеет конфигурации, что приводит к отсутствию ведения журнала.
  3. Чтобы решить эту проблему, добавьте "werkzeug" logger к вашим регистраторам в dictConfig

Мой dictConfig :

 logging_config = dict(
    version=1,
    formatters={
        "file": {"format": LOG_DETAILED_FORMAT},
        "simple_console": {
            "()": "coloredlogs.ColoredFormatter",
            "format": LOG_SIMPLE_FORMAT,
        },
    },
    handlers={
        "server_console": {
            "level": logging.INFO,
            "class": "logging.StreamHandler",
            "formatter": "simple_console",
        },
        "file": {
            "level": logging.WARNING,
            "class": "logging.handlers.RotatingFileHandler",
            "filename": LOG_FILE_NAME,
            "formatter": "file",
            "maxBytes": 1024 * 1024 * 100,  # ~100 MB
            "backupCount": 10,
        }
    },
    loggers={
        "": {  # Root logger
            "handlers": ["server_console", "file"],
            "level": logging.INFO,
            "propagate": False,
        },
        "werkzeug": {  # Flask
            "handlers": ["server_console", "file"],
            "level": logging.INFO,
            "propagate": False,
        },
    },
)
 

После этой настройки единственное различие, которое я вижу между ведением журнала производства и разработки, — это первый журнал об IP-адресе сервера, на котором он запущен. При производстве этот журнал настраивается желаемым образом, но при разработке это просто обычная печать. После этого нет никакой разницы в ведении журнала.