<질문>
내가 쓰고 있는 파이썬 스크립트에서 로깅 모듈을 사용하여 이벤트를 기록하려고 합니다. 내 로거를 구성하는 다음 코드가 있습니다.
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")
, 콘솔에 출력을 얻지 못하더라도this page in the docs 말한다logging.debug
루트 로거가 메시지를 출력해야 합니다. 내 프로그램이 아무 것도 출력하지 않는 이유는 무엇이며 어떻게 고칠 수 있습니까?
<답변1>
수년이 지난 후에도 여전히 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
logger = logging.getLogger("my-app")
# 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
런타임 환경 및 로깅 수준에 따라,기본 구성 이전의 첫 번째 로그 줄은 어디에도 표시되지 않을 수 있음.
<답변2>
기본 로깅 수준은 경고입니다. 레벨을 변경하지 않았기 때문에 루트 로거의 레벨은 여전히 경고입니다. 즉, 디버그 로깅을 포함하여 경고보다 낮은 수준의 로깅은 무시됩니다.
이것은tutorial:
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여야 무엇이든 출력할 수 있습니다.
<답변3>
여기에서 매우 간단한 답변을 원하는 모든 사람을 위해: 표시하려는 수준을 설정하기만 하면 됩니다. 내 모든 스크립트의 맨 위에 방금 넣었습니다.
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
<답변4>
어쩌면 이것을 시도? 제 경우에는 모든 처리기를 제거한 후 문제가 해결된 것 같습니다.
for handler in logging.root.handlers[:]:
logging.root.removeHandler(handler)
logging.basicConfig(filename='output.log', level=logging.INFO)
<답변5>
이 문제로 인해 많은 시간이 낭비되었으므로 답변을 작성하고 귀하의 답변을 저장하는 데 시간을 더 투자하겠습니다.
사용자 지정 로거에 대한 로깅 수준을 설정할 수 없습니다. (예: DEBUG 수준으로)
핸들러에 로깅 수준을 설정합니다.
import logging
# Get logger
logger = logging.getLogger("my logger")
# Create a handler and set logging level for the handler
c_handler = logging.StreamHandler()
c_handler.setLevel(logging.DEBUG) # <- Here things went wrong
# link handler to logger
logger.addHandler(c_handler)
# test
logger.debug('This is a debug message') # WILL NOT WORK
처리기 대신 로거 개체를 통해 로깅 수준 설정Customlogger.setLevel(logging.DEBUG)
import logging
# Get logger
logger = logging.getLogger("my logger")
# Create a handler
c_handler = logging.StreamHandler()
# link handler to logger
logger.addHandler(c_handler)
# Set logging level to the logger
logger.setLevel(logging.DEBUG) # <-- THIS!
# test
logger.debug('This is a debug message') # WILL WORK
<답변6>
import logging
log = logging.getLogger()
log.setLevel(logging.DEBUG)
이 코드는 기본 로깅 수준을 DEBUG로 설정합니다.
<답변7>
removeHandler() 함수를 호출하면 모든 핸들러가 제거된 경우에도 stdout/stderr 출력이 남습니다.
로거를 정리하는 한 가지 방법은 핸들러 목록을 비우는 것입니다. logger.handlers = [] 또는 logger.root.handlers = []
이것은 나를 위해 일했습니다.
'개발 > Python' 카테고리의 다른 글
[파이썬] site-packages 디렉토리는 무엇입니까? (0) | 2022.10.06 |
---|---|
[파이썬] pytorch에서 model.eval()은 무엇을 합니까? (0) | 2022.10.06 |
[파이썬] Django에서 MySQL 설정하는 법 (0) | 2022.10.06 |
[파이썬] 스크립트를 실행하려고 할 때 "ImportError: No module named" (0) | 2022.10.06 |