繁体   English   中英

将标头写入python日志文件,但仅限于写入记录

[英]Write header to a python log file, but only if a record gets written

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

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

使用python 2.7.10,是否有一种理智的方法来在第一次写入不包含这些元素的记录时添加一行(或两行)?

我可以在使用它进行日志记录之前写入该文件,但如果我这样做,我最终会将日志留空但是标题。

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

Using test.fil with option 7
2015-11-01 13:57:58,045 :log_example: INFO     fn:main result:process 4 complete --7 knights said ni
2015-11-01 13:57:58,045 :log_example: INFO     fn:main result:process 3 complete --3 bunnies attacked

谢谢,

子类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."

该脚本应该在Python 2.7中运行。 如果“example.log”文件已存在,则不会重新创建标头。

日志源代码的该解决方案所需的知识发现这里和一般用途的Python记录包找到这里

我有一个更简单的想法。 以下只使用自定义格式化程序。 格式化的第一条消息会抛出一个标题记录,之后只进行正常的格式化。

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.")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM