方法一:使用默认的日志收集器RootLogger,输出日志(默认输出WARN级别以上的日志)
1.import logging
from logging.handlers import RotatingFileHandler
2.设置2个handle
h1=RotatingFileHandler("root_log.log",encoding="utf-8",maxBytes=1024,backupCount=2)
h2=logging.StreamHandler()
3.设置日志输出格式
fmt = '%(asctime)s %(filename)s %(funcName)s [line:%(lineno)d] %(levelname)s %(message)s'
4.设置root logger
logging.basicConfig(level='INFO',format=fmt,handlers=[h1,h2])
logging.info('111111111111111111')
方法二:普通做法,封装一个日志类
缺点:代码多,且日志中显示的lineno,为MyLogger类中封装的对应方法,不能精确到具体报错代码行
import logging
from logging.handlers import RotatingFileHandler
class MyLogger:
def __init__(self, name='my_logger', filename='test.log', encoding='utf-8'):
self.logger = logging.getLogger(name)
self.logger.setLevel(logging.INFO)
fmt = '%(asctime)s %(filename)s %(funcName)s [line:%(lineno)d] %(levelname)s %(message)s'
ft = logging.Formatter(fmt)
h1 = RotatingFileHandler(filename,encoding=encoding,maxBytes=1024*1024*10,backupCount=10)
h1.setFormatter(ft)
h2 = logging.StreamHandler()
h2.setFormatter(ft)
# 将handle添加到logger
self.logger.addHandler(h1)
self.logger.addHandler(h2)
def debug(self, msg):
return self.logger.debug(msg)
def info(self,msg):
return self.logger.info(msg)
def warning(self,msg):
return self.logger.warning(msg)
def error(self,msg):
return self.logger.error(msg)
def critical(self,msg):
return self.logger.critical(msg)
def exception(self,msg):
return self.logger.exception(msg)
logger = MyLogger()
logger.error('error') # 日志中显示的行数为47行,即error方法;实际应该显示为57行
方法三:在2的基础上,继承logging.Logger
优点:解决了2中的代码过多问题;且解决了lineno问题,可以精确到具体的报错代码行
原因:Logger类已经封装好了debug,info...方法,继承后,直接使用即可,无需自己再定义
import logging
from logging.handlers import RotatingFileHandler
class MyLoggerV2(logging.Logger):
def __init__(self, name, level='DEBUG', file=None, encoding='utf-8'):
# 日志收集器
# self.logger = logging.getLogger(name)
super().__init__(name) # Logger(name)
# 级别
self.setLevel(level)
# 格式
fmt = '%(asctime)s %(filename)s %(funcName)s [line:%(lineno)d] %(levelname)s %(message)s'
ft = logging.Formatter(fmt)
# 初始化输出渠道
if file:
file_handle = RotatingFileHandler(file, encoding, maxBytes=1024*1024*10, backupCount=10)
file_handle.setLevel('INFO')
file_handle.setFormatter(ft)
self.addHandler(file_handle)
# 设置handle2
h2 = logging.StreamHandler()
h2.setFormatter(ft)
# 将handle添加到logger
self.addHandler(h2)
l = MyLoggerV2(name='haha', file='test1.log')
l.info('info级别')