2010-07-20 17 views
35

J'essaie de trouver une façon agréable de lire un fichier journal en temps réel en utilisant python. Je voudrais traiter les lignes d'un fichier journal un à la fois comme il est écrit. D'une manière ou d'une autre, je dois continuer à essayer de lire le fichier jusqu'à ce qu'il soit créé, puis continuer à traiter les lignes jusqu'à ce que je termine le processus. Y a-t-il un moyen approprié de faire cela? Merci.Lecture à partir d'un fichier journal en cours d'écriture en utilisant python

+0

Celui-ci est bon aussi ... Je pense qu'il correspond bien à vos critères et offre une classe qui pourrait être étendue facilement. [http://code.activestate.com/recipes/577968-log-watcher-tail-f-log/](http://code.activestate.com/recipes/577968-log-watcher-tail-f-log /) – mogga

Répondre

20

Vous pouvez essayer quelque chose comme ceci:

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 

Exemple a été extrait de here.

+0

Cela semble fonctionner mais il ne me permettra pas de créer des objets ou écrire dans une base de données en même temps dans mon application django. Je ne vois pas une raison évidente pour cela; Y a-t-il une solution simple? – Anon

+0

Je ne sais pas. Vous devriez poster du code dans une question séparée pour obtenir des réponses à celui-ci, je suppose. Je ne vois aucune raison de ne pas mettre à jour la base de données si vous placez ce code dans celui-ci ... –

+0

J'ai eu ce travail mais j'ai dû beaucoup jouer avec la corde avant de pouvoir l'écrire dans ma base de données. Merci. – Anon

-1

Peut-être que vous pourriez faire un appel système à

tail -f 

utilisant os.system()

32

Jetez un oeil à this PDF partir de la page 38, ~ diapositive I-77 et vous trouverez tous les l'info dont vous avez besoin. Bien sûr, le reste des diapositives sont incroyables, aussi, mais ceux qui traitent spécifiquement de votre question:

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

Il est à noter que cela sautera n'importe quel contenu déjà dans le fichier journal, en imprimant uniquement les "nouvelles" entrées créées après la création de cet itérateur. Aussi ce PDF est vraiment une mine d'or;) – blented

3

Comme il s'agit de Python et que la journalisation est balisée, il existe une autre possibilité. Je suppose que cela est basé sur un enregistreur Python, basé sur Logging.Handler.

Vous pouvez juste créer une classe qui obtient le (nom) instance enregistreur et remplacer la fonction emit pour le mettre sur une interface graphique (si vous avez besoin console il suffit d'ajouter un gestionnaire de console au gestionnaire de fichiers)

Exemple:

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) 

Je suis actuellement en utilisant un code similaire pour ajouter un TkinterTreectrl.Multilistbox pour l'affichage de sortie de l'enregistreur à l'exécution. Off-Side: L'enregistreur n'obtient des données que lorsqu'il est initialisé, donc si vous voulez que toutes vos données soient disponibles, vous devez l'initialiser au tout début. (Je sais que c'est ce qui est attendu, mais je pense qu'il vaut la peine d'être mentionné.)