代碼如下:
import logging, os, time, re
from stat import ST_MTIME
from logging.handlers import TimedRotatingFileHandler
# 自定義logger輸出格式的,因為logging自帶的TimedRotatingFileHandler輸出格式,我個人不太喜歡
class TimedHandler(TimedRotatingFileHandler):
def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None):
super(TimedHandler, self).__init__(filename, when, interval, backupCount, encoding, delay, utc, atTime)
self.when = when.upper()
self.backupCount = backupCount
self.utc = utc
self.atTime = atTime
"""
此處修改對應日志格式
"""
if self.when == 'S':
self.interval = 1 # one second
self.suffix = "%Y%m%d.%H%M%S"
self.extMatch = r"^\d{4}\d{2}\d{2}.\d{2}\d{2}\d{2}(\.\w+)?$"
elif self.when == 'M':
self.interval = 60 # one minute
self.suffix = "%Y%m%d.%H%M"
self.extMatch = r"^\d{4}\d{2}\d{2}.\d{2}\d{2}(\.\w+)?$"
elif self.when == 'H':
self.interval = 60 * 60 # one hour
self.suffix = "%Y%m%d.%H"
self.extMatch = r"^\d{4}\d{2}\d{2}.\d{2}(\.\w+)?$"
elif self.when == 'D' or self.when == 'MIDNIGHT':
self.interval = 60 * 60 * 24 # one day
self.suffix = "%Y%m%d"
self.extMatch = r"^\d{4}\d{2}\d{2}(\.\w+)?$"
elif self.when.startswith('W'):
self.interval = 60 * 60 * 24 * 7 # one week
if len(self.when) != 2:
raise ValueError("You must specify a day for weekly rollover from 0 to 6 (0 is Monday): %s" % self.when)
if self.when[1] < '0' or self.when[1] > '6':
raise ValueError("Invalid day specified for weekly rollover: %s" % self.when)
self.dayOfWeek = int(self.when[1])
self.suffix = "%Y%m%d"
self.extMatch = r"^\d{4}\d{2}\d{2}(\.\w+)?$"
else:
raise ValueError("Invalid rollover interval specified: %s" % self.when)
self.extMatch = re.compile(self.extMatch, re.ASCII)
self.interval = self.interval * interval # multiply by units requested
filename = self.baseFilename
if os.path.exists(filename):
t = os.stat(filename)[ST_MTIME]
else:
t = int(time.time())
self.rolloverAt = self.computeRollover(t)
def get_logger(file_name=None, log_path='logs', when='D', backup_count=3, level='warning'):
"""
:param file_name: 自定義log名稱(創建的log會放在此路徑下),None 會通過時間戳來創建文件夾
:param log_path: log的根目錄
:param when: 拆分日志的時間間隔:周(W)、天(D)、時(H)、分(M)、秒(S)切割。
:param backup_count: 保留拆分后最新的文件數量,比如如果為3,則表示保留3天內的日志,3天前的日志會被刪除;如果為0,則所有拆分的日志都會保存
:param level: 日志輸出等級,分為 info,debug,warning(warn),error 四個等級
:return: 返回logger對象,通過調用info,debug,error等方法可以寫入日志
"""
# 選擇日志輸出等級
level = level.lower()
logger_infos = {
'info': logging.INFO,
'debug': logging.DEBUG,
'warning': logging.WARNING,
'warn': logging.WARNING,
'error': logging.ERROR
}
cur_time = time.strftime('%Y%m%d.%H%M%S')
if file_name is None:
file_name = cur_time
logger = logging.getLogger(file_name)
logger.setLevel(logger_infos[level])
if file_name == cur_time: # 未傳入名稱的,以日期作為文件夾類別
log_file_path = os.path.join(log_path, file_name)
else: # 傳入名稱的,以傳入的名稱作為類別
log_file_path = os.path.join(log_path, file_name, cur_time)
if not os.path.exists(log_file_path):
os.makedirs(log_file_path)
file_name = os.path.join(log_file_path, 'log')
# 定義handler的輸出格式
formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
fh = TimedHandler(filename=file_name, when=when, backupCount=backup_count, encoding='utf-8')
fh.setFormatter(formatter)
logger.addHandler(fh) # 將logger添加到handler里面
return logger
if __name__ == '__main__':
# logger = get_logger(file_name='abcd', log_path='./logs', when='S', level='debug')
logger = get_logger(log_path='./logs', when='S', backup_count=2, level='debug')
for i in range(100):
logger.info(i)
time.sleep(0.1)
參考鏈接:https://www.cnblogs.com/mangM/p/11200987.html