方法一:使用默認的日志收集器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級別')