写代码容易,但是调代码难,可以说 20% 的时间在写代码,但是 80% 的时间是在调试代码,解决代码中的 BUG。要想更好得改进这个比例,那么我们就应该提高解决程序 BUG 的效率,首先第一步就是要能快速定位出 BUG 的位置以及触发原因。

我们在开发的时候还好,可以快速得获得各种需要的信息,但是,如果代码到了线上才发现 BUG,这个时候就不好解决的,此时,我们便需要求助于 BUG 发生的环境恢复,但是,显然重现很多时候是很困难的,是不现实的,那么这个时候,良好的编程习惯便帮助良多了,假设这个时候有一份日志告诉你故障发生时的各个变量和参数是什么,以及报了什么异常这类的,估计解决问题也就不远了。

没错,这一篇文章是讲讲日志了,如果你有关注我的博客的话,应该会见过一篇文章叫做:《logging模块学习》,那么这两篇文章有什么不同呢?

其实,没什么不同,这是这篇文章是在原有文章的层次上更封装了一层,《logging模块学习》这篇文章主要是讲解 python 标准库中原生的 logging 模块如何使用,而这篇文章呢,主要是讲解在 flask 框架中使用 logging 模块,本质上没有太大区别,但是,因为集成进了框架,所以也就有更多的内容了,大家下面听我慢慢讲解。

配置logging

跟使用 logging 一样,使用之前肯定要想配置一番,告诉 logging 日志文件放哪?要以哪种方式存放等等,下面简单上一个配置:

import os
import logging
import logging.handlers

# log configure
app.logger.setLevel(logging.INFO)
info_log = os.path.join(app.root_path, .., /log, app-info.log)
info_file_handler = logging.handlers.RotatingFileHandler(
    info_log, maxBytes=1048576, backupCount=20)
info_file_handler.setLevel(logging.INFO)
info_file_handler.setFormatter(
    logging.Formatter('%(asctime)s %(levelname)s: %(message)s '
                      '[in %(pathname)s:%(lineno)d]')
)
app.logger.addHandler(info_file_handler)


这便是简单得打印到文件的配置了,将这个配置放到你的项目中去,然后在需要打日志的地方这样写:

from flask import current_app

current_app.logger.info(Request index page:%s, request.args)


这个时候再去你的日志目录看,你会发现多了一个 app-info.log 的文件,里面可能会有这样的内容:

2015-10-23 22:43:37,881 INFO: Request index page:ImmutableMultiDict([]) [in E:...views.py:89]
2015-10-23 22:50:49,730 INFO: Request index page:ImmutableMultiDict([]) [in E:...views.py:89]
2015-10-23 22:51:54,650 INFO: Request index page:ImmutableMultiDict([]) [in E:...views.py:89]


说明你的日志配置成功,并且成功运行了。

邮件日志通知

接下来,我们来尝试一下如何设置当程序出错时给我们的邮箱发错误邮件的配置。

ADMINS = ['liqianglau@outlook.com']
from logging.handlers import SMTPHandler
mail_handler = SMTPHandler('smtp.qq.com',
                           '12345678@qq.com',
                           ADMINS, 'YourApplication Failed',
                           ('12345678@qq.com', 'mypassword'))
mail_handler.setLevel(logging.ERROR)
mail_handler.setFormatter(
    logging.Formatter('%(asctime)s %(levelname)s: %(message)s '
                      '[in %(pathname)s:%(lineno)d]'))
app.logger.addHandler(mail_handler)


和之前的文件配置一样使用,还是简单的调用,然后这时 flask 既会自动往文件里面打 INFO 级别以上的日志,又会在遇到 ERROR 级别的日志时往我们的邮箱里面发送邮件了。

好的,今天的使用介绍就到此,虽然很简单得介绍了两段,但是,我相信已经能够帮助大家在项目中起到重大的作用了,尤其是出 BUG 而渺无头绪的时候。