logging
모듈을 사용하여 Python 로깅 을 수행하면 로그 파일 외에도 stdout으로 자동으로 출력 하는 방법 이 있습니까? 예를 들어, 나는 모든 통화를하고 싶습니다 logger.warning
, logger.critical
, logger.error
의도 한 장소로 이동하지만, 또한 항상에 복사 stdout
. 이것은 다음과 같은 메시지 복제를 피하기위한 것입니다.
mylogger.critical("something failed")
print "something failed"
답변
모든 로깅 출력은 핸들러에 의해 처리됩니다. logging.StreamHandler()
루트 로거에 추가하십시오 .
다음은 스트림 핸들러를 구성하고 ( stdout
default 대신 사용 stderr
) 루트 로거에 추가 하는 예제입니다 .
import logging
import sys
root = logging.getLogger()
root.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)
답변
stdout에 로그인하는 가장 간단한 방법 :
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
답변
여러 핸들러를 사용하는 것이 가능합니다.
import logging
import auxiliary_module
# create logger with 'spam_application'
log = logging.getLogger('spam_application')
log.setLevel(logging.DEBUG)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
log.addHandler(fh)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
ch.setFormatter(formatter)
log.addHandler(ch)
log.info('creating an instance of auxiliary_module.Auxiliary')
a = auxiliary_module.Auxiliary()
log.info('created an instance of auxiliary_module.Auxiliary')
log.info('calling auxiliary_module.Auxiliary.do_something')
a.do_something()
log.info('finished auxiliary_module.Auxiliary.do_something')
log.info('calling auxiliary_module.some_function()')
auxiliary_module.some_function()
log.info('done with auxiliary_module.some_function()')
# remember to close the handlers
for handler in log.handlers:
handler.close()
log.removeFilter(handler)
https://docs.python.org/2/howto/logging-cookbook.html을 참조 하십시오
답변
file 및 stdout에 대한 두 개의 핸들러를 작성한 후에 handlers
인수를 사용하여 하나의 로거를 작성할 수 basicConfig
있습니다. 두 핸들러에 대해 동일한 log_level 및 형식 출력이있는 경우 유용 할 수 있습니다.
import logging
import sys
file_handler = logging.FileHandler(filename='tmp.log')
stdout_handler = logging.StreamHandler(sys.stdout)
handlers = [file_handler, stdout_handler]
logging.basicConfig(
level=logging.DEBUG,
format='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s',
handlers=handlers
)
logger = logging.getLogger('LOGGER_NAME')
답변
파일과 stderr에 로그인하는 가장 간단한 방법 :
import logging
logging.basicConfig(filename="logfile.txt")
stderrLogger=logging.StreamHandler()
stderrLogger.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
logging.getLogger().addHandler(stderrLogger)
답변
강력하지만 문서화가 잘되지 않은 logging.config.dictConfig
방법을 기반으로 한 솔루션이 있습니다 . 대신에 모든 로그 메시지를 보내는 stdout
, 그것은 로그 수준과 메시지 전송 ERROR
및 이상으로 stderr
하고 다른 모든 것을 stdout
. 시스템의 다른 부분이 stderr
또는을 듣고있는 경우 유용 할 수 있습니다 stdout
.
import logging
import logging.config
import sys
class _ExcludeErrorsFilter(logging.Filter):
def filter(self, record):
"""Filters out log messages with log level ERROR (numeric value: 40) or higher."""
return record.levelno < 40
config = {
'version': 1,
'filters': {
'exclude_errors': {
'()': _ExcludeErrorsFilter
}
},
'formatters': {
# Modify log message format here or replace with your custom formatter class
'my_formatter': {
'format': '(%(process)d) %(asctime)s %(name)s (line %(lineno)s) | %(levelname)s %(message)s'
}
},
'handlers': {
'console_stderr': {
# Sends log messages with log level ERROR or higher to stderr
'class': 'logging.StreamHandler',
'level': 'ERROR',
'formatter': 'my_formatter',
'stream': sys.stderr
},
'console_stdout': {
# Sends log messages with log level lower than ERROR to stdout
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'my_formatter',
'filters': ['exclude_errors'],
'stream': sys.stdout
},
'file': {
# Sends all log messages to a file
'class': 'logging.FileHandler',
'level': 'DEBUG',
'formatter': 'my_formatter',
'filename': 'my.log',
'encoding': 'utf8'
}
},
'root': {
# In general, this should be kept at 'NOTSET'.
# Otherwise it would interfere with the log levels set for each handler.
'level': 'NOTSET',
'handlers': ['console_stderr', 'console_stdout', 'file']
},
}
logging.config.dictConfig(config)
답변
깔끔한 2 개의 라이너를 공유 한 사람이 없기 때문에 본인의 것을 공유 할 것입니다.
logging.basicConfig(filename='logs.log', level=logging.DEBUG, format="%(asctime)s:%(levelname)s: %(message)s")
logging.getLogger().addHandler(logging.StreamHandler())
