日志¶

Flask 使用标准 Python logging 。所有 Flask 相关消息都记录于'flask' 日志记录器命令空间。Flask.logger 可返回名为 'flask.app' 的日志记录器,可用于应用的日志记录。:

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

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

基本配置¶

当想要为项目配置日志时,应当在程序启动时尽早进行配置。如果完了,那么 app.logger 就会成为缺省记录器。如果有可能的话,应当在创建应用对象之前配置日志。

这个例子使用 dictConfig() 来创建一个类似于 Flask 缺省配置的日志记录配置:

  1. from logging.config import dictConfig
  2.  
  3. dictConfig({
  4. 'version': 1,
  5. 'formatters': {'default': {
  6. 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
  7. }},
  8. 'handlers': {'wsgi': {
  9. 'class': 'logging.StreamHandler',
  10. 'stream': 'ext://flask.logging.wsgi_errors_stream',
  11. 'formatter': 'default'
  12. }},
  13. 'root': {
  14. 'level': 'INFO',
  15. 'handlers': ['wsgi']
  16. }
  17. })
  18.  
  19. app = Flask(__name__)

缺省配置¶

如果没有自己配置日志, Flask 会自动添加一个StreamHandlerapp.logger 。在请求过程中,它会写到由 WSGI 服务器指定的,保存在environ['wsgi.errors'] 变量中的日志流(通常是 sys.stderr )中。在请求之外,则会记录到 sys.stderr

移除缺省配置¶

如果在操作 app.logger 之后配置日志,并且需要移除缺省的日志记录器,可以导入并移除它:

  1. from flask.logging import default_handler
  2.  
  3. app.logger.removeHandler(default_handler)

把出错信息通过电子邮件发送给管理者¶

当产品运行在一个远程服务器上时,可能不会经常查看日志信息。 WSGI 服务器可能会在一个文件中记录日志消息,而你只会在当用户告诉你出错的时候才会查看日志文件。

为了主动发现并修复错误,可以配置一个logging.handlers.SMTPHandler ,用于在一般错误或者更高级别错误发生时发送一封电子邮件:

  1. import logging
  2. from logging.handlers import SMTPHandler
  3.  
  4. mail_handler = SMTPHandler(
  5. mailhost='127.0.0.1',
  6. fromaddr='server-error@example.com',
  7. toaddrs=['admin@example.com'],
  8. subject='Application Error'
  9. )
  10. mail_handler.setLevel(logging.ERROR)
  11. mail_handler.setFormatter(logging.Formatter(
  12. '[%(asctime)s] %(levelname)s in %(module)s: %(message)s'
  13. ))
  14.  
  15. if not app.debug:
  16. app.logger.addHandler(mail_handler)

这需要在同一台服务器上拥有一个 SMTP 服务器。关于配置日志的更多内容请参阅Python 文档。

注入请求信息¶

看到更多请求信息,如 IP 地址,有助调试某些错误。可以继承logging.Formatter 来注入自己的内容,以显示在日志消息中。然后,可以修改 Flask 缺省的日志记录器、上文所述的电子邮件日志记录器或者其他日志记录器的格式器。:

  1. from flask import request
  2. from flask.logging import default_handler
  3.  
  4. class RequestFormatter(logging.Formatter):
  5. def format(self, record):
  6. record.url = request.url
  7. record.remote_addr = request.remote_addr
  8. return super().format(record)
  9.  
  10. formatter = RequestFormatter(
  11. '[%(asctime)s] %(remote_addr)s requested %(url)s\n'
  12. '%(levelname)s in %(module)s: %(message)s'
  13. )
  14. default_handler.setFormatter(formatter)
  15. mail_handler.setFormatter(formatter)

其他库¶

其他库可能也会产生大量日志,而你也正好需要查看这些日志。最简单的方法是向根记录器中添加记录器。:

  1. from flask.logging import default_handler
  2.  
  3. root = logging.getLogger()
  4. root.addHandler(default_handler)
  5. root.addHandler(mail_handler)

单独配置每个记录器更好还是只配置一个根记录器更好,取决你的项目。:

  1. for logger in (
  2. app.logger,
  3. logging.getLogger('sqlalchemy'),
  4. logging.getLogger('other_package'),
  5. ):
  6. logger.addHandler(default_handler)
  7. logger.addHandler(mail_handler)

Werkzeug¶

Werkzeug 记录基本的请求/响应信息到 'werkzeug' 日志记录器。如果根记录器没有配置,那么 Werkzeug 会向记录器添加一个 StreamHandler

Flask 扩展¶

根据情况不同,一个扩展可能会选择记录到app.logger 或者其自己的日志记录器。具体请查阅扩展的文档。

原文: https://dormousehole.readthedocs.io/en/latest/logging.html