日志记录¶
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 将自动向 app.logger
添加一个 StreamHandler
。在请求期间,它将写入 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='[email protected]',
toaddrs=['[email protected]'],
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
或其自己的命名记录器。有关详细信息,请参阅每个扩展的文档。