日志

烧瓶采用标准 Python logging . 有关烧瓶应用程序的消息记录在 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 。

移除缺省配置

如果在访问后配置了日志记录,并且需要移除缺省的日志记录器,可以导入并移除它::

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 或者其自己的日志记录器。具体请查阅扩展的文档。