将头写入python日志文件,但仅当写入记录时

2024-04-28 04:38:03 发布

您现在位置:Python中文网/ 问答频道 /正文

fh = logging.FileHandler('example.log',delay = True)
fh.setLevel(logging.INFO)

由于delay为True,除非记录了一些内容,否则永远不会写入文件。 此时,文件中的第一行是第一条记录,它将包含asctime、levelname等元素

使用Python2.7.10,有没有一种方法可以在第一次写入不包含这些元素的记录时添加一行(或两行)?在

我可以在使用该文件进行日志记录之前先写入该文件,但如果我这样做,则日志将为空,但头文件除外。在

所需的输出可能如下所示:

^{pr2}$

谢谢


Tags: 文件infologtrue元素内容examplelogging
2条回答

将FileHandler子类化以创建您自己的自定义FileHandleWithHeader,如下所示:

import os
import logging

# Create a class that extends the FileHandler class from logging.FileHandler
class FileHandlerWithHeader(logging.FileHandler):

    # Pass the file name and header string to the constructor.
    def __init__(self, filename, header,  mode='a', encoding=None, delay=0):
        # Store the header information.
        self.header = header

        # Determine if the file pre-exists
        self.file_pre_exists = os.path.exists(filename)

        # Call the parent __init__
        logging.FileHandler.__init__(self, filename, mode, encoding, delay)

        # Write the header if delay is False and a file stream was created.
        if not delay and self.stream is not None:
            self.stream.write('%s\n' % header)

    def emit(self, record):
        # Create the file stream if not already created.
        if self.stream is None:
            self.stream = self._open()

            # If the file pre_exists, it should already have a header.
            # Else write the header to the file so that it is the first line.
            if not self.file_pre_exists:
                self.stream.write('%s\n' % self.header)

        # Call the parent class emit function.
        logging.FileHandler.emit(self, record)

# Create a logger and set the logging level.
logger = logging.getLogger("example")
logger.setLevel(logging.INFO)

# Create a file handler from our new FileHandlerWith Header class and set the
# logging level.
fh = FileHandlerWithHeader('example.log', 'This is my header',  delay=True)
fh.setLevel(logging.INFO)

# Add formatter to the file handler.
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh.setFormatter(formatter)

# Add the handler to the logger.
logger.addHandler(fh)

# Since the constructor of the FileHandlerWithHeader was passed delay=True
# the file should not exist until the first log as long as the log file did
# not pre-exist.
print "Ready to write to the the example.log file."
raw_input("Press Enter to continue...")

# Send 3 logs to the logger.
logger.info("First line in the file")
logger.info("Second line in the file")
logger.info("Third line in the file")

# The log file should now be created and only have a header at the begining of
# the file.
print "The example.log file should exist and have a header."

这个脚本应该像Python2.7中那样运行。如果示例.log“文件已存在,它不会重新创建头。在

此解决方案需要了解找到的日志源代码here 和一般使用python日志包找到here。在

我有个简单的想法。下面只使用一个自定义格式化程序。第一个格式化的消息会输出一个头记录,然后在这之后执行正常的格式化。在

import logging

class FormatterWithHeader(logging.Formatter):
    def __init__(self, header, fmt=None, datefmt=None, style='%'):
        super().__init__(fmt, datefmt, style)
        self.header = header # This is hard coded but you could make dynamic
        # Override the normal format method
        self.format = self.first_line_format

    def first_line_format(self, record):
        # First time in, switch back to the normal format function
        self.format = super().format
        return self.header + "\n" + self.format(record)

def test_logger():
    logger = logging.getLogger("test")
    logger.setLevel(logging.DEBUG)
    formatter = FormatterWithHeader('First Line Only')
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    ch.setFormatter(formatter)
    logger.addHandler(ch)
    logger.info("This line will kick out a header first.")
    logger.info("This line will *not* kick out a header.")

相关问题 更多 >