本节所讲内容:
1、logger 介绍和作用
2、logger日志的操作方法
3、封装自己的logger日志
1、logger 介绍和作用
一些大型的程序都有记录日志的需求,用来记录程序运行中出现的各种警示,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;
为什么不用print打印输出?
Print大法对于简单脚本型程序有用,但是如果是复杂的系统,最好不要用。
首先,print是没用的输出,大量使用很有可能会被遗忘在代码里。
再者,print 输出的所有信息都到了标准输出中,这将严重影响到你从标准输出中查看其它输出数据。
使用logging的优势:
a)可以控制消息的级别,过滤掉那些并不重要的消息。
b) 可决定输出到什么地方,以及怎么输出。有许多的重要性别级可供选择,debug、info、warning、error 以及 critical [ˈkrɪtɪkl]:严重的。通过赋予 logger 或者 handler 不同的级别,你就可以只输出错误消息到特定的记录文件中,或者在调试时只记录调试信息。
1.Logger中常建错误预先展示
更常见的情形是把信息记录在log文件里。需要用logging.basicConfig()设置文件名以及level等参数,常见的level见下表。
Level | Value | Usage |
CRITICAL | 50 | 严重错误,表明程序已不能继续运行了 |
ERROR | 40 | 严重的问题,程序已不能执行一些功能了 |
WARNING | 30 | 有意外,将来可能发生问题,但依然可用 |
INFO | 20 | 证明事情按预期工作 |
DEBUG | 10 | 详细信息,调试问题时会感兴趣 |
如果设置level为INFO,那么DEBUG级别的信息就不会输出。
常见的函数接口有debug(), info(), warning(), error(),critical()
分别对应log不同严重级别的信息。
代码:
import logging
#配置logger日志基础
# logging.basicConfig(level=logging.DEBUG)
#详细信息,用于调试
logging.debug('this is debug')
#证明事情按照预期工作
logging.info('this is info')
#有意外,可能出现问题,但程序依旧可以运行
logging.warning('this is warning')
#严重问题,程序不能执行一些功能
logging.error('this is error')
#严重错误,程序已经不能继续运行
logging.critical('this is critical')
运行结果如下:
你却惊讶的发现,上面代码中明明写了5条数据输出,但是只有3条展示出来,这是为啥?
这个logger中有过滤系统,毕竟普通的debug和info 不太重要,也不是错误操作
那我们怎么能够把5条用例全部打印出来?
Logging提供了一个basicConfig方法:为日志模块配置基本信息。kwargs 支持如下几个关键字参数:
filename :日志文件的保存路径。如果配置了些参数,将自动创建一个FileHandler作为Handler;
filemode :日志文件的打开模式。 默认值为’a’,表示日志消息以追加的形式添加到日志文件中。如果设为’w’, 那么每次程序启动的时候都会创建一个新的日志文件;
format :设置日志输出格式;
datefmt :定义日期格式;
level :设置日志的级别.对低于该级别的日志消息将被忽略;
stream :设置特定的流用于初始化StreamHandler
具体代码入下:
#配置logger日志基础
logging.basicConfig(level=logging.DEBUG)
具体代码如下
import logging
#配置logger日志基础
logging.basicConfig(level=logging.DEBUG)
#详细信息,用于调试
logging.debug('this is debug')
#证明事情按照预期工作
logging.info('this is info')
#有意外,可能出现问题,但程序依旧可以运行
logging.warning('this is warning')
#严重问题,程序不能执行一些功能
logging.error('this is error')
#严重错误,程序已经不能继续运行
logging.critical('this is critical')
运行结果如下:
Logger 日志写入文件中
import logging
#配置logger日志基础
logging.basicConfig(filename='example.log',level=logging.DEBUG,filemode='a')
#详细信息,用于调试
logging.debug('this is debug')
#证明事情按照预期工作
logging.info('this is info')
#有意外,可能出现问题,但程序依旧可以运行
logging.warning('this is warning')
#严重问题,程序不能执行一些功能
logging.error('this is error')
#严重错误,程序已经不能继续运行
logging.critical('this is critical')
运行结果如下:
配置logger日志的时间
import logging
#配置logger日志基础
logging.basicConfig(format='%(asctime)s:%(message)s',datefmt='%m/%d/%Y %I:%M:%S %p',filename='example.log',level=logging.DEBUG,filemode='a')
#详细信息,用于调试
logging.debug('this is debug')
#证明事情按照预期工作
logging.info('this is info')
#有意外,可能出现问题,但程序依旧可以运行
logging.warning('this is warning')
#严重问题,程序不能执行一些功能
logging.error('this is error')
#严重错误,程序已经不能继续运行
logging.critical('this is critical')
运行结果如下:
3、更丰富的Log控制
上面的代码大部分是利用默认配置,其实我们自定义更多。比如把输出到terminal和log.txt文件
Logger 记录器,暴露了应用程序代码能直接使用的接口。
Handler 处理器,将(记录器产生的)日志记录发送至合适的目的地。
Filter 过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。
Formatter 格式化器,指明了最终输出中日志记录的布局。
首先,创建一个logger,记录器,然后给其添加不同的handler,输出到不同的渠道,比如下面这个例子就会生成log.txt文件,同时输出到console。
import logging
# create logger with name
# if not specified, it will be root
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
# create a handler, write to log.txt
# logging.FileHandler(self, filename, mode='a', encoding=None, delay=0)
# A handler class which writes formatted logging records to disk files.
fh = logging.FileHandler('log.txt')
fh.setLevel(logging.DEBUG)
# create another handler, for stdout in terminal
# A handler class which writes logging records to a stream
sh = logging.StreamHandler()
sh.setLevel(logging.DEBUG)
# set formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
sh.setFormatter(formatter)
# add handler to logger
logger.addHandler(fh)
logger.addHandler(sh)
# log it
logger.debug('Debug')
logger.info('Info')
运行结果如下:
import logging
class MyLog:
def my_log(self,msg,level):
#logger 收集日志
#haddler #输出日志的渠道
#定义一个日志收集器
my_logger = logging.getLogger('python')
#设定级别,收集日志
my_logger.setLevel('DEBUG')
#定义一个输出渠道
ch = logging.StreamHandler()
ch.setLevel('DEBUG')
#文本格式
formatter = logging.Formatter('%(asctime)s-%(levelname)s-%(filename)s-%(name)s-日志信息:%(message)s')
#输出到文本
fh = logging.FileHandler('py.txt',encoding='utf-8')
fh.setLevel('DEBUG')
fh.setFormatter(formatter)
#两者对接
my_logger.addHandler(ch)
my_logger.addHandler(fh)
#收集日志
if level == 'DEBUG':
my_logger.debug(msg)
elif level == 'INFO':
my_logger.info(msg)
elif level == 'ERROR':
my_logger.error(msg)
elif level == 'WARNING':
my_logger.warning(msg)
else:
my_logger.critical(msg)
#关闭日志收集,关闭渠道
my_logger.removeHandler(ch)
my_logger.removeHandler(fh)
def debug(self,msg):
self.my_log(msg,'DEBUG')
def error(self,msg):
self.my_log(msg,'ERROR')
def info(self,msg):
self.my_log(msg,'INFO')
if __name__ == '__main__':
MyLog().debug('哎呦我')
MyLog().my_log('哎呦妈呀2','ERROR')
MyLog().my_log('哎呦妈呀3','ERROR')
总结:
1、logger 介绍和作用
2、logger日志的操作方法
3、封装自己的logger日志