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
используется конфигурация, считанная из файла и измененная использующим приложением (например, на основе параметров командной строки или других аспектов среды выполнения).
- fname – Имя файла, или подобный файлу объект или сущность произошли из
-
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
в отправляемой конфигурации.
Схема словаря конфигурации¶
Описание конфигурации логирование требует перечисления различных объектов для
создания и соединений между ними; например, можно создать обработчик с именем
«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.