Leer un log en tiempo real

Antonio Castro acastro en ciberdroide.com
Mar Mayo 2 09:07:23 CEST 2006


On Mon, 1 May 2006, Oscar Curero wrote:

> Hola,
>
> Necesito leer un fichero de log de un programa y recuperar los datos de ese
> log en el momento en el que aparezcan en él. He estado buscando por si había
> alguna clase hecha y no he encontrado, aparte de buscar alguna receta.
>
> Mi pregunta es la siguiente: ¿Cómo puedo "esuchar" un fichero y recuperar
> cualquier cambio que haya en su contenido? (lo mismo que hace shift+F en la
> utilidad "less" de linux)
>
> Gracias,

Yo usaría popen sobre el comando 'tail -f archivo' dentro de un thread.

Yo lo hice desde un programa usando tkinter, que tiene el problema de que
no es reentrante y lo solucioné como sigue. Te pongo solo los trozos de
código mas significativos porque el módulo que yo me hice es voluminoso y
no es de proósito general. Creo que te liaría mas si te lo mando todo.

Se trata de que pilles la idea y que la adaptes.


#====================================================================
class mkmt_os:

    #------------------------------------------------------------
    def __init__(self, root):
        self.root=root
        self.runing_LinesPopenTask=0
        self.LinesPopenTask_RetLines=[]
        self.LinesPopenTask_RetLinesErr=[]

    #------------------------------------------------------------
    def Warning(self, str, delay=None):
        popupdialog.Warning(self.root, str, delay)

    #----------------------------------------------
    def LinesPopenTask(self, comando):
        '''
        Ejecutar dentro de un thread. No usar desde esta función llamadas
        que no sean reentrartes tales como llamadas a tkinter
        '''
        self.runing_LinesPopenTask=1 # Reservar el recurso
        fdin, fdout, fderr=os.popen3(comando, 'r')
        lines=fdout.readlines()
        LinesErr=fderr.readlines()
        # Procesar los datos leidos (a gusto de cada uno)
        ..........................

        self.runing_LinesPopenTask=0 # Liberar el recurso
        return

    #----------------------------------------------
    def WaitEndTask(self):
        '''
        Esperamos a que termine la tarea pero cada cuarto
        de segundo procesamos todos los eventos pendientes
        de tkinter.
        '''
        while self.runing_LinesPopenTask:
            self.root.after(250)
            self.root.update()

   #---------------------------------------
        # Ahora ya lo podemos usar dentro de un thread
        ..........................
        if self.runing_LinesPopenTask==1: # Ooops. Esta ocupado
            self.Warning("Ya hay una tarea en marcha.", 2)
            return
        self.runing_LinesPopenTask=1;
        t = threading.Thread(target=self.LinesPopenTask, args=(comando,))
        t.start()
        self.WaitEndTask() # Espera activa


-- 
Un saludo
Antonio Castro




Más información sobre la lista de distribución Python-es