Spec-Zone.ru › Flask 2.3

Ведение журнала

Flask использует стандартный Python logging. Сообщения о вашем приложении Flask записываются с помощью app.logger, который использует то же имя, что и app.name. Этот логгер также можно использовать для записи собственных сообщений.

@app.route('/login', methods=['POST'])
def login():
    user = get_user(request.form['username'])

    if user.check_password(request.form['password']):
        login_user(user)
        app.logger.info('%s logged in successfully', user.username)
        return redirect(url_for('index'))
    else:
        app.logger.info('%s failed to log in', user.username)
        abort(401)

Если вы не настраиваете ведение журнала, по умолчанию уровень ведения журнала Python обычно равен ‘warning’. Ничего ниже настроенного уровня отображаться не будет.

Основная настройка

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

В этом примере используется dictConfig() для создания конфигурации ведения журнала, аналогичной по умолчанию для Flask, за исключением всех записей:

from logging.config import dictConfig

dictConfig({
    'version': 1,
    'formatters': {'default': {
        'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
    }},
    'handlers': {'wsgi': {
        'class': 'logging.StreamHandler',
        'stream': 'ext://flask.logging.wsgi_errors_stream',
        'formatter': 'default'
    }},
    'root': {
        'level': 'INFO',
        'handlers': ['wsgi']
    }
})

app = Flask(__name__)

Конфигурация по умолчанию

Если вы не настраиваете ведение журнала самостоятельно, Flask автоматически добавит StreamHandler к app.logger. Во время запросов он будет записывать в поток, указанный сервером WSGI в environ['wsgi.errors'] (обычно это sys.stderr). Вне запроса он будет записывать в sys.stderr.

Удаление обработчика по умолчанию

Если вы настраивали ведение журнала после доступа к app.logger и вам нужно удалить обработчик по умолчанию, вы можете импортировать и удалить его:

from flask.logging import default_handler

app.logger.removeHandler(default_handler)

Отправка ошибок по электронной почте администраторам

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

Для того, чтобы быть проактивными в обнаружении и устранении ошибок, вы можете настроить logging.handlers.SMTPHandler для отправки электронной почты при записи ошибок и более серьезных сообщений.

import logging
from logging.handlers import SMTPHandler

mail_handler = SMTPHandler(
    mailhost='127.0.0.1',
    fromaddr='server-error@example.com',
    toaddrs=['admin@example.com'],
    subject='Application Error'
)
mail_handler.setLevel(logging.ERROR)
mail_handler.setFormatter(logging.Formatter(
    '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
))

if not app.debug:
    app.logger.addHandler(mail_handler)

Это требует наличия SMTP-сервера на том же сервере. Подробную информацию о настройке обработчика см. в документации Python.

Вставка информации о запросе

Просмотр дополнительной информации о запросе, например, IP-адреса, может помочь в отладке некоторых ошибок. Вы можете создать подкласс logging.Formatter, чтобы вставлять свои поля, которые могут использоваться в сообщениях. Вы можете изменить форматтер для обработчика по умолчанию Flask, обработчика электронной почты, определенного выше, или любого другого обработчика.

from flask import has_request_context, request
from flask.logging import default_handler

class RequestFormatter(logging.Formatter):
    def format(self, record):
        if has_request_context():
            record.url = request.url
            record.remote_addr = request.remote_addr
        else:
            record.url = None
            record.remote_addr = None

        return super().format(record)

formatter = RequestFormatter(
    '[%(asctime)s] %(remote_addr)s requested %(url)s\n'
    '%(levelname)s in %(module)s: %(message)s'
)
default_handler.setFormatter(formatter)
mail_handler.setFormatter(formatter)

Другие библиотеки

Другие библиотеки могут активно использовать ведение журнала, и вы также хотите видеть соответствующие сообщения из этих журналов. Самый простой способ сделать это — добавить обработчики в корневой логгер, а не только в логгер приложения.

from flask.logging import default_handler

root = logging.getLogger()
root.addHandler(default_handler)
root.addHandler(mail_handler)

В зависимости от вашего проекта, может быть более полезно настроить каждый логгер, который вас интересует, отдельно, вместо настройки только корневого логгера.

for logger in (
    app.logger,
    logging.getLogger('sqlalchemy'),
    logging.getLogger('other_package'),
):
    logger.addHandler(default_handler)
    logger.addHandler(mail_handler)

Werkzeug

Werkzeug записывает основную информацию о запросе/ответе в логгер 'werkzeug'. Если у корневого логгера нет настроенных обработчиков, Werkzeug добавляет StreamHandler к своему логгеру.

Расширения Flask

В зависимости от ситуации, расширение может выбрать запись в app.logger или в свой собственный логгер с именем. Обратитесь к документации каждого расширения для получения подробной информации.

© 2007–2022 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.3.x/logging/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API