- dziennika obrót codziennie: Użyj kompresji do TimedRotatingFileHandler
- dzienników: Ustaw parametr
encoding='bz2'
. (Uwaga: "trik" działa tylko w Pythonie 2. "bz2" nie jest już uważany za kodowanie w Pythonie 3.)
- opcjonalnie - usuń najstarszy plik dziennika, aby zachować X MB wolnej pamięci. Można (pośrednio) zorganizować to za pomocą RotatingFileHandler. Po ustawieniu parametru
maxBytes
plik dziennika będzie się kręcić po osiągnięciu określonego rozmiaru. Ustawiając parametr backupCount
, można kontrolować liczbę zachowywanych najazdów. Te dwa parametry razem pozwalają kontrolować maksymalną ilość miejsca zużywaną przez pliki dziennika. Prawdopodobnie możesz podklasować TimeRotatingFileHandler
, aby uwzględnić w nim również to zachowanie.
Tak dla zabawy, oto jak można podklasy TimeRotatingFileHandler
. Po uruchomieniu poniższego skryptu będzie on zapisywał pliki dziennika do /tmp/log_rotate*
.
Przy niewielkiej wartości dla time.sleep
(np. 0,1) pliki dziennika szybko się uzupełniają, osiągają limit maks. I są następnie przewracane.
Przy dużym numerze time.sleep
(takim jak 1.0) pliki dziennika wypełniają się powoli, limit maxBytes nie zostaje osiągnięty, ale mimo to przewijają się one po osiągnięciu przedziału czasu (10 sekund).
Cały poniższy kod pochodzi z logging/handlers.py. Po prostu zakomunikowałem TimeRotatingFileHandler za pomocą programu RotatingFileHandler w możliwie najprostszy sposób.
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()
rotacja? Czy masz na myśli uruchamianie skryptu codziennie? Jeśli tak, proponuję użyć zadania crona. – Griffin
Moja aplikacja będzie działać i logować się w sposób ciągły, dlatego chcę, aby system codziennie uruchamiał nowy plik dziennika –
powiązany [Python, wydanie 13516: stare pliki dziennika Gzip w programach do obracania] (http://bugs.python.org/issue13516) wspomina o przykładzie [TimedCompressedRotatingFileHandler] (http://code.activestate.com/recipes/502265-timedcompressedrotatingfilehandler/) – jfs