一、常用日志记录场景及最佳解决方案:
日志记录方式 |
最佳记录日志方案 |
普通情况下,在控制台显示输出 |
print() |
报告正常程序操作过程中发生的事件 |
logging.info()(或者更详细的logging.debug()) |
发出有关特定事件的警告 |
warnings.warn()或者logging.warning() |
报告错误 |
弹出异常 |
在不引发异常的情况下报告错误 |
logging.error(), logging.exception()或者logging.critical() |
二、日志等级:
logging模块定义了下表所示的日志级别,按事件严重程度由低到高排列(注意是全部大写!因为它们是常量。):
级别 |
级别数值 |
使用时机 |
DEBUG |
10 |
详细信息,常用于调试 |
INFO |
20 |
程序正常运行过程中产生的一些信息 |
WARNING |
30 |
警告用户,虽然程序还在正常工作,但有可能发生错误 |
ERROR |
40 |
由于更严重的问题,程序已不能执行一些功能了 |
CRITICAL |
50 |
严重错误,程序已不能继续运行 |
三、logging基本使用方法:
产生五种日志级别(WARING、ERROR和CRITICAL会直接输出()内的提示语至屏幕):
logging.info('info')
logging.debug('debug')
logging.warning('warning')
logging.error('error')
logging.critical('critical')
日志系统配置文件(定义日志一些规则):
logging.basicConfig(filename='test.log', level=logging.INFO, filemode='a', format='%(levelname)s:%(asctime)s:%(message)s')
filename:日志要保存至哪个文件中(定义了这个后日志将不再在屏幕上打印)
level:什么级别以上的日志需要保存
filemode:有"w"、"a"两种模式,同open一样,"a"追加,"w"覆盖
format:定义日志格式(后面提供日志元素表,建议通过":"将各种日志元素连接成合理的日志格式)
format定义格式时用的日志元素表:
日志元素 |
描述 |
%(asctime)s |
日志产生的时间,默认格式为2003-07-08 16:49:45,896 |
%(created)f |
time.time()生成的日志创建时间戳 |
%(filename)s |
生成日志的程序名 |
%(funcName)s |
调用日志的函数名 |
%(levelname)s |
日志级别 ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL') |
%(levelno)s |
日志级别对应的数值 |
%(lineno)d |
日志所针对的代码行号(如果可用的话) |
%(module)s |
生成日志的模块名 |
%(msecs)d |
日志生成时间的毫秒部分 |
%(message)s |
具体的日志信息 |
%(name)s |
日志调用者 |
%(pathname)s |
生成日志的文件的完整路径 |
%(process)d |
生成日志的进程ID(如果可用) |
%(processName)s |
进程名(如果可用) |
%(thread)d |
生成日志的线程ID(如果可用) |
%(threadName)s |
线程名(如果可用) |
四、logging高级用法(让日志即能写入文件又能在屏幕打印):
包含关系(左边包含右边):
记录器<——处理器<——格式化器
import logging
"""
logging模块采用了模块化设计,主要包含四种组件:
Loggers:记录器,提供应用程序代码能直接使用的接口;
Handlers:处理器,将记录器产生的日志发送至目的地;
Filters:过滤器,提供更好的粒度控制,决定哪些日志会被输出;
Formatters:格式化器,设置日志内容的组成结构和消息字段。
"""
# 创建一个记录器loggers,并设置默认等级
logger = logging.getLogger('jack') # ‘jack’位置定义了日志调用者的名字
logger.setLevel(logging.INFO)
# 创建两个处理器handlers(一个发往日志文件、一个发往屏幕),并分别设置他们的日志等级
stream = logging.StreamHandler() # 发往屏幕
stream.setLevel(logging.DEBUG) # 定义什么样级别以上的日志发往屏幕
file = logging.FileHandler('test.log') # 发往日志文件(需指定文件名称)
file.setLevel(logging.ERROR) # 定义什么样级别以上的日志发往日志文件
# 分别为两个处理器handlers创建格式化器formatters(可以让其在屏幕和日志文件中以不同的格式输出)
formatter_stream = logging.Formatter('%(levelname)s:%(asctime)s:%(message)s')
formatter_file = logging.Formatter('%(name)s:%(levelname)s:%(asctime)s:%(message)s')
# 为各个处理器handlers设置相应的格式化器
stream.setFormatter(formatter_stream)
file.setFormatter(formatter_file)
# 将所有的处理器handler加入自定义的记录器logger内
logger.addHandler(stream)
logger.addHandler(file)
# 测试日志功能
logger.debug('debug')
logger.info('info')
logger.warning('warn')
logger.error('error')
logger.critical('critical')