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
谢谢,
答案 0 :(得分:6)
子类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"文件已经存在,它不会重新创建标题。
答案 1 :(得分:3)
我有一个更简单的想法。以下只使用自定义格式化程序。格式化的第一条消息会抛出一个标题记录,然后再进行正常的格式化。
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.")