Поворачивать файлы журналов при каждом запуске приложения (Python) - PullRequest
15 голосов
/ 11 января 2011

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

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

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

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

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

Ответы [ 4 ]

31 голосов
/ 11 января 2011

Мне может быть достаточно использовать 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)
6 голосов
/ 11 января 2011

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

например,

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, чтобы иметь отдельный журнал для каждого вызова приложения, где каждый сам журнал далее делится на несколько журналов фиксированного размера.

0 голосов
/ 24 января 2018

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

import logging

from logging.handlers import BaseRotatingHandler
from typing import Union

def rotate_logs(loggers: Union[str,list]=None, delimiter: str=','):
    """Rotate logs.

    Args:
        loggers: List of logger names as list object or as string,
            separated by `delimiter`.

        delimiter: Separator for logger names, if `loggers` is :obj:`str`.
            Defaults to ``,`` (comma).

    """

    # Convert loggers to list.
    if isinstance(loggers, str):
        loggers = [t.strip() for t in loggers.split(delimiter)]

    handlers = []
    root = logging.getLogger()

    # Include root logger in dict.    
    ld = {'': root, **root.manager.loggerDict}

    for k, v in ld.items():
        if loggers is not None and k not in loggers:
            continue

        try:
            for h in v.handlers:
                if (isinstance(h, BaseRotatingHandler) and
                    h not in handlers):

                    handlers.append(h)

        except AttributeError:
            pass

    for h in handlers:
        h.doRollover()



if __name__ == '__main__':
    pass

Примечания:

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

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

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

0 голосов
/ 11 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...