Логирование в Python

Введение

Примеры

  • 6

    Введение в Python Logging

    Этот модуль определяет функции и классы, которые реализуют гибкую систему регистрации событий для приложений и библиотек.

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

    Итак, начнем:

    Пример конфигурации прямо в коде

     import logging
    
    logger = logging.getLogger()
    handler = logging.StreamHandler()
    formatter = logging.Formatter(
            '%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    logger.setLevel(logging.DEBUG)
    
    logger.debug('this is a %s test', 'debug')
    
     

    Пример вывода:

     2016-07-26 18:53:55,332 root         DEBUG    this is a debug test
    
     

    Пример конфигурации через INI-файл

    Предполагая, что файл называется logging_config.ini. Подробнее для формата файла находятся в конфигурации протоколирования раздела лесозаготовительного учебника .

     [loggers]
    keys=root
    
    [handlers]
    keys=stream_handler
    
    [formatters]
    keys=formatter
    
    [logger_root]
    level=DEBUG
    handlers=stream_handler
    
    [handler_stream_handler]
    class=StreamHandler
    level=DEBUG
    formatter=formatter
    args=(sys.stderr,)
    
    [formatter_formatter]
    format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
    
    
     

    Затем используйте logging.config.fileConfig() в коде:

     import logging
    from logging.config import fileConfig
    
    fileConfig('logging_config.ini')
    logger = logging.getLogger()
    logger.debug('often makes a very good meal of %s', 'visiting tourists')
    
     

    Пример конфигурации через словарь

    Начиная с Python 2.7, вы можете использовать словарь с деталями конфигурации. PEP 391 содержит перечень обязательных и факультативных элементов в словаре конфигурации.

     import logging
    from logging.config import dictConfig
    
    logging_config = dict(
        version = 1,
        formatters = {
            'f': {'format':
                  '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'}
            },
        handlers = {
            'h': {'class': 'logging.StreamHandler',
                  'formatter': 'f',
                  'level': logging.DEBUG}
            },
        root = {
            'handlers': ['h'],
            'level': logging.DEBUG,
            },
    )
    
    dictConfig(logging_config)
    
    logger = logging.getLogger()
    logger.debug('often makes a very good meal of %s', 'visiting tourists')
    
    
     
  • 2

    Регистрация исключений

    Если вы хотите , чтобы войти исключения вы можете и должны использовать logging.exception(msg) метод:

     >>> import logging
    >>> logging.basicConfig()
    >>> try:
    ...     raise Exception('foo')
    ... except:
    ...     logging.exception('bar')
    ...
    ERROR:root:bar
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    Exception: foo
    
     

    Не передавайте исключение в качестве аргумента:

    Как logging.exception(msg) ожидает msg ARG, это распространенная ошибка , чтобы передать исключение в лесозаготовительном вызов , как это:

     >>> try:
    ...     raise Exception('foo')
    ... except Exception as e:
    ...     logging.exception(e)
    ...
    ERROR:root:foo
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    Exception: foo
    
     

    Хотя на первый взгляд может показаться, что это правильно, на самом деле это проблематично из-за причины, по которой исключения и различные кодировки работают вместе в модуле регистрации:

     >>> try:
    ...     raise Exception(u'föö')
    ... except Exception as e:
    ...     logging.exception(e)
    ...
    Traceback (most recent call last):
      File "/.../python2.7/logging/__init__.py", line 861, in emit
        msg = self.format(record)
      File "/.../python2.7/logging/__init__.py", line 734, in format
        return fmt.format(record)
      File "/.../python2.7/logging/__init__.py", line 469, in format
        s = self._fmt % record.__dict__
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-2: ordinal not in range(128)
    Logged from file <stdin>, line 4
    
     

    Попытка войти исключение , которое содержит юникод символы, таким образом , будет с треском провалились . Он скроет StackTrace первоначального исключения путем переопределения его новое, которое возникает в процессе форматирования вашего logging.exception(e) вызова.

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

    Правильное использование:

    Если вместо исключения вы просто передадите сообщение и дадите Python свою магию, он будет работать:

     >>> try:
    ...     raise Exception(u'föö')
    ... except Exception as e:
    ...     logging.exception('bar')
    ...
    ERROR:root:bar
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    Exception: f\xf6\xf6
    
     

    Как вы можете видеть , что мы на самом деле не использовать e в том случае, вызов logging.exception(...) волшебно форматирует самый последнее исключение.

    Регистрация исключений с уровнями журнала, не являющимися ошибками

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

     logging.debug('exception occurred', exc_info=1)
    logging.info('exception occurred', exc_info=1)
    logging.warning('exception occurred', exc_info=1)
    
    
     

    Доступ к сообщению об исключении

    Имейте в виду, что библиотеки могут выдавать исключения с сообщениями как любые из байтовых строк в кодировке Unicode или (utf-8, если вам повезет). Если вам действительно нужно , чтобы получить доступ текста в виде исключения, единственный надежный способ, который будет работать всегда, заключается в использовании repr(e) или %r форматирования строк:

     >>> try:
    ...     raise Exception(u'föö')
    ... except Exception as e:
    ...     logging.exception('received this exception: %r' % e)
    ...
    ERROR:root:received this exception: Exception(u'f\xf6\xf6',)
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    Exception: f\xf6\xf6 

Синтаксис

Параметры

Примечания