1,日志级别
DEBUG:打印调试信息,级别最低
INFO:打印正常的操作信息
WARNING:打印警告信息
ERROR:打印错误信息
CRITICAL:打印致命的错误信息,等级最高
测试程序
# -*- coding: utf-8 -*-
import logging
if __name__ == "__main__":
logging.debug('DEBUG级别')
logging.info('INFO级别')
logging.warning('WARNING级别')
logging.error('ERROR级别')
logging.critical('CRITICAL级别')
打印结果:
发现只输出下面三条信息,这是因为logging是分级别的,上面5个级别的信息从上到下依次递增,可以通过设置logging的level,使其只打印某个级别以上的信息。默认等级是 WARNING,所以只有 WARNING 以上级别的日志被打印出来。 如果想把debug和info也打印出来,可以使用 basicConfig 对其进行配置:
# -*- coding: utf-8 -*-
import logging
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG) #设置log默认级别为DEBUG
logging.debug('DEBUG级别')
logging.info('INFO级别')
logging.warning('WARNING级别')
logging.error('ERROR级别')
logging.critical('CRITICAL级别')
打印结果:添加logging.basicConfig(level=logging.DEBUG)设置日志级别,DEBUG及以上的日志级别被打印出来。
2,日志输出格式
%(name)s:Logger的名字
%(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:打印日志信息
如:filefmt = "%(asctime)s: %(levelname)s: [Func:%(funcName)s]: %(message)s: %(filename)s[line:%(lineno)d]"
打印日志格式如下:
3,日志输出到日志文件
最简单方式:
logging.basicConfig(format="%(asctime)s: %(levelname)s: [Func:%(funcName)s]: %(message)s: %(filename)s[line:%(lineno)d]", level=logging.DEBUG, filename="log.txt", filemode="a")
但是进行这样的操作之后,发现控制台不输出了,怎么做到既输出到控制台又写入到文件呢?
按照如下处理,既能输出到日志文件,又可以打印到控制台:完整程序如下
# -*- coding: utf-8 -*-
import logging
from logging import handlers
import os,time
# 设置日志打印格式
filefmt = "%(asctime)s: %(levelname)s: [Func:%(funcName)s]: %(message)s: %(filename)s[line:%(lineno)d]"
consolefmt = "%(asctime)s: %(levelname)s: [Func:%(funcName)s]: %(message)s: %(filename)s[line:%(lineno)d]"
class Logger(object):
def __init__(self, fileName, level=logging.DEBUG):
# 1:创建日志对象
# logging.basicConfig(level=logging.DEBUG) // 不能加这条配置,加上会打印重复信息
self.logger = logging.getLogger(fileName)
self.logger.setLevel(level=level)
path = os.path.dirname(os.path.abspath(__file__))
self.logFileName = os.path.join(path, fileName)
def file_handle(self):
# 创建日志文件句柄
file_handle = logging.FileHandler(filename=self.logFileName, mode="a", encoding="utf-8")
filefmatter = logging.Formatter(fmt=filefmt)
file_handle.setFormatter(fmt=filefmatter)
return file_handle
def console_handle(self):
# 1,控制台日志
console_handle = logging.StreamHandler()
# 2,设置控制台日志输出等级
console_handle.setLevel(level=logging.DEBUG)
# 3,设置文件日志格式
consolefmatter = logging.Formatter(fmt=consolefmt)
console_handle.setFormatter(fmt=consolefmatter)
return console_handle
def get_console_logfile_logger(self):
"""
获取日志管理器:将日志保存到日志文件同时打印到控制台
:return:
"""
self.logger.addHandler(self.file_handle())
self.logger.addHandler(self.console_handle())
return self.logger
def get_console_logger(self):
"""
获取日志管理器:仅将日志打印在控制台
:return:
"""
self.logger.addHandler(self.console_handle())
return self.logger
def get_file_logger(self):
"""
获取日志管理器:仅将日志添加到日志文件
:return:
"""
self.logger.addHandler(self.file_handle())
return self.logger
def get_auto_segmentation_logger_by_time(self, filename, when="D"):
"""
获取日志管理器:根据时间自动分割日志文件
:return:
"""
file_handler = handlers.TimedRotatingFileHandler(filename=filename, when=when)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(filefmt)
return file_handler
def get_auto_segmentation_logger_by_size(self, size=12328960):
"""
获取日志管理器:根据日志文件大小自动分割日志文件,默认10M=1024*1024*10
:return:
"""
file_handler = handlers.RotatingFileHandler(filename=self.logFileName, maxBytes=size)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(filefmt)
return file_handler
if __name__ == "__main__":
logger = Logger("log.txt").get_console_logfile_logger()
logger.debug('DEBUG:打印调试信息,级别最低')
logger.info('INFO:打印正常的操作信息')
logger.warning('WARNING:打印警告信息')
logger.error('ERROR:打印错误信息')
logger.critical('CRITICAL:打印致命的错误信息,等级最高')
上述Logger类中 get_console_logfile_logger()表示获取同时将日志打印到控制台和保存到日志文件,测试如下。
if __name__ == "__main__":
logger = Logger("log.txt").get_console_logfile_logger()
logger.debug('DEBUG:打印调试信息,级别最低')
logger.info('INFO:打印正常的操作信息')
logger.warning('WARNING:打印警告信息')
logger.error('ERROR:打印错误信息')
logger.critical('CRITICAL:打印致命的错误信息,等级最高')
日志文件信息:
控制台信息:
日志文件和控制台显示日志信息完全一致。也可以定制不同的显示格式。
4, 自动分割日志文件
当日志比较大或者时间比较久需要对日志文件进行分割,方便管理。python 提供了两个分割文件处理器:
logging.handlers.RotatingFileHandler : 按照大小自动分割日志文件,一旦达到指定的大小重新生成文件。
logging.handlers.TimedRotatingFileHandler:按照时间自动分割日志文件。
def get_auto_segmentation_logger_by_time(self,when="D"):
"""
获取日志管理器:根据时间自动分割日志文件
:return:
"""
file_handler = handlers.TimedRotatingFileHandler(filename=self.logFileName, when=when)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(filefmt)
self.logger.addHandler(file_handler)
return self.logger
def get_auto_segmentation_logger_by_size(self, size=12328960):
"""
获取日志管理器:根据日志文件大小自动分割日志文件,默认10M=1024*1024*10
:return:
"""
file_handler = handlers.RotatingFileHandler(filename=self.logFileName, maxBytes=size)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(filefmt)
self.logger.addHandler(file_handler)
return self.logger
测试按s自动分割日志文件:---自动分割日志没有调通,暂不可用
TimedRotatingFileHandler类参数详解如下: filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None #interval是时间间隔 #backupCount是备份文件的个数,如果超过这个个数,就会自动删除 #when是间隔的时间单位,单位有以下几种: # S 秒 # M 分 # H 小时、 # D 天、 # W 每星期(interval==0时代表星期一)