文章目录
开发的web项目需要记录日志,本来打算使用python中的logging模块,但是,进入flask的官网发现自带有日志模块,直接使用flask中的日志。
1、flask中的logging
flask中也有自己的日志模块,通过flask的实例(一般叫作app)能够直接调用日志模块,输出或者记录日志。有一个问题就是在蓝图中如何使用flask的日志模块呢?还记得flask中的current_app吗,这个current_app返回的就是该蓝图注册所在的flask实例。
# /flask_project/app/views.py
from flask import current_app
current_app.logger.error("错误开发")
current_app.logger.warnning("警告信息")
通过这个例子,我们应该明白,在flask中的蓝图要使用app(flask的实例)中的一些方法或者属性就需要用到current_app。
# /flask_project/app/__init__.py
# 应用工厂函数
def create_app(config_name):
app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
SECRET_KEY = os.urandom(16)
)
if config_name is None:
app.config.from_pyfile('config.py', silent=True)
else:
app.config.from_object(config[config_name])
try:
os.makedirs(app.instance_path)
except OSError:
pass
# 注册蓝图
from . import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
# /flask_project/app/main/__init__.py
# 创建蓝图
from flask import Blueprint
main = Blueprint('main', __name__)
from . import views
# /flask_project/manage.py
import logging
from app import create_app
from flask_script import Manager, Shell
# 日志文件的保存路径
log_file_path = '/home/test/flask_project/logs/test.log'
# 创建handler(日志处理器), 指定了输出路径
handler = logging.FileHandler(log_file_path, encoding='UTF-8')
# 设置日志输出格式
formatter = logging.Formatter(
fmt="%(asctime)s %(name)s %(filename)s %(funcName)s %(lineno)d %(message)s",
datefmt="%Y-%m-%d %X"
)
# 为handler(处理器)指定输出的日志格式
handler.setFormatter(formatter)
# 为handler(处理器)指定终端输出的日志等级,即只有级别大于等于logging.WARNING的日志才会在终端输出
handler.setLevel(logging.WARNING)
app = create_app('development')
# 为此应用的日志记录器中添加一个handler(处理器)
app.logger.addHandler(handler)
manager = Manager(app)
if __name__ == '__main__':
manager.run()
什么是StreamHandler?什么是FileHandler?
简单的讲,我们需要输出信息到控制台,也需要记录日志在文件中,那么就要同时使用这两个handler。
StreamHandler用于控制输出到控制台的信息。
FileHandler用于控制记录到文件的信息。
通过上面的这些脚本就实现了,既能打印日志到控制台(并且能够控制日志输出的级别和输出的格式),还能记录日志到指定的文件当中。在测试过程中发现,记录到文件的日志是没有问题的,但是打印到控制台的日志好像仍然是最初的样子,并没有根据我的配置而改变这是为什么呢?
在阅读flask官方文档-日志的时候发现里面是这样说明的。
缺省配置
如果没有自己配置日志, 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)
很明显,我们是在flask应用实例创建之后在添加的handler,因此,在flask应用实例创建的时候已经使用了缺省配置,添加了一个StreamHandler到app.logger了,所以我们必须移除这个default_handler才能使用新的StreamHandler。
修改后的部分代码是:
# /flask_project/manage.py
import logging
from app import create_app
from flask_script import Manager, Shell
from flask.logging import default_handler
# 日志文件的保存路径
log_file_path = '/home/test/flask_project/logs/test.log'
# 创建handler(日志处理器), 指定了输出路径
file_handler = logging.FileHandler(log_file_path, encoding='UTF-8')
stream_handler = logging.StreamHandler()
# 设置日志输出格式
formatter = logging.Formatter(
fmt="%(asctime)s %(levelname)s %(filename)s %(funcName)s[line:%(lineno)d] %(message)s",
datefmt="%Y-%m-%d %X"
)
# 为handler(处理器)指定输出的日志格式
file_handler.setFormatter(formatter)
stream_handler.setFormatter(formatter)
# 为handler(处理器)指定终端输出的日志等级,即只有级别大于等于logging.WARNING的日志才会在终端输出
file_handler.setLevel(logging.INFO)
stream_handler.setLevel(logging.WARNING)
app = create_app('development')
# 先移除flask日志中默认的handler
app.logger.removerHandler(default_handler)
# 为此应用的日志记录器中添加一个handler(处理器)
app.logger.addHandler(file_handler)
app.logger.addHandler(stream_handler)
manager = Manager(app)
if __name__ == '__main__':
manager.run()
如果根据大小或者是时间来记录日志,那么是handler分别使用 RotatingFileHandler 和 TimedRotatingFileHandler 来实现。具体的使用方法请查看 官方使用说明-教程
# 每隔 1000 Byte 划分一个日志文件,备份文件为 3 个
file_handler = logging.handlers.RotatingFileHandler("test.log", mode="w", maxBytes=1000, backupCount=3, encoding="utf-8")
# 每隔 1小时 划分一个日志文件,interval 是时间间隔,备份文件为 10 个
handler2 = logging.handlers.TimedRotatingFileHandler("test.log", when="H", interval=1, backupCount=10)
参考文献
[1] Python日志库logging总结-可能是目前为止将logging库总结的最好的一篇文章
[2] Python 日志Logging详解
[3] Flask log配置,实现按照日期自动生成日志文件
[4] 官方使用说明-教程
[5] 官方使用说明-日志操作手册