压缩日志文件,当它达到10个备份计数时,使用Python。

huangapple go评论71阅读模式
英文:

zip log files after it reach 10 backup count python

问题

以下是您提供的内容的翻译部分:

我正在尝试在日志处理程序中的备份计数达到10次时对日志进行压缩。我在检查文件大小并创建新文件时会检查每个日志文件。现在,如果已创建了10个文件,那么对于下一个文件,它应该压缩所有日志并删除所有10个日志文件,然后开始下一个新文件,直到再次达到10个文件。

以下是我尝试过的内容:

class CompressedRotatingFileHandler(logging.handlers.RotatingFileHandler):
    def doRollover(self):
        """
        执行卷动,就像在__init__()中描述的那样。
        """
        
        if self.backupCount > 0:
            for i in range(self.backupCount - 1, 0, -1):
                sfn = "%s.%d.gz" % (self.baseFilename, i)
                dfn = "%s.%d.gz" % (self.baseFilename, i + 1)
                if os.path.exists(sfn):
                    # print "%s -> %s" % (sfn, dfn)
                    if os.path.exists(dfn):
                        os.remove(dfn)
                    os.rename(sfn, dfn)
            dfn = self.baseFilename + ".1.gz"
            if os.exists(dfn):
                os.remove(dfn)
            # 下面的两行是唯一的新行。我注释掉了os.rename(self.baseFilename, dfn)并用这两行替换它。
            with open(self.baseFilename, 'rb') as f_in, gzip.open(dfn, 'wb') as f_out:
                shutil.copyfileobj(f_in, f_out)
            # os.rename(self.baseFilename, dfn)
            # print "%s -> %s" % (self.baseFilename, dfn)
        self.mode = 'w'

if __name__ == '__main__':
    name = 'test.log'
    logging.basicConfig(level=logging.INFO, filename=name, filemode="a+",
                format="%(asctime)-15s %(levelname)-8s %(message)s")
    log = logging.getLogger()
    handler = CompressedRotatingFileHandler(name, maxBytes=2000, backupCount=10)
    ii = 0
    while True:
        logging.debug("Test {0}".format(ii))
        ii += 1

请注意,我已将HTML编码的引号(")还原为正常的引号。这是您提供的Python代码,其中包括自定义的CompressedRotatingFileHandler类,用于处理日志文件的滚动和压缩。如果您需要更多帮助或有其他问题,请随时提出。

英文:

I am trying to zip logs once it reaches 10 backup counts in logging handler. Each log file am checking file size and am creating new file. Now if 10 files are getting created, for next file it should zip all logs and delete all 10 log files and start next new file till 10 files again.

Here is what I tried:

class CompressedRotatingFileHandler(logging.handlers.RotatingFileHandler):
    def doRollover(self):
        """
        Do a rollover, as described in __init__().
        """
        
        if self.backupCount > 0:
            for i in range(self.backupCount - 1, 0, -1):
                sfn = "%s.%d.gz" % (self.baseFilename, i)
                dfn = "%s.%d.gz" % (self.baseFilename, i + 1)
                if os.path.exists(sfn):
                    # print "%s -> %s" % (sfn, dfn)
                    if os.path.exists(dfn):
                        os.remove(dfn)
                    os.rename(sfn, dfn)
            dfn = self.baseFilename + ".1.gz"
            if os.path.exists(dfn):
                os.remove(dfn)
            # These two lines below are the only new lines. I commented out the os.rename(self.baseFilename, dfn) and
            #  replaced it with these two lines.
            with open(self.baseFilename, 'rb') as f_in, gzip.open(dfn, 'wb') as f_out:
                shutil.copyfileobj(f_in, f_out)
            # os.rename(self.baseFilename, dfn)
            # print "%s -> %s" % (self.baseFilename, dfn)
        self.mode = 'w'

if __name__ == '__main__':
    name = 'test.log'
    logging.basicConfig(level=logging.INFO, filename=name, filemode="a+",
				format="%(asctime)-15s %(levelname)-8s %(message)s")
    log = logging.getLogger()
    handler = CompressedRotatingFileHandler(name, maxBytes=2000, backupCount=10)
    ii = 0
    while True:
        logging.debug("Test {0}".format(ii))
        ii += 1

But, I am not getting what I am expecting.

答案1

得分: 1

当执行rollover操作时,您需要创建一个包含所有test.log.XX文件的.zip文件,然后删除它们。如果没有10个test.log.XX文件,您应该执行创建它们的正常行为。

doRollover方法如下所示:

import zipfile
import glob
import os

def doRollover(self):
    """
    执行rollover,如__init__()中所述。
    """
    # 从备份文件中创建.zip文件

    # 计算已经存在的test.log.XXX文件数量
    log_files = [
        f"{self.baseFilename}.{i}"
        for i in range(1, self.backupCount + 1)
        if os.path.exists(f"{self.baseFilename}.{i}")
    ]

    # 计算已经存在的backup.XXX.zip文件的数量,以避免覆盖现有文件。
    nzip_backups = len(glob.glob('backup.*.zip'))

    # 如果有10(self.backupCount)个test.log.XXX文件,创建zip并删除这些文件
    if len(log_files) == self.backupCount:
        with zipfile.ZipFile(f"backup.{nzip_backups + 1}.zip", "w") as myzip:
            for fn in log_files:
                if os.path.exists(fn):
                    myzip.write(fn, fn.split("/")[-1])
                    os.remove(fn)

    # 在所有情况下,都采用默认行为(复制test.log.4 -> test.log.5等)。
    # 不要重写它,只需重用父类的方法。
    super().doRollover()

此外,我还鼓励您不要使用根记录器(使用log = logging.getLogger()logging.debug("XXX")),而是使用子记录器。在这里,我们将使用"foobar"记录器,使用logging.getLogger("foobar")。由于它尚不存在,我们为其指定了处理程序和正确的Formatter

将所有内容拼接在一起,得到如下代码:

import logging
import logging.handlers
import os
import time
import glob
import zipfile

class CompressedRotatingFileHandler(logging.handlers.RotatingFileHandler):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def doRollover(self):
        """
        执行rollover,如__init__()中所述。
        """
        # 从备份文件中创建.zip文件

        log_files = [
            f"{self.baseFilename}.{i}"
            for i in range(1, self.backupCount + 1)
            if os.path.exists(f"{self.baseFilename}.{i}")
        ]

        # 获取备份文件的数量
        nzip_backups = len(glob.glob('backup.*.zip'))

        if len(log_files) == self.backupCount:
            with zipfile.ZipFile(f"backup.{nzip_backups + 1}.zip", "w") as myzip:
                for fn in log_files:
                    if os.path.exists(fn):
                        myzip.write(fn, fn.split("/")[-1])
                        os.remove(fn)
                        time.sleep(1)

        super().doRollover()

if __name__ == '__main__':
    name = 'test.log'
    log = logging.getLogger("foobar")
    log.setLevel(logging.DEBUG)
    log.propagate = False
    handler = CompressedRotatingFileHandler(
        name, mode="a+", maxBytes=2000, backupCount=10
    )
    handler.setFormatter(
        logging.Formatter(
            "%(asctime)-15s %(levelname)-8s %(message)s"
        )
    )
    log.addHandler(handler)

    ii = 0
    while True:
        log.info(f"Test {ii}")
        time.sleep(0.3)
        ii += 1
英文:

When you do the rollover, you need to create a .zip file with all the test.log.XX, delete them. In case you don't have 10 test.log.XX files, you should do the normal behavior of creating them.

The doRollover method looks like this:

import zipfile
import glob
import os
def doRollover(self):
"""
Do a rollover, as described in __init__().
"""
# This creates the .zip file from the 10 backup files
# Count all the test.log.XXX that already exist
log_files = [
f"{self.baseFilename}.{i}"
for i in range(1, self.backupCount + 1)
if os.path.exists(f"{self.baseFilename}.{i}")
]
# Count all the backup.XXX.zip files that already exist
# to avoid overwriting one.
nzip_backups = len(glob.glob('backup.*.zip'))
# If there are 10 (self.backupCount) test.log.XXX files, create the zip and delete the files
if len(log_files) == self.backupCount:
with zipfile.ZipFile(f"backup.{nzip_backups + 1}.zip", "w") as myzip:
for fn in log_files:
if os.path.exists(fn):
myzip.write(fn, fn.split("/")[-1])
os.remove(fn)
# In all cases, resort to the default behavior
# (that copies test.log.4 -> test.log.5 etc.). Don't rewrite it,
# just reuse the parent class' method.
super().doRollover()

I also encourage you not to use the root logger (that you are using with log = logging.getLogger() and logging.debug("XXX")), but to use a child logger. Here, we will be using the "foobar" logger with logging.getLogger("foobar"). Since it does not already exist, we give it your handler and the correct Formatter.


By piecing everything together, it gives:

import logging
import logging.handlers
import os
import time
import glob
import zipfile


class CompressedRotatingFileHandler(logging.handlers.RotatingFileHandler):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def doRollover(self):
        """
        Do a rollover, as described in __init__().
        """

        # This creates the .zip file from the 10 backup files

        log_files = [
            f"{self.baseFilename}.{i}"
            for i in range(1, self.backupCount + 1)
            if os.path.exists(f"{self.baseFilename}.{i}")
        ]

        # get count of backup.XXX.zip
        nzip_backups = len(glob.glob('backup.*.zip'))

        if len(log_files) == self.backupCount:
            with zipfile.ZipFile(f"backup.{nzip_backups + 1}.zip", "w") as myzip:
                for fn in log_files:
                    if os.path.exists(fn):
                        myzip.write(fn, fn.split("/")[-1])
                        os.remove(fn)
                        time.sleep(1)

        super().doRollover()


if __name__ == '__main__':
    name = 'test.log'
    log = logging.getLogger("foobar")
    log.setLevel(logging.DEBUG)
    log.propagate = False
    handler = CompressedRotatingFileHandler(
        name, mode="a+", maxBytes=2000, backupCount=10
    )
    handler.setFormatter(
        logging.Formatter(
            "%(asctime)-15s %(levelname)-8s %(message)s"
        )
    )
    log.addHandler(handler)

    ii = 0
    while True:
        log.info(f"Test {ii}")
        time.sleep(0.3)
        ii += 1

huangapple
  • 本文由 发表于 2023年2月13日 23:53:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75438229.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定