- rotación de registros todos los días: Utilice una compresión TimedRotatingFileHandler
- de troncos: Ajuste el parámetro
encoding='bz2'
. (Tenga en cuenta que este "truco" solo funcionará para Python2. 'Bz2' ya no se considera una codificación en Python3.)
- opcional - elimine el archivo de registro más antiguo para conservar X MB de espacio libre. Podría (indirectamente) organizar esto usando un RotatingFileHandler. Al establecer el parámetro
maxBytes
, el archivo de registro se reiniciará cuando alcance un determinado tamaño. Al establecer el parámetro backupCount
, puede controlar la cantidad de renovaciones que se mantienen. Los dos parámetros juntos le permiten controlar el espacio máximo consumido por los archivos de registro. Probablemente también podría subclasificar el TimeRotatingFileHandler
para incorporar este comportamiento en él.
Sólo por diversión, aquí es cómo se podría subclase TimeRotatingFileHandler
. Cuando ejecuta el script a continuación, escribirá archivos de registro en /tmp/log_rotate*
.
Con un valor pequeño para time.sleep
(como 0.1), los archivos de registro se llenan rápidamente, alcanzan el límite maxBytes y luego se vuelcan.
Con un gran time.sleep
(como 1.0), los archivos de registro se llenan lentamente, no se alcanza el límite de maxBytes, pero se transfieren de todos modos cuando se alcanza el intervalo de tiempo (de 10 segundos).
Todo el código siguiente proviene de logging/handlers.py. Simplemente conecté TimeRotatingFileHandler con RotatingFileHandler de la manera más directa posible.
import time
import re
import os
import stat
import logging
import logging.handlers as handlers
class SizedTimedRotatingFileHandler(handlers.TimedRotatingFileHandler):
"""
Handler for logging to a set of files, which switches from one file
to the next when the current file reaches a certain size, or at certain
timed intervals
"""
def __init__(self, filename, maxBytes=0, backupCount=0, encoding=None,
delay=0, when='h', interval=1, utc=False):
handlers.TimedRotatingFileHandler.__init__(
self, filename, when, interval, backupCount, encoding, delay, utc)
self.maxBytes = maxBytes
def shouldRollover(self, record):
"""
Determine if rollover should occur.
Basically, see if the supplied record would cause the file to exceed
the size limit we have.
"""
if self.stream is None: # delay was set...
self.stream = self._open()
if self.maxBytes > 0: # are we rolling over?
msg = "%s\n" % self.format(record)
# due to non-posix-compliant Windows feature
self.stream.seek(0, 2)
if self.stream.tell() + len(msg) >= self.maxBytes:
return 1
t = int(time.time())
if t >= self.rolloverAt:
return 1
return 0
def demo_SizedTimedRotatingFileHandler():
log_filename = '/tmp/log_rotate'
logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
handler = SizedTimedRotatingFileHandler(
log_filename, maxBytes=100, backupCount=5,
when='s', interval=10,
# encoding='bz2', # uncomment for bz2 compression
)
logger.addHandler(handler)
for i in range(10000):
time.sleep(0.1)
logger.debug('i=%d' % i)
demo_SizedTimedRotatingFileHandler()
rotación? ¿Te refieres a ejecutar el script todos los días? Si es así, sugeriría usar un trabajo cron. – Griffin
Mi aplicación se ejecutará y se registrará continuamente, por lo que quiero que el sistema inicie un nuevo archivo de registro todos los días –
relacionado [Python issue 13516: archivos de registro antiguos de Gzip en controladores rotativos] (http://bugs.python.org/issue13516) menciona [ejemplo de TimedCompressedRotatingFileHandler] (http://code.activestate.com/recipes/502265-timedcompressedrotatingfilehandler/) – jfs