Поворачивайте лог файлы каждый раз, когда приложение запускается (Python)

Я использую модуль протоколирования в Python, и я хотел бы, чтобы он создавал новый файл журнала каждый раз, когда запускается мое приложение. Более старые файлы журналов должны быть повернуты (например: logfile.txt → logfile1.txt и т.д.).

Я уже нашел это:

http://docs.python.org/library/logging.html

BaseRotatingHandler - базовый класс для обработчиков, которые вращают файлы журналов в определенный момент. Он не должен быть созданный непосредственно. Вместо этого используйте RotatingFileHandler или TimedRotatingFileHandler.

RotatingFileHandler выполняет опрокидывание с заданным размером, а TimedRotatingFileHandler выполняет опрокидывание, основанное на произведении времени и интервала. И то, и другое не то, что я хочу, я хочу, чтобы ротация произошла сразу же после запуска моего приложения.

Ответ 1

Мне может быть достаточно использовать RotatingFileHandler без maxBytes, а затем вызвать doRollover() при запуске приложения.

Да, кажется, все нормально. В приведенном ниже коде будет создан новый файл журнала для каждого запуска приложения с добавленными отметками времени для начала и закрытия журнала. Запуск будет распечатан список доступных файлов журнала. Вы можете проверить их, чтобы проверить правильность поведения. Адаптировано из примера документов Python:

import os
import glob
import logging
import logging.handlers
import time

LOG_FILENAME = 'logging_rotatingfile_example.out'

# Set up a specific logger with our desired output level
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)

# Check if log exists and should therefore be rolled
needRoll = os.path.isfile(LOG_FILENAME)

# Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(LOG_FILENAME, backupCount=50)

my_logger.addHandler(handler)

# This is a stale log, so roll it
if needRoll:    
    # Add timestamp
    my_logger.debug('\n---------\nLog closed on %s.\n---------\n' % time.asctime())

    # Roll over on application start
    my_logger.handlers[0].doRollover()

# Add timestamp
my_logger.debug('\n---------\nLog started on %s.\n---------\n' % time.asctime())

# Log some messages
for i in xrange(20):
    my_logger.debug('i = %d' % i)

# See what files are created
logfiles = glob.glob('%s*' % LOG_FILENAME)

print '\n'.join(logfiles)

Ответ 2

Простейший способ - просто иметь метку даты в имени файла журнала, поэтому при запуске приложения каждый раз, когда вы получите новый файл журнала.

например.

dateTag = datetime.datetime.now().strftime("%Y-%b-%d_%H-%M-%S")
logging.basicConfig(filename="myapp_%s.log" % dateTag, level=logging.DEBUG)

поэтому каждый раз, когда у вас будет журнал вроде myapp_2011-Jan-11_12-27-29.log

Еще одно преимущество заключается в том, что вы можете смешивать это с RotatingFileHandler, чтобы иметь отдельный журнал для каждого вызова приложения, где каждый сам журнал далее делится на несколько журналов с фиксированным размером.

Ответ 3

Лог Rotation и RoatatingFileHandler обычно разрабатываются и желательны, когда приложение работает очень долго (дни), и вы хотите, чтобы журнал сохранял вращение. В тех случаях, когда мне нужно повернуть журнал при перезагрузке приложения, мне пришлось сделать это за пределами обработчика журнала, что было проще. Это было похоже на то, что до того, как журнал записи вызовет первый раз, я увижу, если файл журнала уже существует, и если да, переименуйте его и создайте новый файл журнала. Переименование должно быть дифференцировано от механизма переименования обработчика.

Ответ 4

У меня было аналогичное требование, чтобы иметь возможность принудительно вращать журнал при запуске на основе параметра командной строки, но для файлов журналов в противном случае они будут вращаться в обычном расписании. Это было мое решение:

import logging
import logging.handlers

# For my use case, handlers are attached to the root logger. This may be
# changed, if the handlers are attached to a different logger.
LOGGER = ''

# Force log rotation.
if args.rotate_logs:
    for h in logging.getLogger(LOGGER).handlers:
        if isinstance(h, logging.handlers.BaseRotatingHandler):
            h.doRollover()

Примечания:

  • Это подтверждено для работы, если maxBytes > 0 на RotatingFileHandler.

  • Этот метод не был протестирован с помощью TimedRotatingFileHandler, но должен работать.

  • Этот метод устраняет необходимость поддерживать ссылку на RotatingFileHandler для вращения; в результате его можно легко использовать при настройке ведения журнала с помощью logging.config.