poner limpiar font etiquetas como python tail

python - limpiar - labels en tkinter



¿Cómo puedo alinear un archivo de registro en Python? (10)

Me gustaría que la salida de cola -F o algo similar esté disponible para mí en Python sin bloquear o bloquear. He encontrado un código muy viejo para hacer eso here , pero estoy pensando que debe haber una mejor manera o una biblioteca para hacer lo mismo por ahora. Alguien sabe de uno?

Idealmente, tendría algo como tail.getNewData() que podría llamar cada vez que quisiera más datos.


Idealmente, tendría algo como tail.getNewData () que podría llamar cada vez que quisiera más datos

Ya tenemos uno y es muy agradable. Simplemente llame a f.read () cada vez que desee más datos. Comenzará a leer donde quedó la lectura anterior y leerá hasta el final de la secuencia de datos:

f = open(''somefile.log'') p = 0 while True: f.seek(p) latest_data = f.read() p = f.tell() if latest_data: print latest_data print str(p).center(10).center(80, ''='')

Para leer línea por línea, use f.readline () . A veces, el archivo que se lee terminará con una línea parcialmente leída. Maneje ese caso con f.tell () buscando la posición actual del archivo y usando f.seek () para mover el puntero del archivo al principio de la línea incompleta. Vea esta receta de ActiveState para el código de trabajo.


Sin bloqueo

Si está en Linux (ya que Windows no admite la selección de llamadas en los archivos) puede usar el módulo de subproceso junto con el módulo de selección.

import time import subprocess import select f = subprocess.Popen([''tail'',''-F'',filename],/ stdout=subprocess.PIPE,stderr=subprocess.PIPE) p = select.poll() p.register(f.stdout) while True: if p.poll(1): print f.stdout.readline() time.sleep(1)

Este sondea la tubería de salida para nuevos datos y la imprime cuando está disponible. Normalmente el time.sleep(1) y la print f.stdout.readline() se reemplazarán por un código útil.

Bloqueo

Puede utilizar el módulo de subproceso sin las llamadas de módulo de selección adicionales.

import subprocess f = subprocess.Popen([''tail'',''-F'',filename],/ stdout=subprocess.PIPE,stderr=subprocess.PIPE) while True: line = f.stdout.readline() print line

Esto también imprimirá nuevas líneas a medida que se agreguen, pero se bloqueará hasta que se cierre el programa de cola, probablemente con f.kill() .


Entonces, esto llega bastante tarde, pero me encontré con el mismo problema otra vez, y ahora hay una solución mucho mejor. Solo usa el pygtail :

Pygtail lee líneas de archivos de registro que no se han leído. Incluso manejará los archivos de registro que se han girado. Basado en Logcheck''s logtail2 ( http://logcheck.org )


La única forma portátil de tail -f un archivo parece ser, de hecho, leer de ella y volver a intentar (después de un sleep ) si la read devuelve 0. Las utilidades de tail en varias plataformas usan trucos específicos de plataforma (por ejemplo, kqueue en BSD ) para cola eficientemente un archivo para siempre sin necesidad de sleep .

Por lo tanto, implementar una buena tail -f puramente en Python probablemente no sea una buena idea, ya que tendrías que usar la implementación del mínimo denominador común (sin recurrir a hacks específicos de la plataforma). Usando un subprocess simple para abrir tail -f e iterar a través de las líneas en un subproceso separado, puede implementar fácilmente una operación de tail no bloqueante en Python.

Ejemplo de implementación:

import threading, Queue, subprocess tailq = Queue.Queue(maxsize=10) # buffer at most 100 lines def tail_forever(fn): p = subprocess.Popen(["tail", "-f", fn], stdout=subprocess.PIPE) while 1: line = p.stdout.readline() tailq.put(line) if not line: break threading.Thread(target=tail_forever, args=(fn,)).start() print tailq.get() # blocks print tailq.get_nowait() # throws Queue.Empty if there are no lines to read


Otra opción es la biblioteca de tailhead que proporciona tanto las versiones de Python de tail utilidades de tail y head como las API que se pueden usar en su propio módulo.

Originalmente basado en el módulo tailer , su principal ventaja es la capacidad de seguir archivos por ruta, es decir, puede manejar la situación cuando se recrea el archivo. Además, tiene algunas correcciones de errores para varios casos de borde.


Puede usar la biblioteca ''tailer'': https://pypi.python.org/pypi/tailer/

Tiene una opción para obtener las últimas líneas:

# Get the last 3 lines of the file tailer.tail(open(''test.txt''), 3) # [''Line 9'', ''Line 10'', ''Line 11'']

Y también puede seguir un archivo:

# Follow the file as it grows for line in tailer.follow(open(''test.txt'')): print line

Si uno quiere un comportamiento parecido a la cola, esa parece ser una buena opción.


Python es "pilas incluidas", tiene una buena solución para ello: https://pypi.python.org/pypi/pygtail

Lee las líneas del archivo de registro que no se han leído. Recuerda dónde terminó la última vez, y continúa desde allí.

import sys from pygtail import Pygtail for line in Pygtail("some.log"): sys.stdout.write(line)


Si está en Linux, implemente una implementación sin bloqueo en python de la siguiente manera.

import subprocess subprocess.call(''xterm -title log -hold -e /"tail -f filename/"&'', shell=True, executable=''/bin/csh'') print "Done"



Usando el módulo sh (instalación pip sh):

from sh import tail # runs forever for line in tail("-f", "/var/log/some_log_file.log", _iter=True): print(line)

[actualizar]

Como sh.tail con _iter = True es un generador, puedes:

import sh tail = sh.tail("-f", "/var/log/some_log_file.log", _iter=True)

Entonces puedes "obtener nuevos datos" con:

new_data = tail.next()

Tenga en cuenta que si el buffer de cola está vacío, bloqueará hasta que haya más datos (de su pregunta no está claro qué es lo que quiere hacer en este caso).

[actualizar]

Esto funciona si reemplazas -f con -F, pero en Python estaría bloqueando. Estaría más interesado en tener una función a la que pudiera llamar para obtener nuevos datos cuando quiera, si eso es posible. - Eli

Un generador de contenedores colocando la llamada de la cola dentro de un ciclo True y atrapando eventuales excepciones de E / S tendrán casi el mismo efecto de -F.

def tail_F(some_file): while True: try: for line in sh.tail("-f", some_file, _iter=True): yield line except sh.ErrorReturnCode_1: yield None

Si el archivo se vuelve inaccesible, el generador devolverá None. Sin embargo, todavía bloquea hasta que haya nuevos datos si se puede acceder al archivo. No está claro para mí lo que quieres hacer en este caso.

El enfoque de Raymond Hettinger parece bastante bueno:

def tail_F(some_file): first_call = True while True: try: with open(some_file) as input: if first_call: input.seek(0, 2) first_call = False latest_data = input.read() while True: if ''/n'' not in latest_data: latest_data += input.read() if ''/n'' not in latest_data: yield '''' if not os.path.isfile(some_file): break continue latest_lines = latest_data.split(''/n'') if latest_data[-1] != ''/n'': latest_data = latest_lines[-1] else: latest_data = input.read() for line in latest_lines[:-1]: yield line + ''/n'' except IOError: yield ''''

Este generador devolverá '''' si el archivo se vuelve inaccesible o si no hay nuevos datos.

[actualizar]

La penúltima respuesta gira alrededor de la parte superior del archivo cuando parece que se queda sin datos. - Eli

Creo que el segundo dará salida a las últimas diez líneas cada vez que finalice el proceso de cola, que con -f es siempre que hay un error de E / S. El comportamiento de tail --follow --retry no está lejos de esto en la mayoría de los casos que se me ocurre en entornos de tipo Unix.

Quizás si actualizas tu pregunta para explicar cuál es tu objetivo real (la razón por la que quieres imitar la cola), obtendrás una mejor respuesta.

La última respuesta en realidad no sigue la cola y simplemente lee lo que está disponible en tiempo de ejecución. - Eli

Por supuesto, cola mostrará las últimas 10 líneas por defecto ... Puede colocar el puntero del archivo al final del archivo usando file.seek, dejaré una implementación adecuada como ejercicio para el lector.

En mi humilde opinión, el enfoque file.read () es mucho más elegante que una solución basada en subprocesos.