logging多进程报错:PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问

最好在午夜更新

import os
import logging
from logging.handlers import TimedRotatingFileHandler


# 这个只能指定文件大小进行切割?
# from concurrent_log_handler  import ConcurrentRotatingFileHandler


class MyTimedRotatingFileHandler(TimedRotatingFileHandler):
    def rotate(self, source, destination):
        if not callable(self.rotator):
            # Issue 18940: A file may not have been created if delay is True.
            self.new_rename(destination, source)
        else:
            self.rotator(source, destination)

    @staticmethod
    def new_rename(destination, source):
        """整体思路避免直接rename当前日志文件,我们先创建新的rotate备份文件,
        将当前日志文件内容复制到这个备份文件中去,然后清空当前日志文件
        缺点是读写过程中的日志可能会漏掉,建议午夜时间进行rotate备份
        """
        if os.path.exists(source):
            with open(destination, "wb+") as fw:
                with open(source, "rb+") as fr:
                    fw.write(fr.read())
            with open(source, "w+") as fw:
                fw.write("###\n")


class Logger:
    def __init__(self, name=None, filename="./log"):
        self.logger = logging.getLogger(name)
        self.logger.setLevel(level=logging.DEBUG)
        # 防止动态加载或多模块导入时重复加载此模块导致的打印重复日志的问题
        if self.logger.hasHandlers():
            self.logger.handlers.clear()

        formatter = logging.Formatter(
            '%(asctime)s-[P]%(process)s-%(filename)s:%('
            'funcName)s:%(lineno)s-%(levelname)s-[msg]%(message)s')

        # 添加文件打印handler
        # 创建TimedRotatingFileHandler处理对象
        file_handler = MyTimedRotatingFileHandler(
            filename=filename, when='midnight', backupCount=30, encoding="utf-8")
        # 设置日志文件后缀,以当前时间作为日志文件后缀名,
        # 一定要符合如下的时间格式,精确到秒的就when的最小单位就只能是S,同理
        file_handler.suffix = "%Y-%m-%d_%H-%M-%S"
        file_handler.setLevel(logging.DEBUG)
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)

        # 添加console打印handler
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(formatter)
        console_handler.setLevel(logging.DEBUG)
        self.logger.addHandler(console_handler)


logger = Logger(name="test", filename="log_test.log").logger

if __name__ == "__main__":
    logger.info("Start print log")
    logger.debug("Do something")
    logger.warning("Something maybe fail.")

时间后缀格式和when对应如下:

 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+)?$"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值