-1

我正在建立一个读出系统,该系统从许多仪器中获取数据,并且需要将数据记录到日志文件中。该系统一次将运行数周,因此每天都应该有一个日志文件。由于这些仪器在这段时间内被操纵,它们也可能具有与其状态相关的日志文件。

有了这个,我就有了一个存储所有日志的目录,例如“C:/logs”。由于每天都会有多个日志文件,我想每天在日志文件夹中自动创建一个新的子目录,所以文件的结构类似于'C:/logs/20190814' for August 14, 'C:/logs/20190815' for the 15th,等等。然后,在每个日常目录中,我都会有许多日志文件,例如'data.log', 'instrument1.log', 'instrument2.log'等。

理想情况下,这些将在每天午夜翻转。

我一直在使用 Python Logging 模块来尝试创建这些日志文件。我已经能够实现TimedRotatingFileHandler,但问题是

(1) 我想根据日期更改日志文件所在的目录,但保持它们的标题相同(例如'C:/logs/20190814/data.log', 'C:/logs/20190815/data.log'

(2)TimedRotatingFileHandler不使用'%Y%m%d.log'扩展名保存文件,而是'.log.%Y%m%d'使用 . 我想每天创建一个新目录并开始在新一天的目录中写入新日志。

4

2 回答 2

0

使用来自另一个 StackOverflow 问题的框架,该框架与我所需要的类似但不完全是我所需要的,我能够获得我想要的行为。这是更新记录 TimedRotatingFileHandler 类的自定义类。

class MyTimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
def __init__(self, log_title, whenTo="midnight", intervals=1):
    self.when = whenTo.upper()
    self.inter = intervals
    self.log_file_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "logs"))
    if not os.path.isdir(self.log_file_path):
        os.mkdir(self.log_file_path)
    if self.when == "S":
        self.extStyle = "%Y%m%d%H%M%S"
    if self.when == "M":
        self.extStyle = "%Y%m%d%H%M"
    if self.when == "H":
        self.extStyle = "%Y%m%d%H"
    if self.when == "MIDNIGHT" or self.when == "D":
        self.extStyle = "%Y%m%d"

    self.dir_log = os.path.abspath(os.path.join(self.log_file_path, datetime.now().strftime(self.extStyle)))
    if not os.path.isdir(self.dir_log):
        os.mkdir(self.dir_log)
    self.title = log_title
    filename = os.path.join(self.dir_log, self.title)
    logging.handlers.TimedRotatingFileHandler.__init__(self, filename, when=whenTo, interval=self.inter, backupCount=0, encoding=None)
    self._header = ""
    self._log = None
    self._counter = 0

def doRollover(self):
    """
    TimedRotatingFileHandler remix - rotates logs on daily basis, and filename of current logfile is time.strftime("%m%d%Y")+".txt" always
    """
    self.stream.close()
    # get the time that this sequence started at and make it a TimeTuple
    t = self.rolloverAt - self.interval
    timeTuple = time.localtime(t)

    self.new_dir = os.path.abspath(os.path.join(self.log_file_path, datetime.now().strftime(self.extStyle)))

    if not os.path.isdir(self.new_dir):
        os.mkdir(self.new_dir)
    self.baseFilename = os.path.abspath(os.path.join(self.new_dir, self.title))
    if self.encoding:
        self.stream = codecs.open(self.baseFilename, "w", self.encoding)
    else:
        self.stream = open(self.baseFilename, "w")

    self.rolloverAt = self.rolloverAt + self.interval
于 2019-08-16T18:48:37.717 回答
0

这是一个例子:

import logging
import time

from logging.handlers import TimedRotatingFileHandler

#----------------------------------------------------------------------
def create_timed_rotating_log(path):
""""""
logger = logging.getLogger("Rotating Log")
logger.setLevel(logging.INFO)

handler = TimedRotatingFileHandler(path,
                                   when="m",
                                   interval=1,
                                   backupCount=5)
logger.addHandler(handler)

for i in range(6):
    logger.info("This is a test!")
    time.sleep(75)

#----------------------------------------------------------------------
if __name__ == "__main__":
log_file = "timed_test.log"
create_timed_rotating_log(log_file)

此示例将每分钟轮换一次日志,备份计数为 5。更现实的轮换可能是每小时,因此您可以将间隔设置为 60 或将时间设置为“h”。运行此代码时,它也会创建 6 个文件,但不是将整数附加到日志文件名,而是使用 strftime 格式 %Y-%m-%d_%H-%M-%S 附加时间戳。

于 2019-08-14T22:28:19.317 回答