2010-07-20 58 views
35

我試圖找到一個很好的方式來使用python實時讀取日誌文件。我希望在寫入日誌文件時逐行處理一行。不知何故,我需要不斷嘗試讀取文件,直到它被創建,然後繼續處理行,直到我終止該過程。有沒有適當的方法來做到這一點?謝謝。從日誌文件中讀取,因爲它正在使用Python編寫

+0

這個也很好......我認爲它符合你的標準,並提供一個可以輕鬆擴展的類。 [http://code.activestate.com/recipes/577968-log-watcher-tail-f-log/](http://code.activestate.com/recipes/577968-log-watcher-tail-f-log /) – mogga 2012-10-23 18:55:15

回答

20

你可以用這樣的嘗試:

import time 

while 1: 
    where = file.tell() 
    line = file.readline() 
    if not line: 
     time.sleep(1) 
     file.seek(where) 
    else: 
     print line, # already has newline 

例子來自here提取。

+0

這似乎是工作,但它不會允許我在我的Django應用程序中同時創建對象或寫入數據庫。我沒有看到明顯的原因。有一個簡單的修復? – Anon 2010-07-20 19:37:12

+0

我不知道。我想你應該在一個單獨的問題中發佈一些代碼來獲得這個答案。我沒有看到任何理由不讓數據庫更新,如果你把這個代碼放在這個... – 2010-07-20 21:16:20

+0

得到這個工作,但我不得不把它弄亂了字符串之前,我可以把它寫入我的數據庫。謝謝。 – Anon 2010-07-21 18:23:43

-1

也許你可以做一個系統調用來

tail -f 

使用使用os.system()

32

看看this PDF開始在38頁,幻燈片〜I-77,你會發現所有的你需要的信息。當然幻燈片的其餘部分是驚人的,也是如此,但是那些專門與您的問題處理:

import time 
def follow(thefile): 
    thefile.seek(0,2) # Go to the end of the file 
    while True: 
     line = thefile.readline() 
     if not line: 
      time.sleep(0.1) # Sleep briefly 
      continue 
     yield line 
+4

值得注意的是,這會跳過日誌文件中的任何內容,只會在創建此迭代器後創建創建的「新」條目。此外,PDF真的是一個金礦;) – blented 2016-09-02 00:48:41

3

由於這是Python和日誌標記,所以還有另一種可能性。

我認爲這是基於Python記錄器,基於logging.Handler。

您只需創建一個類,得到(命名)的記錄器實例,並覆蓋emit功能,把它放到一個GUI(如果你需要控制檯只需添加一個控制檯處理程序文件處理器)

例子:

import logging 

class log_viewer(logging.Handler): 
    """ Class to redistribute python logging data """ 

    # have a class member to store the existing logger 
    logger_instance = logging.getLogger("SomeNameOfYourExistingLogger") 

    def __init__(self, *args, **kwargs): 
     # Initialize the Handler 
     logging.Handler.__init__(self, *args) 

     # optional take format 
     # setFormatter function is derived from logging.Handler 
     for key, value in kwargs.items(): 
      if "{}".format(key) == "format": 
       self.setFormatter(value) 

     # make the logger send data to this class 
     self.logger_instance.addHandler(self) 

    def emit(self, record): 
     """ Overload of logging.Handler method """ 

     record = self.format(record) 

     # --------------------------------------- 
     # Now you can send it to a GUI or similar 
     # "Do work" starts here. 
     # --------------------------------------- 

     # just as an example what e.g. a console 
     # handler would do: 
     print(record) 

我目前使用類似的代碼來添加一個TkinterTreectrl.Multilistbox在運行時查看記錄器輸出。

Off-Side:記錄器只在初始化時才獲取數據,因此如果您想讓所有數據都可用,則需要在開始時對其進行初始化。 (我知道這是預料之中,但我認爲值得提及。)

相關問題