Python logging使用
快速配置
# -*- coding:utf-8 -*-
import logging
# 默认配置root logger
logging.basicConfig(filename='root.log', level=logging.INFO)
# 写入文件中
logging.debug('debug message') # 低于INFO级别,不输出
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')
通过Logger配置
当程序模块众多时,每个模块可以分别创建logger,更将灵活;
一个logger可以有多个FileHandler;
# -*- encoding:utf-8 -*-
import logging
# 创建一个名为example的logger
logger = logging.getLogger('example')
logger.setLevel(logging.DEBUG)
# 创建一个FileHandler,绑定到logger中
# 一个logger可以有多个FileHandler
fh1 = logging.FileHandler('warn.log')
fh1.setLevel(logging.WARN) # 记录warn级别
logger.addHandler(fh1)
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message') # 以下都输出到warn.log
logger.error('error message')
logger.critical('critical message')
# 再创建一个FileHandler,绑定到logger中
fh2 = logging.FileHandler('./error.log')
fh2.setLevel(logging.ERROR) # 记录error级别
logger.addHandler(fh2)
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message') # 以下都输出到warn.log、error.log
logger.critical('critical message')
Logger的层级关系
# -*- encoding:utf-8 -*-
import logging
import sys
# logging默认有root logger
print logging.root
print logging.getLogger()
print logging.getLogger() == logging.root
# 没有handler
print logging.root.handlers
# 一旦执行这个,就会自动添加stdout到handler中,下面两行等价
# logging.basicConfig(stream=sys.stdout, level=logging.WARN)
logging.warn('warn message')
print logging.root.handlers
# 新建的logger,默认是root的孩子
child = logging.getLogger('child')
print child.parent
print child.handlers
# 消息会自低向顶传到root
# 一条标准输出来自root
child.error('error message')
child.addHandler(logging.StreamHandler())
# 一条标准输出来自child;一条标准输出来自root
child.error('error message')
# 自动解析层次结果;root->child->descendant
descendant = logging.getLogger('child.descendant')
Flask logging配置
# 需要:将所有输出都重定向到一个文件中;
# 查看flask logging文档
# Werkzeug logs basic request/response information to the 'werkzeug' logger.
# 所以需要在root logger指定日志文件handler;让Werkzeug接收的record向上传递到root中的handler
logging.basicConfig(filename=filename, filemode='w', level=logging.INFO)
# 同时,程序运行时可能会报错,需要将stdout与stderr重定向到日志文件中。
# 不能再使用handler,因为stdout也是filehandler,不存在handler绑定logger的
# 似乎更好的选择是用两个日志文件: nohup command > error.log 2>&1 &
sys.stdout = sys.stderr = open(filename, "a")