2010-07-20 22 views
35

Próbuję znaleźć dobry sposób na odczytanie pliku dziennika w czasie rzeczywistym za pomocą Pythona. Chciałbym przetwarzać linie z pliku dziennika pojedynczo podczas jego zapisywania. Wciąż muszę próbować czytać plik, dopóki go nie utworzy, a następnie kontynuować przetwarzanie linii, dopóki nie zakończę procesu. Czy istnieje odpowiedni sposób na zrobienie tego? Dzięki.Odczytaj z pliku dziennika zapisanego przy użyciu pythona

+0

Ten też jest dobry ... Myślę, że pasuje on do twoich kryteriów i zapewnia klasę, którą można łatwo rozszerzyć. [http://code.activestate.com/recipes/577968-log-watcher-tail-f-log/](http://code.activestate.com/recipes/577968-log-watcher-tail-f-log /) – mogga

Odpowiedz

20

można spróbować z czymś takim:

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 

Przykład ekstrahowano z here.

+0

To wydaje się działać, ale nie pozwoli mi tworzyć obiektów ani pisać do bazy danych w tym samym czasie w mojej aplikacji django. Nie widzę żadnego oczywistego powodu; czy istnieje prosta naprawa? – Anon

+0

Nie wiem. Powinieneś opublikować kod w osobnym pytaniu, aby uzyskać odpowiedzi na ten temat. Nie widzę powodu, aby nie aktualizować bazy danych, jeśli umieścisz ten kod wewnątrz tego ... –

+0

Mam to do roboty, ale musiałem dużo zepsuć, zanim zdołałem napisać do mojej bazy danych. Dzięki. – Anon

-1

Może można zrobić wywołanie systemowe do

tail -f 

użyciu os.system()

32

Spójrz na this PDF zaczynając od strony 38 ~ slajd I-77, a znajdziesz wszystko potrzebne informacje. Oczywiście reszta slajdy są niesamowite, zbyt, ale te konkretnie zajmować problemu:

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

Warto zauważyć, że pominie to zawartość już zawartą w pliku dziennika, a jedynie drukuje "nowe" wpisy utworzone po utworzeniu tego iteratora. Także ten PDF naprawdę jest kopalnią złota;) – blented

3

Ponieważ jest to oznaczenie Python i logowanie, istnieje inna możliwość, aby to zrobić.

Zakładam, że jest to oparte na logarytmie Pythona, opartym na logging.Handler.

Można po prostu utworzyć klasę, która dostaje (nazwie) instancji rejestratora i zastąpić funkcję emit umieścić go na GUI (jeśli trzeba konsolę wystarczy dodać obsługi konsoli do obsługi plików)

przykładu:

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) 

obecnie używam podobny kod, aby dodać TkinterTreectrl.Multilistbox do oglądania wyjście rejestratora przy starcie.

Off-Side: Rejestrator pobiera dane dopiero po zainicjowaniu, więc jeśli chcesz mieć wszystkie dostępne dane, musisz je zainicjować na samym początku. (Wiem, że to jest oczekiwane, ale myślę, że warto o tym wspomnieć.)

Powiązane problemy