Spec-Zone.ru › Python 3.6

logging.config — Настройка логгера

Исходный код: Lib/logging/config.py

Важно

Эта страница содержит только справочную информацию. Для учебных пособий см.

  • Базовый учебник
  • Продвинутый учебник
  • Кулинарная книга по работе с логгерами

В этом разделе описывается API для настройки модуля логгирования.

16.7.1. Функции конфигурации

Следующие функции настраивают модуль логгирования. Они находятся в модуле logging.config. Их использование необязательно — вы можете настроить модуль логгирования, используя эти функции или вызывая функции основного API (определенные в logging самом) и определяя обработчики, которые объявляются либо в logging, либо в logging.handlers.

logging.config.dictConfig(config)

Использует словарь для конфигурации логгера. Содержимое этого словаря описано в Схеме словаря конфигурации ниже.

Если при конфигурации возникает ошибка, эта функция вызовет ValueError, TypeError, AttributeError или ImportError с соответствующим сообщением. Ниже приведён (возможно, неполный) список условий, которые приведут к ошибке:

  • Значение level, которое не является строкой или которое является строкой, не соответствующей фактическому уровню логгирования.
  • Значение propagate должно быть булевым значением.
  • Идентификатор, которому не соответствует место назначения.
  • Несуществующий идентификатор обработчика, обнаруженный во время наращиваемого вызова.
  • Некорректное имя логгера.
  • Невозможность разрешения на внутренний или внешний объект.

Разбор выполняется классом DictConfigurator, конструктору которого передаётся словарь, используемый для конфигурации, и у которого есть метод configure(). Модуль logging.config имеет вызываемый атрибут dictConfigClass, который по умолчанию установлен в DictConfigurator. Вы можете заменить значение dictConfigClass на подходящую реализацию.

dictConfig() вызывает dictConfigClass, передавая указанный словарь, а затем вызывает метод configure() на возвращённом объекте, чтобы применить конфигурацию:

def dictConfig(config):
    dictConfigClass(config).configure()

Например, подкласс DictConfigurator может вызвать DictConfigurator.__init__() в своём методе __init__(), затем настроить пользовательские префиксы, которые можно использовать в последующем вызове configure(). dictConfigClass будет привязан к этому новому подклассу, и затем dictConfig() можно вызывать точно так же, как в стандартном, не настроенном состоянии.

Новое в версии 3.2.

logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True)

Считывает конфигурацию логгера из файла в формате configparser. Формат файла должен соответствовать описанию в Формат файла конфигурации. Эту функцию можно вызывать несколько раз из приложения, позволяя конечному пользователю выбирать из различных предварительно подготовленных конфигураций (если разработчик предоставляет механизм для представления выбора и загрузки выбранной конфигурации).

Параметры
  • fname – Имя файла или объект файла или экземпляр, полученный от RawConfigParser. Если передан экземпляр, полученный от RawConfigParser, он используется как есть. В противном случае создаётся экземпляр Configparser, и конфигурация считывается из объекта, переданного в fname. Если у объекта есть метод readline(), предполагается, что это объект файла, и он считывается с помощью read_file(); в противном случае предполагается, что это имя файла, и оно передаётся в read().
  • defaults – Значения по умолчанию, которые нужно передать в ConfigParser, можно указать в этом аргументе.
  • disable_existing_loggers – Если задано значение False, логгеры, которые существуют на момент вызова, остаются включёнными. По умолчанию True, поскольку это позволяет сохранить старое поведение в обратной совместимости. Это поведение заключается в отключении всех существующих логгеров, если они или их предки явно не указаны в конфигурации логгирования.

Изменено в версии 3.4: Теперь экземпляр подкласса RawConfigParser принимается в качестве значения для fname. Это облегчает:

  • Использование файла конфигурации, где конфигурация логгера является только частью общей конфигурации приложения.
  • Использование конфигурации, считанной из файла, а затем изменённой приложением (например, на основе параметров командной строки или других аспектов среды выполнения) перед передачей в fileConfig.
END_OF_DOCUMENT_MARKER ```
logging.config.listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None)

Запускает сокет-сервер на указанном порту и прослушивает новые конфигурации. Если порт не указан, используется значение по умолчанию модуля DEFAULT_LOGGING_CONFIG_PORT. Конфигурации логгирования будут отправляться как файл, подходящий для обработки с помощью dictConfig() или fileConfig(). Возвращает экземпляр Thread, на котором можно вызвать start() для запуска сервера и join() в нужное время. Чтобы остановить сервер, вызовите stopListening().

Аргумент verify, если указан, должен быть вызываемым объектом, который проверяет, являются ли полученные через сокет байты валидными и подлежат обработке. Это можно сделать, зашифровав и/или подписав отправляемые данные через сокет, таким образом, что вызываемый объект verify может выполнить проверку подписи и/или дешифрование. Вызываемый объект verify вызывается с одним аргументом — байтами, полученными через сокет, — и должен вернуть байты для обработки или None для указания на то, что байты следует отбросить. Возвращаемые байты могут быть такими же, как и переданные байты (например, при выполнении только проверки), или они могут быть совершенно другими (например, если выполняется дешифрование).

Чтобы отправить конфигурацию в сокет, прочитайте файл конфигурации и отправьте его в сокет как последовательность байтов, предваряемую четырёхбайтовым строковым значением, упакованным в двоичный формат с использованием struct.pack('>L', n).

Примечание

Поскольку части конфигурации передаются через eval(), использование этой функции может создать риск для безопасности. Хотя функция связывается только с сокетом на localhost, и поэтому не принимает подключения от удалённых машин, существуют сценарии, в которых неуправляемый код может выполняться от имени процесса, который вызывает listen(). В частности, если процесс, вызывающий listen(), выполняется на многопользовательской машине, где пользователи не могут доверять друг другу, то злонамеренный пользователь может организовать выполнение произвольного кода в процессе жертвы, просто подключившись к сокету жертвы listen() и отправив конфигурацию, которая выполняет любой код, который злоумышленник хочет выполнить в процессе жертвы. Это особенно легко сделать, если используется порт по умолчанию, но не сложно даже если используется другой порт). Чтобы избежать этого риска, используйте аргумент verify для listen(), чтобы предотвратить применение неизвестных конфигураций.

Изменено в версии 3.4: Добавлен аргумент verify.

Примечание

Если вы хотите отправлять конфигурации в прослушиватель, которые не отключают существующие логгеры, вам необходимо использовать формат JSON для конфигурации, который будет использовать dictConfig() для конфигурации. Этот метод позволяет указать disable_existing_loggers как False в отправляемой вами конфигурации.

logging.config.stopListening()

Останавливает прослушивающий сервер, созданный вызовом listen(). Обычно это вызывается перед вызовом join() на возвращаемом значении из listen().

16.7.2. Схема словаря конфигурации

Для описания конфигурации логгирования необходимо указать различные объекты и связи между ними; например, вы можете создать обработчик с именем «console» и затем указать, что логгер с именем «startup» будет отправлять свои сообщения в обработчик «console». Эти объекты не ограничиваются теми, что предоставляются модулем logging, так как вы можете написать собственные классы форматеров или обработчиков. Параметры этих классов также могут потребовать внешние объекты, такие как sys.stderr. Синтаксис описания этих объектов и связей определён в Связях объектов ниже.

16.7.2.1. Подробности схемы словаря

Словарь, переданный в dictConfig(), должен содержать следующие ключи:

  • version - значение должно быть целым числом, представляющим версию схемы. В настоящее время единственное допустимое значение равно 1, но наличие этого ключа позволяет схеме развиваться, сохраняя обратную совместимость.

Все остальные ключи необязательны, но если они присутствуют, они будут интерпретированы, как описано ниже. Во всех случаях ниже, где упоминается «словарь конфигурации», он проверяется на наличие специального ключа '()' для определения необходимости пользовательской инициализации. Если это необходимо, используется механизм, описанный в Пользовательские объекты ниже; в противном случае контекст используется для определения того, что нужно инициализировать.

  • formatters - соответствующее значение будет словарем, в котором каждый ключ — это идентификатор форматера, а каждое значение — это словарь, описывающий, как настроить соответствующий экземпляр Formatter.

    В словаре конфигурации ищутся ключи format и datefmt (с значениями по умолчанию None) и они используются для создания экземпляра Formatter.

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

    В словаре конфигурации ищется ключ name (по умолчанию пустая строка), и он используется для создания экземпляра logging.Filter.

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

    В словаре конфигурации ищутся следующие ключи:

    • class (обязательно). Полное квалифицированное имя класса обработчика.
    • level (необязательно). Уровень обработчика.
    • formatter (необязательно). Идентификатор форматера для данного обработчика.
    • filters (необязательно). Список идентификаторов фильтров для данного обработчика.

    Все другие ключи передаются в качестве ключевых аргументов конструктору обработчика. Например, приведённый фрагмент:

    handlers:
      console:
        class : logging.StreamHandler
        formatter: brief
        level   : INFO
        filters: [allow_foo]
        stream  : ext://sys.stdout
      file:
        class : logging.handlers.RotatingFileHandler
        formatter: precise
        filename: logconfig.log
        maxBytes: 1024
        backupCount: 3
    

    обработчик с идентификатором console создаётся как logging.StreamHandler с использованием sys.stdout в качестве базового потока. Обработчик с идентификатором file создаётся как logging.handlers.RotatingFileHandler с ключевыми аргументами filename='logconfig.log', maxBytes=1024, backupCount=3.

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

    В словаре конфигурации ищутся следующие ключи:

    • level (необязательно). Уровень логгера.
    • propagate (необязательно). Настройка распространения логгера.
    • filters (необязательно). Список идентификаторов фильтров для данного логгера.
    • handlers (необязательно). Список идентификаторов обработчиков для данного логгера.

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

  • root - это конфигурация для корневого логгера. Обработка конфигурации будет аналогична любому логгеру, за исключением того, что настройка propagate не применима.
  • incremental - определяет, интерпретируется ли конфигурация как инкремент к существующей конфигурации. Это значение по умолчанию False, что означает, что заданная конфигурация заменяет существующую конфигурацию с теми же семантиками, что и используемый API fileConfig().

    Если указанное значение True, конфигурация обрабатывается, как описано в разделе Инкрементная конфигурация.

  • disable_existing_loggers - определяет, должны ли быть отключены любые существующие логгеры. Это параметр аналогичен параметру с таким же именем в fileConfig(). Если параметр отсутствует, он имеет значение по умолчанию True. Это значение игнорируется, если incremental имеет значение True.

16.7.2.2. Инкрементная конфигурация

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

Кроме того, нет убедительных причин для произвольного изменения графа объектов логгеров, обработчиков, фильтров, форматеров во время выполнения после настройки конфигурации; уровень подробности логгеров и обработчиков можно контролировать, просто устанавливая уровни (и, в случае с логгерами, флаги распространения). Произвольное изменение графа объектов безопасным способом в многопоточной среде проблематично; хотя это и не невозможно, преимущества не стоят сложности, которую это добавляет в реализацию.

Таким образом, когда ключ incremental словаря конфигурации присутствует и True, система полностью игнорирует любые formatters и filters записи, и обрабатывает только настройки level в handlers записях, и настройки level и propagate в loggers и root записях.

Использование значения в словаре конфигурации позволяет отправлять конфигурации по сети в виде закодированных словарей в сокет-листенер. Таким образом, уровень подробности ведения логов долго работающего приложения можно изменять со временем без необходимости останавливать и перезапускать приложение.

16.7.2.3. Связи объектов

Схема описывает набор объектов ведения логов — логгеров, обработчиков, форматеров, фильтров — которые связаны друг с другом в графе объектов. Таким образом, схема должна представлять связи между объектами. Например, предположим, что после конфигурации конкретный логгер присоединен к конкретному обработчику. Для целей этого обсуждения мы можем сказать, что логгер представляет источник, а обработчик — пункт назначения связи между ними. Конечно, в настроенных объектах это представлено тем, что логгер хранит ссылку на обработчик. В словаре конфигурации это делается путем присвоения каждому объекту назначения идентификатора, который однозначно его идентифицирует, а затем использования идентификатора в конфигурации источника объекта для указания наличия связи между исходным и объектом назначения с этим идентификатором.

Итак, например, рассмотрим следующий фрагмент YAML:

formatters:
  brief:
    # configuration for formatter with id 'brief' goes here
  precise:
    # configuration for formatter with id 'precise' goes here
handlers:
  h1: #This is an id
   # configuration of handler with id 'h1' goes here
   formatter: brief
  h2: #This is another id
   # configuration of handler with id 'h2' goes here
   formatter: precise
loggers:
  foo.bar.baz:
    # other configuration for logger 'foo.bar.baz'
    handlers: [h1, h2]

(Примечание: YAML используется здесь, потому что он немного читабельнее, чем эквивалентная форма исходного кода Python для словаря.)

Идентификаторы логгеров — это имена логгеров, которые используются в программировании для получения ссылки на эти логгеры, например foo.bar.baz. Идентификаторы форматеров и фильтров могут быть любыми строковыми значениями (например, brief, precise выше), и они являются временными, в том смысле, что они имеют смысл только для обработки словаря конфигурации и используются для определения связей между объектами, и не сохраняются нигде после завершения вызова конфигурации.

Вышеприведенный фрагмент указывает, что логгер с именем foo.bar.baz должен иметь два обработчика, которые описаны идентификаторами обработчиков h1 и h2. Форматер для h1 — это тот, который описан идентификатором brief, а форматер для h2 — тот, который описан идентификатором precise.

16.7.2.4. Пользовательские объекты

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

Объекты, которые нужно настроить, описываются словарями, которые содержат их конфигурацию. В некоторых местах система ведения логов сможет определить, как создать объект из контекста, но когда нужно создать пользовательский объект, система не будет знать, как это сделать. Для обеспечения полной гибкости создания пользовательских объектов пользователю необходимо предоставить «фабрику» — вызываемый объект, который вызывается со словарем конфигурации и возвращает созданный объект. Это обозначается абсолютным путем импорта к фабрике, который доступен по специальному ключу '()'. Вот конкретный пример:

formatters:
  brief:
    format: '%(message)s'
  default:
    format: '%(asctime)s %(levelname)-8s %(name)-15s %(message)s'
    datefmt: '%Y-%m-%d %H:%M:%S'
  custom:
      (): my.package.customFormatterFactory
      bar: baz
      spam: 99.9
      answer: 42

Вышеприведенный фрагмент YAML определяет три форматера. Первый, с идентификатором brief, — это стандартный экземпляр logging.Formatter со строкой формата, указанной в нем. Второй, с идентификатором default, имеет более длинный формат и также явно определяет формат времени, и приведет к созданию экземпляра logging.Formatter с этими двумя строками формата. В форме исходного кода Python, форматеры brief и default имеют подсловари конфигурации:

{
  'format' : '%(message)s'
}

и:

{
  'format' : '%(asctime)s %(levelname)-8s %(name)-15s %(message)s',
  'datefmt' : '%Y-%m-%d %H:%M:%S'
}

соответственно, и поскольку эти словари не содержат специального ключа '()', создание экземпляров определяется из контекста: в результате создаются стандартные экземпляры logging.Formatter. Подсловарь конфигурации для третьего форматера с идентификатором custom:

{
  '()' : 'my.package.customFormatterFactory',
  'bar' : 'baz',
  'spam' : 99.9,
  'answer' : 42
}

и в нем есть специальный ключ '()', что означает, что требуется пользовательское создание экземпляров. В этом случае будет использоваться указанная вызываемая фабрика. Если это фактически вызываемый объект, он будет использоваться напрямую; в противном случае, если вы укажете строку (как в примере), фактический вызываемый объект будет найден с помощью обычных механизмов импорта. Вызываемый объект будет вызван со **оставшимися** элементами подсловаря конфигурации в качестве аргументов ключевых слов. В приведенном выше примере, форматер с идентификатором custom будет предполагаться возвращаемым вызовом:

my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42)

Ключ '()' используется в качестве специального ключа, потому что он не является допустимым именем аргумента ключевого слова, и поэтому не будет конфликтовать с именами аргументов ключевых слов, используемых в вызове. Ключ '()' также служит мнемонику, что соответствующее значение является вызываемым объектом.

16.7.2.5. Доступ к внешним объектам

Иногда конфигурация должна ссылаться на объекты, внешние по отношению к конфигурации, например sys.stderr. Если словарь конфигурации создается с помощью кода Python, это просто, но проблема возникает, когда конфигурация предоставляется через текстовый файл (например, JSON, YAML). В текстовом файле нет стандартного способа отличить sys.stderr от фактической строки 'sys.stderr'. Для облегчения этого различия система конфигурации ищет определенные специальные префиксы в строковых значениях и обрабатывает их особым образом. Например, если фактическая строка 'ext://sys.stderr' предоставляется в качестве значения в конфигурации, то ext:// будет удален, и остальная часть значения будет обработана с использованием обычных механизмов импорта.

Обработка таких префиксов осуществляется аналогично обработке протоколов: существует общий механизм поиска префиксов, соответствующих регулярному выражению ^(?P<prefix>[a-z]+)://(?P<suffix>.*)$, при котором, если prefix распознан, suffix обрабатывается в зависимости от префикса, и результат обработки заменяет строковое значение. Если префикс не распознан, строковое значение останется без изменений.

16.7.2.6. Доступ к внутренним объектам

Помимо внешних объектов, иногда необходимо также ссылаться на объекты в конфигурации. Это будет происходить неявно системой конфигурации для вещей, которые она знает. Например, строковое значение 'DEBUG' для level в логгере или обработчике будет автоматически преобразовано в значение logging.DEBUG, а записи handlers, filters и formatter будут получать идентификатор объекта и разрешать соответствующему объекту назначения.

Однако для пользовательских объектов, которые неизвестны модулю logging, нужен более общий механизм. Например, рассмотрим logging.handlers.MemoryHandler, который принимает аргумент target, который является другим обработчиком для делегирования. Поскольку система уже знает об этом классе, то в конфигурации заданный target должен быть только идентификатором объекта соответствующего целевого обработчика, и система будет искать обработчик по идентификатору. Однако если пользователь определяет my.package.MyHandler, который имеет alternate обработчик, система конфигурации не будет знать, что alternate относится к обработчику. Для этого предназначена общая система разрешения, которая позволяет пользователю указывать:

handlers:
  file:
    # configuration of file handler goes here

  custom:
    (): my.package.MyHandler
    alternate: cfg://handlers.file

Фактическая строка 'cfg://handlers.file' будет разрешаться аналогично строкам с префиксом ext://, но будет искать в самой конфигурации, а не в пространстве импорта. Механизм позволяет получить доступ по точке или по индексу, аналогично тому, что предоставляет str.format. Таким образом, в данном фрагменте:

handlers:
  email:
    class: logging.handlers.SMTPHandler
    mailhost: localhost
    fromaddr: my_app@domain.tld
    toaddrs:
      - support_team@domain.tld
      - dev_team@domain.tld
    subject: Houston, we have a problem.

в конфигурации строка 'cfg://handlers' будет разрешаться к словарю с ключом handlers, строка 'cfg://handlers.email будет разрешаться к словарю с ключом email в словаре handlers, и так далее. Строка 'cfg://handlers.email.toaddrs[1] будет разрешаться к 'dev_team.domain.tld', а строка 'cfg://handlers.email.toaddrs[0]' — к значению 'support_team@domain.tld'. Значение subject может быть получено как с помощью 'cfg://handlers.email.subject', так и, что эквивалентно, с помощью 'cfg://handlers.email[subject]'. Последняя форма используется только в том случае, если ключ содержит пробелы или небуквенно-цифровые символы. Если значение индекса состоит только из десятичных цифр, будет попытка доступа по соответствующему целому значению, в противном случае возвращается строковое значение.

Учитывая строку cfg://handlers.myhandler.mykey.123, это будет разрешено до config_dict['handlers']['myhandler']['mykey']['123']. Если строка задана как cfg://handlers.myhandler.mykey[123], система будет пытаться получить значение из config_dict['handlers']['myhandler']['mykey'][123], и откажется к config_dict['handlers']['myhandler']['mykey']['123'], если это не удастся.

16.7.2.7. Разрешение импорта и пользовательские импортеры

Разрешение импорта, по умолчанию, использует встроенную функцию __import__() для выполнения импорта. Возможно, вам потребуется заменить её собственным механизмом импорта: в таком случае, вы можете заменить атрибут importer класса DictConfigurator или его суперкласса, класса BaseConfigurator. Однако, следует быть внимательными из-за способа доступа к функциям из классов через дескрипторы. Если вы используете вызываемый объект Python для выполнения импорта и хотите определить его на уровне класса, а не экземпляра, вам необходимо обернуть его в staticmethod(). Например:

from importlib import import_module
from logging.config import BaseConfigurator

BaseConfigurator.importer = staticmethod(import_module)

Вам не нужно оборачивать в staticmethod(), если вы устанавливаете вызываемый объект импорта на экземпляре конфигуратора.

16.7.3. Формат файла конфигурации

Формат файла конфигурации, понимаемый fileConfig(), основан на функциональности configparser. Файл должен содержать секции, называемые [loggers], [handlers] и [formatters], которые идентифицируют по имени сущности каждого типа, определенные в файле. Для каждой такой сущности существует отдельная секция, которая определяет, как эта сущность настроена. Таким образом, для логгера с именем log01 в секции [loggers], соответствующие детали конфигурации хранятся в секции [logger_log01]. Аналогично, обработчик с именем hand01 в секции [handlers] будет иметь свою конфигурацию, хранящуюся в секции с именем [handler_hand01], а форматировщик с именем form01 в секции [formatters] будет иметь свою конфигурацию, указанную в секции с именем [formatter_form01]. Конфигурация корневого логгера должна быть указана в секции с именем [logger_root].

Примечание

API fileConfig() старше API dictConfig() и не предоставляет функциональности для покрытия определенных аспектов ведения логов. Например, вы не можете настроить объекты Filter, которые обеспечивают фильтрацию сообщений за пределами простых целочисленных уровней, используя fileConfig(). Если вам необходимо использовать экземпляры Filter в вашей конфигурации ведения логов, вам необходимо использовать dictConfig(). Обратите внимание, что будущие улучшения функциональности конфигурации будут добавлены в dictConfig(), поэтому стоит рассмотреть переход на этот более новый API, когда это удобно.

Примеры этих секций в файле приведены ниже.

[loggers]
keys=root,log02,log03,log04,log05,log06,log07

[handlers]
keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09

[formatters]
keys=form01,form02,form03,form04,form05,form06,form07,form08,form09

Корневой логгер должен указать уровень и список обработчиков. Пример секции корневого логгера приведен ниже.

[logger_root]
level=NOTSET
handlers=hand01

Запись level может быть одной из DEBUG, INFO, WARNING, ERROR, CRITICAL или NOTSET. Только для корневого логгера, NOTSET означает, что все сообщения будут записаны в лог. Значения уровней оцениваются в контексте пространства имен пакета logging.

Запись handlers — это список имён обработчиков, разделенных запятыми, которые должны присутствовать в секции [handlers]. Эти имена должны присутствовать в секции [handlers], и у них должны быть соответствующие секции в файле конфигурации.

Для логгеров, отличных от корневого логгера, требуется дополнительная информация. Это проиллюстрировано в следующем примере.

[logger_parser]
level=DEBUG
handlers=hand01
propagate=1
qualname=compiler.parser

Записи level и handlers интерпретируются так же, как для корневого логгера, за исключением того, что если уровень некорневого логгера указан как NOTSET, система обращается к логгерам выше по иерархии, чтобы определить эффективный уровень логгера. Запись propagate устанавливается в 1, чтобы указать, что сообщения должны распространяться в обработчики выше по иерархии логгера от этого логгера, или в 0, чтобы указать, что сообщения не распространяются в обработчики выше по иерархии. Запись qualname — это иерархическое имя канала логгера, то есть имя, используемое приложением для получения логгера.

Секции, которые определяют конфигурацию обработчика, показаны ниже.

[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
args=(sys.stdout,)

Запись class указывает класс обработчика (как определено eval() в пространстве имен пакета logging). Запись level интерпретируется так же, как для логгеров, а NOTSET означает «записать всё».

Запись formatter указывает имя форматировщика для этого обработчика. Если оно пустое, используется форматировщик по умолчанию (logging._defaultFormatter). Если имя указано, оно должно присутствовать в секции [formatters], и у него должна быть соответствующая секция в файле конфигурации.

Запись args, при оценке в контексте пространства имён пакета logging, представляет собой список аргументов для конструктора класса обработчика. Обратитесь к конструкторам соответствующих обработчиков или к приведённым ниже примерам, чтобы увидеть, как создаются типичные записи.

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form02
args=('python.log', 'w')

[handler_hand03]
class=handlers.SocketHandler
level=INFO
formatter=form03
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)

[handler_hand04]
class=handlers.DatagramHandler
level=WARN
formatter=form04
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)

[handler_hand05]
class=handlers.SysLogHandler
level=ERROR
formatter=form05
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)

[handler_hand06]
class=handlers.NTEventLogHandler
level=CRITICAL
formatter=form06
args=('Python Application', '', 'Application')

[handler_hand07]
class=handlers.SMTPHandler
level=WARN
formatter=form07
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')

[handler_hand08]
class=handlers.MemoryHandler
level=NOTSET
formatter=form08
target=
args=(10, ERROR)

[handler_hand09]
class=handlers.HTTPHandler
level=NOTSET
formatter=form09
args=('localhost:9022', '/log', 'GET')

Секции, которые определяют конфигурацию форматировщика, типизированы следующим образом.

[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s
datefmt=
class=logging.Formatter

Запись format — это строка формата в целом, а запись datefmt — строка формата даты/времени, совместимая с strftime(). Если она пуста, пакет подставляет что-то, что почти эквивалентно указанию строки формата даты '%Y-%m-%d %H:%M:%S'. Этот формат также указывает миллисекунды, которые добавляются к результату использования вышеуказанной строки формата, с разделителем запятой. Пример времени в этом формате: 2003-01-23 00:29:50,411.

Запись class необязательна. Она указывает имя класса форматировщика (как имя модуля и класса с точками). Этот параметр полезен для создания подкласса Formatter. Подклассы Formatter могут отображать трассировки исключений в расширенном или сокращённом формате.

Примечание

Из-за использования eval(), как описано выше, существуют потенциальные риски безопасности, которые возникают при использовании listen() для отправки и получения конфигураций через сокеты. Риски ограничиваются случаями, когда несколько пользователей без взаимного доверия выполняют код на одной машине; см. документацию listen() для получения дополнительной информации.

См. также

Module logging

Справочник по API модуля ведения логов.

Module logging.handlers

Полезные обработчики, включенные в модуль ведения логов.

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/logging.config.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API