A mi me servios la siguiente lectura: http://www.dabeaz.com/coroutines/
En especial: http://www.dabeaz.com/coroutines/follow.py que es un "tail" a la python... 2011/4/18 Esteban Dauksis <este...@dauksis.com>: > Os lo reenvío, espero que ésta vez llegue a la lista. > > Saludos > > > Hola, hace algún tiempo me embarqué en algo parecido.... algo que no > te han comentado de momento es gestionar la rotación/truncado de > archivos de log... lo mejor que encontré y que no recuerdo de dónde lo > saqué es lo siguiente: > > > # -*- coding: utf-8 -*- > """ > Module to allow for reading lines from a continuously-growing file (such as > a system log). Handles log files that get rotated/trucated out from under > us. Inspired by the Perl File::Tail module. > > Example: > > t = filetail.Tail("log.txt") > while True: > line = t.nextline() > # do something with the line > > or: > > t = filetail.Tail("log.txt") > for line in t: > # do something > pass > > """ > > from os import stat > from os.path import abspath > from stat import ST_SIZE > from time import sleep, time > > class Tail(object): > """The Tail monitor object.""" > > def __init__(self, path, only_new = False, > min_sleep = 1, > sleep_interval = 1, > max_sleep = 60): > """Initialize a tail monitor. > path: filename to open > only_new: By default, the tail monitor will start reading from > the beginning of the file when first opened. Set only_new to > True to have it skip to the end when it first opens, so that > you only get the new additions that arrive after you start > monitoring. > min_sleep: Shortest interval in seconds to sleep when waiting > for more input to arrive. Defaults to 1.0 second. > sleep_interval: The tail monitor will dynamically recompute an > appropriate sleep interval based on a sliding window of data > arrival rate. You can set sleep_interval here to seed it > initially if the default of 1.0 second doesn't work for you > and you don't want to wait for it to converge. > max_sleep: Maximum interval in seconds to sleep when waiting > for more input to arrive. Also, if this many seconds have > elapsed without getting any new data, the tail monitor will > check to see if the log got truncated (rotated) and will > quietly reopen itself if this was the case. Defaults to 60.0 > seconds. > """ > > # remember path to file in case I need to reopen > self.path = abspath(path) > self.f = open(self.path,"r") > self.min_sleep = min_sleep * 1.0 > self.sleep_interval = sleep_interval * 1.0 > self.max_sleep = max_sleep * 1.0 > if only_new: > # seek to current end of file > file_len = stat(path)[ST_SIZE] > self.f.seek(file_len) > self.pos = self.f.tell() # where am I in the file? > self.last_read = time() # when did I last get some data? > self.queue = [] # queue of lines that are ready > self.window = [] # sliding window for dynamically > # adjusting the sleep_interval > > def _recompute_rate(self, n, start, stop): > """Internal function for recomputing the sleep interval. I get > called with a number of lines that appeared between the start and > stop times; this will get added to a sliding window, and I will > recompute the average interarrival rate over the last window. > """ > self.window.append((n, start, stop)) > purge_idx = -1 # index of the highest old record > tot_n = 0 # total arrivals in the window > tot_start = stop # earliest time in the window > tot_stop = start # latest time in the window > for i, record in enumerate(self.window): > (i_n, i_start, i_stop) = record > if i_stop < start - self.max_sleep: > # window size is based on self.max_sleep; this record has > # fallen out of the window > purge_idx = i > else: > tot_n += i_n > if i_start < tot_start: tot_start = i_start > if i_stop > tot_stop: tot_stop = i_stop > if purge_idx >= 0: > # clean the old records out of the window (slide the window) > self.window = self.window[purge_idx+1:] > if tot_n > 0: > # recompute; stay within bounds > self.sleep_interval = (tot_stop - tot_start) / tot_n > if self.sleep_interval > self.max_sleep: > self.sleep_interval = self.max_sleep > if self.sleep_interval < self.min_sleep: > self.sleep_interval = self.min_sleep > > def _fill_cache(self): > """Internal method for grabbing as much data out of the file as is > available and caching it for future calls to nextline(). Returns > the number of lines just read. > """ > old_len = len(self.queue) > line = self.f.readline() > while line != "": > self.queue.append(line) > line = self.f.readline() > # how many did we just get? > num_read = len(self.queue) - old_len > if num_read > 0: > self.pos = self.f.tell() > now = time() > self._recompute_rate(num_read, self.last_read, now) > self.last_read = now > return num_read > > def _dequeue(self): > """Internal method; returns the first available line out of the > cache, if any.""" > if len(self.queue) > 0: > line = self.queue[0] > self.queue = self.queue[1:] > return line > else: > return None > > def _reset(self): > """Internal method; reopen the internal file handle (probably > because the log file got rotated/truncated).""" > self.f.close() > self.f = open(self.path, "r") > self.pos = self.f.tell() > self.last_read = time() > > def nextline(self): > """Return the next line from the file. Blocks if there are no lines > immediately available.""" > > # see if we have any lines cached from the last file read > line = self._dequeue() > if line: > return line > > # ok, we are out of cache; let's get some lines from the file > if self._fill_cache() > 0: > # got some > return self._dequeue() > > # hmm, still no input available > while True: > sleep(self.sleep_interval) > if self._fill_cache() > 0: > return self._dequeue() > now = time() > if (now - self.last_read > self.max_sleep): > # maybe the log got rotated out from under us? > if stat(self.path)[ST_SIZE] < self.pos: > # file got truncated and/or re-created > self._reset() > if self._fill_cache() > 0: > return self._dequeue() > > def close(self): > """Close the tail monitor, discarding any remaining input.""" > self.f.close() > self.f = None > self.queue = [] > self.window = [] > > def __iter__(self): > """Iterator interface, so you can do: > > for line in filetail.Tail('log.txt'): > # do stuff > pass > """ > return self > > def next(self): > """Kick the iterator interface. Used under the covers to support: > > for line in filetail.Tail('log.txt'): > # do stuff > pass > """ > return self.nextline() > > > Espero que te sea de ayuda. A mi me sirvió y me sigue funcionando :-) > Saludos > > Esteban > > El 29/03/2011, a las 01:33, Carlos Herrera Polo escribió: > > Gracias a todos por sus aportes, estoy implementando un lector de logs > utilizando las ideas del link que me sugerio Angel > > http://stackoverflow.com/questions/136168/get-last-n-lines-of-a-file-with-python-similar-to-tail/136368#136368 > > Muchas gracias a todos por sus aportes y ayuda. > > El 28 de marzo de 2011 18:30, Chema Cortes <pych...@gmail.com> escribió: > El día 27 de marzo de 2011 22:33, Carlos Herrera Polo > <carlos.herrerap...@gmail.com> escribió: > >> Alguien que me pueda sugerir algo por favor ? > > Se puede hacer fácilmente, y sin recurrir a herramientas externas, > manteniendo el fichero abierto para lectura y leyendo de él cuando se > detecte que ha cambiado su tamaño. Algo parecido al código de este > mensaje: > > http://mail.python.org/pipermail/python-es/2003-May/002091.html > > _______________________________________________ > Python-es mailing list > Python-es@python.org > http://mail.python.org/mailman/listinfo/python-es > FAQ: http://python-es-faq.wikidot.com/ > > > > El día 27 de marzo de 2011 22:33, Carlos Herrera Polo > <carlos.herrerap...@gmail.com> escribió: >> Ilustres, quisiera tener su opinion al respecto.. >> >> Administro ciertos servidores linux, y consolido la informacion de los >> logs de estos en un unico servidor con el servicio syslog-ng, los logs >> son archivos planos que se almacenan en formato ASCII, un log por cada >> servicio/servicio. >> Quisiera desarrollar un programa simple que me alerte por correo de >> ciertos eventos que ocurren en los logs.... Existe un programa llamado >> logsurfer, escrito en C que hace esto... >> Mi idea es hacer un logsurfer pero en python, pero no se como trabajar >> la lectura de estos archivos planos que cada uno debe tener varios >> megas de peso, y son escritos cada segundo, ustedes como lo harian ? >> Porque hacer fileread por cada uno y luego irme hasta las ultimas >> filas como que no seria eficiente... >> >> Alguien que me pueda sugerir algo por favor ? >> >> Muchas gracias a todos >> >> Saludos >> >> -- >> Enviado desde mi dispositivo móvil >> _______________________________________________ >> Python-es mailing list >> Python-es@python.org >> http://mail.python.org/mailman/listinfo/python-es >> FAQ: http://python-es-faq.wikidot.com/ >> > _______________________________________________ > Python-es mailing list > Python-es@python.org > http://mail.python.org/mailman/listinfo/python-es > FAQ: http://python-es-faq.wikidot.com/ > -- http://celord.blogspot.com/ _______________________________________________ Python-es mailing list Python-es@python.org http://mail.python.org/mailman/listinfo/python-es FAQ: http://python-es-faq.wikidot.com/