logging.config — Конфигурация журналирования

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


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

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

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

logging.config.dictConfig(config)

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

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

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

Синтаксический анализ выполняется классом 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-derived сущность передается, он используемый как есть. Иначе Configparser иллюстрируется примерами, и конфигурация, прочитанная им из объекта, прошла в fname. Если он имеет метод readline(), предполагается, что он является файловым объектом и считывается с помощью метода read_file(); в противном случае предполагается, что это имя файла и передается в read().
  • defaults – В этом аргументе можно указать значения по умолчанию, передаваемые в ConfigParser.
  • disable_existing_loggers – Если указано как False, логгеры, существующие при выполнении этого вызова, остаются включенными. Значение по умолчанию равно True, поскольку это позволяет использовать старое поведение обратно совместимым образом. Это поведение приводит к отключению всех существующих не корневых логгеры, если они или их предки не имеют явных имен в конфигурации логирование.

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

  • Использование файла конфигурации, в котором конфигурация логирование является частью общей конфигурации приложения.
  • Перед передачей в fileConfig используется конфигурация, считанная из файла и измененная использующим приложением (например, на основе параметров командной строки или других аспектов среды выполнения).
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().

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

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

Детали схемы словаря

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

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

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

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

    Настройка словарь является найденный для ключей format и datefmt (со значениями по умолчанию None), и они являются используемый для построения Formatter сущность.

    Изменено в версии 3.8: ключ validate (по умолчанию True) может быть добавлен в раздел formatters конфигурирующего словарь.

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

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

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

    Конфигурационный словарь является найденный для следующих ключей:

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

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

    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, что означает, что указанная конфигурация заменяет существующую конфигурацию той же семантикой как используемый существующим fileConfig() API.

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

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

Инкрементальная конфигурация

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

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

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

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

Связи объекта

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

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

formatters:
  brief:
    # здесь приведена конфигурация для форматера с идентификатором "brief"
  precise:
    # здесь приведена конфигурация для форматера с идентификатором "precise"
handlers:
  h1: #Это другой идентификатор
   # здесь идет настройка обработчика с идентификатором "h1"
   formatter: brief
  h2: #Это другой идентификатор
   # здесь идет настройка обработчика с идентификатором "h2"
   formatter: precise
loggers:
  foo.bar.baz:
    # другая конфигурация для логгера 'foo.bar.baz'
    handlers: [h1, h2]

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

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

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

Определенные пользователями объекты

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

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

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 source форматеры 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
}

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

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

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

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

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

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

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

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

Однако для определяемых пользователем объектов, которые не известны модулю logging, необходим более общий механизм. Например, рассмотрим logging.handlers.MemoryHandler, который принимает аргумент target, который является другим обработчиком для делегирования. Поскольку система уже знает об этом классе, то в конфигурации данный target просто должен быть id объекта соответствующего целевого обработчика, и система выполнит разрешение для обработчика из идентификатора If, однако пользователь определяет 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'], если это не удается.

Разрешение импорта и настраиваемые импортеры

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

from importlib import import_module
from logging.config import BaseConfigurator

BaseConfigurator.importer = staticmethod(import_module)

Вы не должны обертывать staticmethod(), если вы устанавливаете импорт, подлежащий выкупу на конфигураторе instance.

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

Формат файла конфигурации, понятный 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 означает, что все сообщения будут записываться в журнал. Уровень значения - eval(), используемый в контекст пространства имен пакета 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, когда eval() используется в контекст пространства имен пакета logging, представляет собой список аргументов конструктора для класса обработчика. Обратитесь к конструкторам для соответствующих обработчиков или к приведенным ниже примерам, чтобы посмотреть, как строятся типовые записи. Если не указано, по умолчанию устанавливается значение ().

Необязательная запись kwargs, когда eval() используется в контекст пространства имен пакета 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')
kwargs={'timeout': 10.0}

[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')
kwargs={'secure': True}

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

[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().

См.также

Модуль logging
Справочник API для модуля logging.
Модуль logging.handlers
Полезные обработчики, входящие в состав модуля logging.