Django的基础知识这里没有
需求:
我的需求是这样。日志文件每5M一个文件,超过5M要滚动。另外,还有安装时间滚动,比如超过了凌晨12点,就要新起一个日志文件。目前Django提供的有按照文件大小滚动的,有按照时间滚动的,但是两个结合起来,就需要自己实现了。
直接代码
下面展示一些 内联代码片
。
import datetime
import logging
import os
import time
try:
from secrets import randbits
except ImportError:
import random
# 日志
class MyLogHandler(logging.FileHandler):
# 切文件的时间
rolloverTime = 0
def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False):
if maxBytes > 0:
mode = 'a'
super().__init__(filename, mode, encoding, delay)
self.maxBytes = maxBytes
self.backupCount = backupCount
self.namer = None
self.rotator = None
def emit(self, record):
"""
Emit a record.
Output the record to the file, catering for rollover as described
in doRollover().
"""
try:
if self.shouldRollover(record):
self.doRollover()
logging.FileHandler.emit(self, record)
except Exception:
self.handleError(record)
# 切文件
def doRollover(self):
"""
Do a rollover, as described in __init__().
"""
if self.stream:
self.stream.close()
self.stream = None
if self.backupCount > 0:
for i in range(self.backupCount - 1, 0, -1):
sfn = self.rotation_filename("%s-%d.log" % (self.baseFilename.split(".")[0], i))
dfn = self.rotation_filename("%s-%d.log" % (self.baseFilename.split(".")[0], i + 1))
if os.path.exists(sfn):
if os.path.exists(dfn):
os.remove(dfn)
os.rename(sfn, dfn)
dfn = self.rotation_filename(self.baseFilename.split(".")[0] + "-1.log")
if os.path.exists(dfn):
os.remove(dfn)
self.rotate(self.baseFilename, dfn)
if not self.delay:
self.stream = self._open()
def shouldRollover(self, record):
if self.stream is None: # delay was set...
self.stream = self._open()
##########################################################################################
# 根据日期滚动
##########################################################################################
if self.rolloverTime == 0:
d = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
d = d + datetime.timedelta(days=1)
self.rolloverTime = d
if datetime.datetime.now() > self.rolloverTime:
# 过了凌晨,要滚动文件
log_path = os.path.join("C:\\edata\\logs\\", time.strftime('%Y-%m-%d'))
if not os.path.exists(log_path):
os.mkdir(log_path) # 如果不存在这个logs文件夹,就自动创建一个
self.baseFilename = os.path.join(log_path, '{}.log'.format(time.strftime('%Y-%m-%d')))
self.rolloverTime = 0
return True
##########################################################################################
# 根据文件大小滚动
##########################################################################################
if self.maxBytes > 0: # are we rolling over?
msg = "%s\n" % self.format(record)
self.stream.seek(0, 2) # due to non-posix-compliant Windows feature
if self.stream.tell() + len(msg) >= self.maxBytes:
return True
return False
def rotation_filename(self, default_name):
if not callable(self.namer):
result = default_name
else:
result = self.namer(default_name)
return result
def rotate(self, source, dest):
if not callable(self.rotator):
# Issue 18940: A file may not have been created if delay is True.
if os.path.exists(source):
os.rename(source, dest)
else:
self.rotator(source, dest)