Django自定义日志滚动方案

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)

基本上是按照logging.handlers.RotatingFileHandler,只不过是加上了过了凌晨要换新的目录和新的文件而已logging.FileHandler一定要继承这个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值