2015-11-01 55 views
2
fh = logging.FileHandler('example.log',delay = True) 
fh.setLevel(logging.INFO) 

由于delay为true,因此除非记录日志,否则永远不会写入文件。 在这一点上,文件中的第一行是第一条记录,它将包含asctime,levelname等元素将标题写入python日志文件,但只有在写入记录时才有效

使用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

我的思绪马上就到子类logging.Formatter和具有格式化的第一条消息之后基本上改变其格式是written.At至少,这是哪里,如果你正在寻找的想法,我将开始。 – RobertB

回答

1

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

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

这和Joshua的解决方案在不同情况下都有优点。 如果标题只会出现在文件的开头,无论脚本运行多少次,约书亚的将是最好的。 罗伯特的答案在每次脚本运行时都会显示一个标题,即使它附加到现有的日志中,这更符合我的目的 - 尽管我一开始并没有这么想。 –

3

子类的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”文件已经存在,它将不会重新创建标题。

这个解决方案需要知道日志源代码here 和python日志包的一般用法here

相关问题