Spec-Zone.ru › Flask

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

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 обычно равен «предупреждение». Ничего ниже настроенного уровня отображаться не будет.

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

Когда вы хотите настроить ведение журнала для своего проекта, сделайте это как можно скорее при запуске программы. Если к 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 (
    logging.getLogger(app.name),
    logging.getLogger('sqlalchemy'),
    logging.getLogger('other_package'),
):
    logger.addHandler(default_handler)
    logger.addHandler(mail_handler)

Werkzeug

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

Flask Extensions

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

© 2010 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/stable/logging/

Spec-Zone.ru

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