logging.config
— Logging configuration¶
소스 코드: Lib/logging/config.py
이 절에서는 logging 모듈을 구성하기 위한 API에 관해 설명합니다.
구성 함수¶
다음 함수는 logging 모듈을 구성합니다. logging.config
모듈에 있습니다. 사용은 선택 사항입니다 — 이 함수들을 사용하거나 (logging
자체에서 정의된) 주 API를 호출하고 logging
이나 logging.handlers
에서 선언된 처리기를 정의해서 logging 모듈을 구성할 수 있습니다.
- logging.config.dictConfig(config)¶
딕셔너리로 로깅 구성을 받습니다. 이 딕셔너리의 내용은 아래의 구성 딕셔너리 스키마에 설명되어 있습니다.
구성 중에 에러를 만나면, 이 함수는 적절하게 설명하는 메시지와 함께
ValueError
,TypeError
,AttributeError
또는ImportError
를 발생시킵니다. 다음은 에러를 발생시킬 수 있는 (불완전한) 조건 목록입니다:문자열이 아니거나 실제 로깅 수준과 일치하지 않는 문자열인
level
.불리언이 아닌
propagate
값.해당 대상이 없는 id.
증분(incremental) 호출 중에 발견된 존재하지 않는 처리기 id.
잘못된 로거 이름.
결정할 수 없는 내부나 외부 객체.
구문 분석은
DictConfigurator
클래스에 의해 수행되며, 생성자로는 구성에 사용되는 딕셔너리가 전달되고, 객체는configure()
메서드를 가집니다.logging.config
모듈에는 초기에DictConfigurator
로 설정된 콜러블 어트리뷰트dictConfigClass
가 있습니다. 여러분 자신의 적절한 구현으로dictConfigClass
의 값을 바꿀 수 있습니다.dictConfig()
는dictConfigClass
를 호출해서 지정된 딕셔너리를 전달한 다음, 반환된 객체의configure()
메서드를 호출하여 구성을 적용합니다:def dictConfig(config): dictConfigClass(config).configure()
For example, a subclass of
DictConfigurator
could callDictConfigurator.__init__()
in its own__init__()
, then set up custom prefixes which would be usable in the subsequentconfigure()
call.dictConfigClass
would be bound to this new subclass, and thendictConfig()
could be called exactly as in the default, uncustomized state.Added in version 3.2.
- logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True, encoding=None)¶
configparser
-형식 파일에서 로깅 구성을 읽습니다. 파일 형식은 구성 파일 형식에 설명된 것과 같아야 합니다. 이 함수는 응용 프로그램에서 여러 번 호출 할 수 있어서, 최종 사용자가 여러 가지 미리 준비된 구성 중에서 선택할 수 있도록 합니다 (개발자가 선택 사항을 표시하고 선택한 구성을 로드하는 메커니즘을 제공한다면).It will raise
FileNotFoundError
if the file doesn’t exist andRuntimeError
if the file is invalid or empty.- 매개변수:
fname – A filename, or a file-like object, or an instance derived from
RawConfigParser
. If aRawConfigParser
-derived instance is passed, it is used as is. Otherwise, aConfigParser
is instantiated, and the configuration read by it from the object passed infname
. If that has areadline()
method, it is assumed to be a file-like object and read usingread_file()
; otherwise, it is assumed to be a filename and passed toread()
.defaults – Defaults to be passed to the
ConfigParser
can be specified in this argument.disable_existing_loggers –
False
로 지정되면, 이 호출이 이루어졌을 때 존재하는 로거는 활성화된 상태로 남습니다. 기본값은True
이므로, 과거 호환성을 유지하도록 이전 동작을 활성화합니다. 이 동작은 이미 존재하는 비 루트 로거를 그들이나 그들의 조상이 로깅 구성에서 명시적으로 명명되지 않으면 비활성화하는 것입니다.encoding – The encoding used to open file when fname is filename.
버전 3.4에서 변경: An instance of a subclass of
RawConfigParser
is now accepted as a value forfname
. This facilitates:로깅 구성이 전체 응용 프로그램 구성의 일부인 구성 파일의 사용.
파일에서 읽어 들인 다음
fileConfig
로 전달되기 전에 사용하는 응용 프로그램이 (예를 들어, 명령 줄 매개 변수나 실행 시간 환경의 다른 측면에 기반하여) 수정하는 구성의 사용.
버전 3.10에서 변경: Added the encoding parameter.
버전 3.12에서 변경: An exception will be thrown if the provided file doesn’t exist or is invalid or empty.
- logging.config.listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None)¶
지정된 포트에서 소켓 서버를 시작하고, 새 구성을 수신 대기합니다. 포트를 지정하지 않으면, 모듈의 기본
DEFAULT_LOGGING_CONFIG_PORT
가 사용됩니다. 로깅 구성은dictConfig()
나fileConfig()
로 처리하기에 적합한 파일로 전송됩니다. 서버를 시작하기 위해start()
를 호출할 수 있는Thread
인스턴스를 반환하고, 적절할 때join()
할 수 있습니다. 서버를 중지하려면,stopListening()
을 호출하십시오.verify
인자가 지정되면, 소켓을 통해 수신된 바이트열이 유효하고 처리되어야 하는지를 확인하는 콜러블이어야 합니다. 소켓을 통해 전송되는 것을 암호화 및/또는 서명하고,verify
콜러블이 서명 확인 및/또는 암호 해독을 수행할 수 있습니다.verify
콜러블은 단일 인자(소켓을 통해 수신된 바이트열)로 호출되며, 처리할 바이트열이나 바이트열을 버려야 함을 나타내기 위해None
을 반환합니다. 반환된 바이트열은 전달된 바이트열과 같을 수 있고 (예를 들어, 확인만 수행될 때), 또는 완전히 다를 수 있습니다 (아마도 암호 해독이 수행될 때).소켓으로 구성을 보내려면, 구성 파일을 읽어서 소켓에
struct.pack('>L', n)
를 사용하여 바이너리로 만든 4바이트의 길이를 앞에 붙인 바이트 시퀀스를 보냅니다.참고
Because portions of the configuration are passed through
eval()
, use of this function may open its users to a security risk. While the function only binds to a socket onlocalhost
, and so does not accept connections from remote machines, there are scenarios where untrusted code could be run under the account of the process which callslisten()
. Specifically, if the process callinglisten()
runs on a multi-user machine where users cannot trust each other, then a malicious user could arrange to run essentially arbitrary code in a victim user’s process, simply by connecting to the victim’slisten()
socket and sending a configuration which runs whatever code the attacker wants to have executed in the victim’s process. This is especially easy to do if the default port is used, but not hard even if a different port is used. To avoid the risk of this happening, use theverify
argument tolisten()
to prevent unrecognised configurations from being applied.버전 3.4에서 변경:
verify
인자가 추가되었습니다.참고
리스너에 기존 로거를 비활성화하지 않는 구성을 보내려면,
dictConfig()
를 사용하도록 구성에 JSON 형식을 사용해야 합니다. 이 방법은 보내는 구성에서disable_existing_loggers
를False
로 지정할 수 있도록 합니다.
Security considerations¶
The logging configuration functionality tries to offer convenience, and in part this is done by offering the ability to convert text in configuration files into Python objects used in logging configuration - for example, as described in 사용자 정의 객체. However, these same mechanisms (importing callables from user-defined modules and calling them with parameters from the configuration) could be used to invoke any code you like, and for this reason you should treat configuration files from untrusted sources with extreme caution and satisfy yourself that nothing bad can happen if you load them, before actually loading them.
구성 딕셔너리 스키마¶
로깅 구성을 기술하려면 만들려는 다양한 객체와 그들 간의 연결을 나열해야 합니다; 예를 들어, ‘console’이라는 처리기를 만든 다음 ‘startup’이라는 로거가 ‘console’ 처리기에 메시지를 보낼 것이라고 말할 수 있습니다. 사용자 자신의 포매터나 처리기 클래스를 작성할 수 있으므로, 이러한 객체가 logging
모듈에서 제공하는 객체로만 제한되지는 않습니다. 이러한 클래스의 매개 변수는 sys.stderr
과 같은 외부 객체를 포함할 수도 있습니다. 이러한 객체와 연결을 기술하는 문법은 아래의 객체 연결에 정의되어 있습니다.
딕셔너리 스키마 세부사항¶
dictConfig()
에 전달되는 딕셔너리에는 반드시 다음 키가 있어야 합니다:
version - 스키마 버전을 나타내는 정숫값으로 설정됩니다. 현재 유효한 유일한 값은 1이지만, 이 키를 사용하면 과거 호환성을 유지하면서 스키마를 발전시킬 수 있습니다.
다른 모든 키는 선택 사항이지만, 있으면 아래에 설명된 대로 해석됩니다. 아래에서 ‘구성 딕셔너리(configuring dict)’가 언급되는 모든 경우에, 특수한 '()'
키를 검사해서 사용자 정의 인스턴스화가 필요한지를 확인합니다. 있다면, 아래의 사용자 정의 객체에 설명된 메커니즘을 사용하여 인스턴스를 만듭니다; 그렇지 않다면, 어떤 인스턴스를 만들지를 결정하는데 문맥이 사용됩니다.
formatters - 해당 값은 딕셔너리인데, 각 키는 포매터 id이고, 각 값은 해당
Formatter
인스턴스를 구성하는 방법을 설명하는 딕셔너리입니다.The configuring dict is searched for the following optional keys which correspond to the arguments passed to create a
Formatter
object:format
datefmt
style
validate
(since version >=3.8)defaults
(since version >=3.12)
An optional
class
key indicates the name of the formatter’s class (as a dotted module and class name). The instantiation arguments are as forFormatter
, thus this key is most useful for instantiating a customised subclass ofFormatter
. For example, the alternative class might present exception tracebacks in an expanded or condensed format. If your formatter requires different or extra configuration keys, you should use 사용자 정의 객체.filters - 해당 값은 딕셔너리인데, 각 키가 필터 id이고 각 값은 해당 Filter 인스턴스를 구성하는 방법을 설명하는 딕셔너리입니다.
구성 딕셔너리는 키
name
(기본값은 빈 문자열)으로 검색되며, 이는logging.Filter
인스턴스를 만드는 데 사용됩니다.handlers - 해당 값은 딕셔너리인데, 각 키가 처리기 id이고 각 값은 해당 Handler 인스턴스를 구성하는 방법을 설명하는 딕셔너리입니다.
구성 딕셔너리는 다음 키에서 검색합니다:
class
(필수). 이것은 처리기 클래스의 완전히 정규화된 이름입니다.level
(선택). 처리기의 수준.formatter
(선택). 이 처리기의 포매터의 id.filters
(선택). 이 처리기의 필터의 id의 리스트.버전 3.11에서 변경:
filters
can take filter instances in addition to ids.
모든 다른 키는, 처리기의 생성자에 키워드 인자로 전달됩니다. 예를 들어, 다음과 같이 주어진 조각에서:
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
id가
console
인 처리기는sys.stdout
를 하부 스트림으로 사용하는logging.StreamHandler
로 인스턴스가 만들어집니다. id가file
인 처리기는 키워드 인자filename='logconfig.log', maxBytes=1024, backupCount=3
를 사용하여logging.handlers.RotatingFileHandler
로 인스턴스가 만들어집니다.loggers - 해당 값은 딕셔너리인데, 각 키가 로거 이름이고 각 값은 해당 Logger 인스턴스를 구성하는 방법을 설명하는 딕셔너리입니다.
구성 딕셔너리는 다음 키에서 검색합니다:
level
(선택). 로거의 수준.propagate
(선택). 로거의 전파(propagation) 설정.filters
(선택). 이 로거의 필터의 id의 리스트버전 3.11에서 변경:
filters
can take filter instances in addition to ids.handlers
(선택). 이 로거의 처리기의 id의 리스트.
지정된 로거는 지정된 수준, 전파, 필터와 처리기에 따라 구성됩니다.
root - 루트 로거에 대한 구성입니다.
propagate
설정을 적용할 수 없다는 점을 제외하고 구성 처리는 모든 로거와 같습니다.incremental - 구성을 기존 구성의 증분으로 해석할지 여부. 이 값의 기본값은
False
이며, 이는 지정된 구성이 기존 구성을 기존fileConfig()
API에서 사용된 것과 같은 의미로 대체 함을 뜻합니다.지정된 값이
True
이면, 증분 구성 절에서 설명하는 대로 구성이 처리됩니다.disable_existing_loggers - 기존의 루트가 아닌 로거를 비활성화할지 여부. 이 설정은
fileConfig()
의 같은 이름의 매개 변수를 반영합니다. 없으면, 이 매개 변수의 기본값은True
입니다. incremental이True
이면 이 값은 무시됩니다.
증분 구성¶
증분 구성에 완벽한 유연성을 제공하기는 어렵습니다. 예를 들어, 필터와 포매터와 같은 객체는 익명이므로, 일단 구성이 설정되면, 이러한 익명 객체를 참조하여 구성을 보강할 수 없습니다.
또한, 일단 구성이 설정되면, 실행 시간에 로거, 처리기, 필터, 포매터의 객체 그래프를 임의로 변경해야 할 강력한 사례는 없습니다; 로거와 처리기의 상세도는 단지 수준(과, loggers에서는 전파 플래그)을 설정하여 제어할 수 있습니다. 객체 그래프를 임의로 안전하게 변경하는 것은 다중 스레드 환경에서 문제가 됩니다; 불가능하지는 않지만, 구현에 추가되는 복잡성을 상쇄할만한 가치가 없습니다.
따라서, 구성 딕셔너리의 incremental
키가 있고 True
이면, 시스템은 formatters
와 filters
항목을 완전히 무시하고 handlers
항목의 level
설정과 loggers
와 root
항목의 level
과 propagate
설정만 처리합니다.
구성 딕셔너리의 값을 사용하면 구성을 피클 된 딕셔너리의 형태로 네트워크를 통해 소켓 리스너로 전송할 수 있습니다. 따라서, 장기 실행 응용 프로그램의 로깅 상세도는 응용 프로그램을 중지하고 다시 시작할 필요 없이 도중에 변경될 수 있습니다.
객체 연결¶
스키마는 객체 그래프에서 서로 연결된 로깅 객체 집합(로거, 처리기, 포매터, 필터)을 기술합니다. 따라서, 스키마는 객체 간의 연결을 표현할 필요가 있습니다. 예를 들어, 일단 구성되면, 특정 로거가 특정 처리기에 연결된다고 합시다. 이 토론의 목적을 위해, 둘 간의 연결에서 로거는 소스를, 처리기는 대상(destination)을 나타낸다고 할 수 있습니다. 물론 구성된 객체에서 이것은 처리기에 대한 참조를 갖는 로거로 표현됩니다. 구성 딕셔너리에서, 각 대상 객체에 명확하게 식별하는 id를 부여한 다음, 소스 객체의 구성에서 그 id를 사용하여, 소스와 그 id를 갖는 대상 객체 사이에 연결이 있음을 나타냅니다.
그래서, 예를 들어, 다음 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을 사용했습니다.)
로거의 id는 로거로의 참조를 얻기 위해서 프로그램적으로 사용되는 로거 이름입니다, 예를 들어 foo.bar.baz
. 포매터와 필터의 id는 임의의 문자열 값(가령 위의 brief
, precise
)이 될 수 있으며, 일시적이므로 구성 딕셔너리 처리에만 의미가 있고 객체 간의 연결을 결정하는 데 사용되며, 구성 호출이 완료된 후에는 어디에도 남아있지 않습니다.
위의 조각은 foo.bar.baz
라는 로거에 두 개의 처리기가 연결되어 있어야 하며, 이 처리기들은 처리기 id 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 조각은 세 가지 포매터를 정의합니다. 첫 번째(id brief
)는 지정된 포맷 문자열을 갖는 표준 logging.Formatter
인스턴스입니다. 두 번째(id default
)는 더 긴 포맷을 가지며 명시적으로 시간 포맷을 정의하기도 하고, 이 두 포맷 문자열로 초기화된 logging.Formatter
가 됩니다. 파이썬 소스 형식으로 표시하면, brief
와 default
포매터는 각각 다음과 같은 구성 서브 딕셔너리를 갖습니다:
{
'format' : '%(message)s'
}
그리고:
{
'format' : '%(asctime)s %(levelname)-8s %(name)-15s %(message)s',
'datefmt' : '%Y-%m-%d %H:%M:%S'
}
그리고, 이 딕셔너리에는 특수키 '()'
가 포함되어 있지 않으므로, 문맥에서 인스턴스가 추론됩니다: 결과적으로, 표준 logging.Formatter
인스턴스가 만들어집니다. 세 번째 포매터(id custom
)에 대한 구성 서브 딕셔너리는 다음과 같습니다:
{
'()' : 'my.package.customFormatterFactory',
'bar' : 'baz',
'spam' : 99.9,
'answer' : 42
}
여기에는 특수키 '()'
가 포함되어 있는데, 사용자 정의 인스턴스가 필요하다는 뜻입니다. 이때, 지정된 팩토리 콜러블이 사용됩니다. 그것이 실제 콜러블이면 직접 사용됩니다 - 그렇지 않고, (예에서와같이) 문자열을 지정하면 일반적인 임포트 메커니즘을 사용하여 실제 콜러블을 얻습니다. 콜러블은 구성 서브 딕셔너리의 나머지 항목을 키워드 인자로 호출됩니다. 위의 예제에서, id가 custom
인 포매터는 다음과 같은 호출이 반환한다고 가정합니다:
my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42)
경고
The values for keys such as bar
, spam
and answer
in
the above example should not be configuration dictionaries or references such
as cfg://foo
or ext://bar
, because they will not be processed by the
configuration machinery, but passed to the callable as-is.
'()'
키가 유효한 키워드 매개 변수 이름이 아니라서 특수키로 사용되었습니다. 그러므로 호출에 사용되는 키워드 인자의 이름과 충돌하지 않습니다. '()'
는 해당 값이 콜러블이라는 표시로도 기능합니다.
버전 3.11에서 변경: The filters
member of handlers
and loggers
can take
filter instances in addition to ids.
You can also specify a special key '.'
whose value is a dictionary is a
mapping of attribute names to values. If found, the specified attributes will
be set on the user-defined object before it is returned. Thus, with the
following configuration:
{
'()' : 'my.package.customFormatterFactory',
'bar' : 'baz',
'spam' : 99.9,
'answer' : 42,
'.' {
'foo': 'bar',
'baz': 'bozz'
}
}
the returned formatter will have attribute foo
set to 'bar'
and
attribute baz
set to 'bozz'
.
경고
The values for attributes such as foo
and baz
in
the above example should not be configuration dictionaries or references such
as cfg://foo
or ext://bar
, because they will not be processed by the
configuration machinery, but set as attribute values as-is.
Handler configuration order¶
Handlers are configured in alphabetical order of their keys, and a configured
handler replaces the configuration dictionary in (a working copy of) the
handlers
dictionary in the schema. If you use a construct such as
cfg://handlers.foo
, then initially handlers['foo']
points to the
configuration dictionary for the handler named foo
, and later (once that
handler has been configured) it points to the configured handler instance.
Thus, cfg://handlers.foo
could resolve to either a dictionary or a handler
instance. In general, it is wise to name handlers in a way such that dependent
handlers are configured _after_ any handlers they depend on; that allows
something like cfg://handlers.foo
to be used in configuring a handler that
depends on handler foo
. If that dependent handler were named bar
,
problems would result, because the configuration of bar
would be attempted
before that of foo
, and foo
would not yet have been configured.
However, if the dependent handler were named foobar
, it would be configured
after foo
, with the result that cfg://handlers.foo
would resolve to
configured handler foo
, and not its configuration dictionary.
외부 객체에 대한 액세스¶
구성에서 구성 외부의 객체를 참조해야 하는 경우가 있습니다, 예를 들어 sys.stderr
. 구성 딕셔너리가 파이썬 코드를 사용하여 만들어질 때는 간단하지만, 구성이 텍스트 파일(예를 들어, JSON, YAML)을 통해 제공될 때 문제가 발생합니다. 텍스트 파일에서는, sys.stderr
를 리터럴 문자열 'sys.stderr'
과 구별하는 표준 방법이 없습니다. 이 구별을 쉽게 하기 위해, 구성 시스템은 문자열 값에서 특정 접두사를 찾아 특수하게 처리합니다. 예를 들어, 리터럴 문자열 'ext://sys.stderr'
이 구성에서 값으로 제공되면, ext://
는 제거되고 값의 나머지 부분을 일반 임포트 메커니즘을 사용하여 처리합니다.
이러한 접두사의 처리는 프로토콜 처리와 유사한 방식으로 수행됩니다: 정규식 ^(?P<prefix>[a-z]+)://(?P<suffix>.*)$
와 일치하는 접두사를 찾는 일반 메커니즘이 있습니다. prefix
가 인식되면 suffix
는 접두사 종속적 방식으로 처리되고 처리 결과가 문자열 값을 대체합니다. 접두사가 인식되지 않으면, 문자열 값은 그대로 남습니다.
내부 객체에 대한 액세스¶
외부 객체뿐만 아니라, 때로 구성에 있는 객체를 참조할 필요도 있습니다. 이것은 구성 시스템이 알고 있는 것들에 대해 묵시적으로 수행됩니다. 예를 들어, 로거나 처리기의 level
에 대한 문자열 값 'DEBUG'
은 자동으로 값 logging.DEBUG
으로 변환되고, handlers
, filters
및 formatter
항목은 객체 id를 받아서 적절한 대상 객체로 결정합니다.
하지만, logging
모듈에 알려지지 않은 사용자 정의 객체에는 더욱 일반적인 메커니즘이 필요합니다. 예를 들어, 위임할 다른 처리기인 target
인자를 취하는 logging.handlers.MemoryHandler
를 고려해봅시다. 시스템이 이미 이 클래스에 대해 알고 있으므로, 구성에서, 주어진 target
은 단지 관련 target 처리기의 객체 id이기만 하면 되며, 시스템은 id로부터 처리기를 결정합니다. 그러나 사용자가 alternate
처리기를 갖는 my.package.MyHandler
를 정의하면, 구성 시스템은 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.
in the configuration, the string 'cfg://handlers'
would resolve to
the dict with key handlers
, the string 'cfg://handlers.email
would resolve to the dict with key email
in the handlers
dict,
and so on. The string 'cfg://handlers.email.toaddrs[1]
would
resolve to 'dev_team@domain.tld'
and the string
'cfg://handlers.email.toaddrs[0]'
would resolve to the value
'support_team@domain.tld'
. The subject
value could be accessed
using either 'cfg://handlers.email.subject'
or, equivalently,
'cfg://handlers.email[subject]'
. The latter form only needs to be
used if the key contains spaces or non-alphanumeric characters. Please note
that the characters [
and ]
are not allowed in the keys. If an
index value consists only of decimal digits, access will be attempted
using the corresponding integer value, falling back to the string
value if needed.
문자열 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__()
함수를 사용합니다. 이것을 자신의 임포트 메커니즘으로 바꾸고 싶을 수 있습니다: 그렇다면, DictConfigurator
나 그것의 슈퍼 클래스(BaseConfigurator
클래스)의 importer
어트리뷰트를 바꿀 수 있습니다. 그러나, 함수가 클래스에서 디스크립터를 통해 액세스 되는 방식 때문에 주의해야 합니다. 파이썬 콜러블을 사용하여 임포트를 수행하려고 하고, 인스턴스 수준이 아닌 클래스 수준에서 정의하려고 한다면, staticmethod()
로 감쌀 필요가 있습니다. 예를 들면:
from importlib import import_module
from logging.config import BaseConfigurator
BaseConfigurator.importer = staticmethod(import_module)
구성자 instance에서 임포트 콜러블을 설정한다면, staticmethod()
로 감쌀 필요가 없습니다.
Configuring QueueHandler and QueueListener¶
If you want to configure a QueueHandler
, noting that this
is normally used in conjunction with a QueueListener
, you
can configure both together. After the configuration, the QueueListener
instance
will be available as the listener
attribute of
the created handler, and that in turn will be available to you using
getHandlerByName()
and passing the name you have used for the
QueueHandler
in your configuration. The dictionary schema for configuring the pair
is shown in the example YAML snippet below.
handlers:
qhand:
class: logging.handlers.QueueHandler
queue: my.module.queue_factory
listener: my.package.CustomListener
handlers:
- hand_name_1
- hand_name_2
...
The queue
and listener
keys are optional.
If the queue
key is present, the corresponding value can be one of the following:
An object implementing the
Queue.put_nowait
andQueue.get
public API. For instance, this may be an actual instance ofqueue.Queue
or a subclass thereof, or a proxy obtained bymultiprocessing.managers.SyncManager.Queue()
.This is of course only possible if you are constructing or modifying the configuration dictionary in code.
A string that resolves to a callable which, when called with no arguments, returns the queue instance to use. That callable could be a
queue.Queue
subclass or a function which returns a suitable queue instance, such asmy.module.queue_factory()
.A dict with a
'()'
key which is constructed in the usual way as discussed in 사용자 정의 객체. The result of this construction should be aqueue.Queue
instance.
If the queue
key is absent, a standard unbounded queue.Queue
instance is
created and used.
If the listener
key is present, the corresponding value can be one of the following:
A subclass of
logging.handlers.QueueListener
. This is of course only possible if you are constructing or modifying the configuration dictionary in code.A string which resolves to a class which is a subclass of
QueueListener
, such as'my.package.CustomListener'
.A dict with a
'()'
key which is constructed in the usual way as discussed in 사용자 정의 객체. The result of this construction should be a callable with the same signature as theQueueListener
initializer.
If the listener
key is absent, logging.handlers.QueueListener
is used.
The values under the handlers
key are the names of other handlers in the
configuration (not shown in the above snippet) which will be passed to the queue
listener.
Any custom queue handler and listener classes will need to be defined with the same
initialization signatures as QueueHandler
and
QueueListener
.
Added in version 3.12.
구성 파일 형식¶
fileConfig()
이 이해하는 구성 파일 형식은 configparser
기능을 기반으로 합니다. 파일에는 [loggers]
, [handlers]
및 [formatters]
라는 섹션이 있어야 하며, 이 섹션에서는 파일에 정의된 각 유형의 엔티티를 이름으로 식별합니다. 이러한 엔티티마다 해당 엔티티 구성 방법을 식별하는 별도의 섹션이 있습니다. 따라서, [loggers]
섹션에서 log01
이라고 이름 붙은 로거에 대해, 관련 구성 세부 사항은 [logger_log01]
섹션에 담깁니다. 마찬가지로, [handlers]
섹션에서 hand01
이라고 부르는 처리기는 [handler_hand01]
이라는 섹션에 구성이 담기고, [formatters]
섹션에서 form01
이라고 부르는 포매터는 [formatter_form01]
이라는 섹션에서 구성이 지정됩니다. 루트 로거 구성은 [logger_root]
라는 섹션에서 지정해야 합니다.
참고
fileConfig()
API는 dictConfig()
API보다 오래되었으며 로깅의 특정 측면을 다루는 기능을 제공하지 않습니다. 예를 들어, fileConfig()
를 사용해서는 간단한 정수 수준을 넘어서는 메시지 필터링을 제공하는 Filter
객체를 구성할 수 없습니다. 로깅 구성에 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
The level
entry can be one of DEBUG, INFO, WARNING, ERROR, CRITICAL
or
NOTSET
. For the root logger only, NOTSET
means that all messages will be
logged. Level values are evaluated in the context of the logging
package’s namespace.
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
항목은 (logging
패키지의 이름 공간에서 eval()
로 결정되는) 처리기의 클래스를 나타냅니다. level
은 로거에서처럼 해석되며, NOTSET
은 ‘모든 것을 로깅’을 의미합니다.
formatter
항목은 이 처리기의 포매터의 키 이름을 나타냅니다. 비어 있으면, 기본 포매터(logging._defaultFormatter
)가 사용됩니다. 이름이 지정되면, [formatters]
섹션에 나타나야 하며 구성 파일에 해당 섹션이 있어야 합니다.
The args
entry, when evaluated in the context of the logging
package’s namespace, is the list of arguments to the constructor for the handler
class. Refer to the constructors for the relevant handlers, or to the examples
below, to see how typical entries are constructed. If not provided, it defaults
to ()
.
The optional kwargs
entry, when evaluated in the context of the
logging
package’s namespace, is the keyword argument dict to the constructor
for the handler class. If not provided, it defaults to {}
.
[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 %(customfield)s
datefmt=
style=%
validate=True
defaults={'customfield': 'defaultvalue'}
class=logging.Formatter
The arguments for the formatter configuration are the same as the keys in the dictionary schema formatters section.
The defaults
entry, when evaluated in the context of
the logging
package’s namespace, is a dictionary of default values for
custom formatting fields. If not provided, it defaults to None
.
참고
위에서 설명한 대로 eval()
를 사용하기 때문에, listen()
을 사용하여 소켓을 통해 구성을 보내고 받을 때 발생할 수 있는 잠재적인 보안 위험이 있습니다. 위험은 상호 신뢰가 없는 여러 사용자가 같은 기계에서 코드를 실행할 때로 제한됩니다; 자세한 내용은 listen()
설명서를 참조하십시오.
더 보기
- 모듈
logging
logging 모듈에 관한 API 레퍼런스.
- 모듈
logging.handlers
logging 모듈에 포함된 유용한 처리기.