最近突然发现个好东西---logging,以前写日志还是自己写的辛辛苦苦的写print,以及write写到文件中去。最近有个需求要自动切换日志,这个想了好久都没有想到实现方式,就百度了一下。python自己就带了这么些库,这就尴尬了。记录下来,以后再也不做这傻事了。
一、打印
python提供了一个标准的日志接口,就是logging模块。日志级别有DEBUG、INFO、WARNING、ERROR、CRITICAL五种(级别依次升高),分别对应的函数为debug()、info()、warning()、error()、critical()。
实例
import logging
if __name__ == '__main__':
print('this is main !')
logging.debug('this is a debug level message')
logging.info("this is a info level message")
logging.warning("this is a warning level message")
logging.error("this is a error level message")
logging.critical("this is a critical level message")
二、写文件
通过basicConfig函数写文件。
logging.basicConfig函数各参数:
filename: 指定日志文件名
filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a'
format: 指定输出的格式和内容,format可以输出很多有用信息,如上例所示:
%(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcName)s: 打印日志的当前函数
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
%(message)s: 打印日志信息
datefmt: 指定时间格式,同time.strftime()
level: 设置日志级别,默认为logging.WARNING
stream: 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略
实例
import logging
import time
from logging.handlers import RotatingFileHandler
import os, sys
class loger:
def __init__(self):
self.log_format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s: %(message)s'
if not os.path.exists("./log/"):
os.mkdir("./log/")
self.log_filename = "./log/error_log.txt"
self.write_log_Onefilename()
def write_log_Onefilename(self):
#只写在一个文件
filename = self.log_filename.format(time.strftime("%Y-%m-%d",time.localtime(time.time())))
logging.basicConfig(filename=filename, format=self.log_format, datefmt='%Y-%m-%d %H:%M:%S:%S %p', filemode='a+', level=logging.INFO)
if __name__ == '__main__':
print('this is main !')
logging.debug('this is a debug level message')
logging.info("this is a info level message")
logging.warning("this is a warning level message")
logging.error("this is a error level message")
logging.critical("this is a critical level message")
三、自动切换日志写入文件
RotatingFileHander模块,用于自动切换日志写入文件,保证单个日志文件不会太大。
构造函数是:
RotatingFileHandler(filename[, mode[, maxBytes[, backupCount]]])
filename: 指定日志文件名
filemode: 和file函数意义相同,指定日志文件的打开模式,'w'或'a'
maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
实例
import logging
import time
from logging.handlers import RotatingFileHandler
import os, sys
class loger:
def __init__(self):
self.log_format = '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s: %(message)s'
if not os.path.exists("./log/"):
os.mkdir("./log/")
self.log_filename = "./log/error_log.txt"
self.write_log_file()
def write_log_file(self):
logging.getLogger().setLevel(logging.DEBUG)
#打印到控制台
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)#设置控制台日志输出的级别。如果设置为logging.INFO,就不会输出DEBUG日志信息
console.setFormatter(logging.Formatter(self.log_format))
logging.getLogger().addHandler(console)
#自动换文件
handler = logging.handlers.RotatingFileHandler(filename=self.log_filename, maxBytes=500, backupCount=5)
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter(self.log_format))
logging.getLogger().addHandler(handler)
if __name__ == '__main__':
print('this is main !')
logging.debug('this is a debug level message')
logging.info("this is a info level message")
logging.warning("this is a warning level message")
logging.error("this is a error level message")
logging.critical("this is a critical level message")
四、遇到的问题
1、debug级别没有打印
if __name__ == '__main__':
print('this is main !')
logging.debug('this is a debug level message')
logging.info("this is a info level message")
logging.warning("this is a warning level message")
logging.error("this is a error level message")
logging.critical("this is a critical level message")
打印如下:
原因:
可以发现debug()和info()方法没有显示任何信息,这是因为默认的日志级别是WARNING,所以低于此级别的日志不会记录。
解决方案
logging.getLogger().setLevel(logging.DEBUG)
#或者
logging.getLogger().setLevel(logging.INFO)
注意:info的级别比debug高
结束语
以上就是python自带日志库的用法。最后给大家推介一个技术公众号,欢迎大家来留言交流技术。