2015-11-01 31 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