아무것도 출력하지 않는 Python 로깅


97

내가 쓰는 파이썬 스크립트에서 로깅 모듈을 사용하여 이벤트를 기록하려고합니다. 로거를 구성하려면 다음 코드가 있습니다.

ERROR_FORMAT = "%(levelname)s at %(asctime)s in %(funcName)s in %(filename) at line %(lineno)d: %(message)s"
DEBUG_FORMAT = "%(lineno)d in %(filename)s at %(asctime)s: %(message)s"
LOG_CONFIG = {'version':1,
              'formatters':{'error':{'format':ERROR_FORMAT},
                            'debug':{'format':DEBUG_FORMAT}},
              'handlers':{'console':{'class':'logging.StreamHandler',
                                     'formatter':'debug',
                                     'level':logging.DEBUG},
                          'file':{'class':'logging.FileHandler',
                                  'filename':'/usr/local/logs/DatabaseUpdate.log',
                                  'formatter':'error',
                                  'level':logging.ERROR}},
              'root':{'handlers':('console', 'file')}}
logging.config.dictConfig(LOG_CONFIG)

을 실행하려고 할 때 문서의이 페이지에 루트 로거가 메시지를 출력해야 한다고 말 logging.debug("Some string")하더라도 콘솔에 출력이 표시되지 않습니다. 내 프로그램이 아무 것도 출력하지 않는 이유는 무엇이며 어떻게 수정할 수 있습니까?logging.debug

답변:


103

기본 로깅 수준은 경고입니다. 레벨을 변경하지 않았으므로 루트 로거의 레벨은 여전히 ​​경고입니다. 즉, 디버그 로깅을 포함하여 경고보다 낮은 수준의 로깅은 무시됩니다.

이것은 튜토리얼에 설명되어 있습니다 .

import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything

레벨이 정보보다 높기 때문에 'info'라인은 아무것도 인쇄하지 않습니다.

레벨을 변경하려면 루트 로거에서 설정하십시오.

'root':{'handlers':('console', 'file'), 'level':'DEBUG'}

즉, level = DEBUG로 핸들러를 정의하는 것으로는 충분하지 않습니다. 실제 로깅 레벨도 DEBUG가되어야 출력 할 수 있습니다.


7
문서에 따르면 기본 수준은 모든 것을 출력해야하는 0 수준 인 NOTSET입니다. 왜 이것이 사실이 아닌가?
Ben

@Ben은 어디라고 말합니까? 내가 볼 수있는 것은 "기본 수준은 WARNING입니다. 이는 로깅 패키지가 달리 수행하도록 구성되지 않은 경우이 수준 이상의 이벤트 만 추적됨을 의미합니다."
Omri Barel


1
@Ben 문서에 따르면 로거는 첫 번째 부모 level != NOTSET또는 루트 를 찾기 위해 순회됩니다 (찾을 수 없는 경우). 루트에는 WARNING기본적으로 레벨 이 있습니다. 이것은 귀하가 링크 한 섹션 ( Logger.setLevel)에 작성되었습니다 .
Omri Barel

5
가져온 후에 는 한 번 이상 logging전화해야합니다 logging.basicConfig(). 그렇지 않으면 자식 로거가 아무것도 인쇄하지 않는다는 사실에 놀라실 수 있습니다. 루트 로거의 로깅 기능은 느리게 호출합니다.
Hubert Grzeskowiak

72

수년이 지난 후에도 여전히 Python 로거에 사용성 문제가있는 것 같습니다. 다음은 예제와 함께 몇 가지 설명입니다.

import logging
# This sets the root logger to write to stdout (your console).
# Your script/app needs to call this somewhere at least once.
logging.basicConfig()

# By default the root logger is set to WARNING and all loggers you define
# inherit that value. Here we set the root logger to NOTSET. This logging
# level is automatically inherited by all existing and new sub-loggers
# that do not set a less verbose level.
logging.root.setLevel(logging.NOTSET)

# The following line sets the root logger level as well.
# It's equivalent to both previous statements combined:
logging.basicConfig(level=logging.NOTSET)


# You can either share the `logger` object between all your files or the
# name handle (here `my-app`) and call `logging.getLogger` with it.
# The result is the same.
handle = "my-app"
logger1 = logging.getLogger(handle)
logger2 = logging.getLogger(handle)
# logger1 and logger2 point to the same object:
# (logger1 is logger2) == True


# Convenient methods in order of verbosity from highest to lowest
logger.debug("this will get printed")
logger.info("this will get printed")
logger.warning("this will get printed")
logger.error("this will get printed")
logger.critical("this will get printed")


# In large applications where you would like more control over the logging,
# create sub-loggers from your main application logger.
component_logger = logger.getChild("component-a")
component_logger.info("this will get printed with the prefix `my-app.component-a`")

# If you wish to control the logging levels, you can set the level anywhere 
# in the hierarchy:
#
# - root
#   - my-app
#     - component-a
#

# Example for development:
logger.setLevel(logging.DEBUG)

# If that prints too much, enable debug printing only for your component:
component_logger.setLevel(logging.DEBUG)


# For production you rather want:
logger.setLevel(logging.WARNING)

일반적인 혼동의 원인은 잘못 초기화 된 루트 로거에서 비롯됩니다. 이걸 고려하세요:

import logging
log = logging.getLogger("myapp")
log.warning("woot")
logging.basicConfig()
log.warning("woot")

산출:

woot
WARNING:myapp:woot

런타임 환경 및 로깅 수준에 따라 첫 번째 로그 줄 (기본 구성 이전)이 어디에도 표시되지 않을 수 있습니다 .


내 로깅이 작동하지 않아 출력 파일이 생성되지 않습니다. 내가하는 일이 분명히 잘못된 것 같습니까? logging.basicConfig( filename='logging.txt', level=logging.DEBUG) logger = logging.getLogger() logger.info('Test B') logging.info('Test A')
Rylan Schaeffer

로깅 파일도 생성되지 않았습니다
Rylan Schaeffer

이후에 중단 점을 삭제 logger = logging.getLogger()하면 수준을으로 지정했지만 수준이 WARNING으로 설정되어 있음을 알았습니다 DEBUG. 내가 뭘 잘못하고 있는지 알아?
Rylan Schaeffer

@RylanSchaeffer 님, 새 질문을 작성하고 더 자세한 정보를 제공 할 수 있습니다. 이것은 또한 다른 사람들에게 당신을 도울 기회를 줄 것입니다.
Hubert Grzeskowiak

내가했다. 자주, 댓글을 묻는 것이 답을 찾는 빠른 방법입니다. 최소한 한 명의 지식이있는 사람이 내 질문을 볼 수 있기 때문입니다
Rylan Schaeffer

26

여기에 아주 간단한 대답을 원하는 사람이라면 표시 할 수준을 설정하기 만하면됩니다. 내 모든 스크립트의 맨 위에 방금 넣었습니다.

import logging
logging.basicConfig(level = logging.INFO)

그런 다음 해당 수준 이상을 표시하려면 :

logging.info("Hi you just set your fleeb to level plumbus")

로그가 사용자가 설정 한 수준 이상으로 표시되도록 5 개 수준의 계층 적 집합입니다 . 따라서 오류를 표시하려면 logging.error("The plumbus is broken").

심각도의 순서를 증가의 수준이다 DEBUG, INFO, WARNING, ERROR,와 CRITICAL. 기본 설정은 WARNING입니다.

이것은 내 대답보다 더 잘 표현 된이 정보를 포함하는 좋은 기사입니다 :
https://www.digitalocean.com/community/tutorials/how-to-use-logging-in-python-3


14

시도해 볼까요? 제 경우에는 모든 핸들러를 제거한 후 문제가 해결 된 것 같습니다.

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

logging.basicConfig(filename='output.log', level=logging.INFO)

SyntaxError: invalid syntax
Eric

2
왜 이것이 필요한가요? 파이썬 로거와 함께 제공되는 핸들러는 무엇이며 시작해야하는 이유는 무엇입니까? 아니면 질문은 왜 basicConfig가 그것들을 덮어 쓰거나 대체하지 않는 것일까 요?
jrh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.