development

파이썬에서 콘솔 로깅을 비활성화하고 다시 활성화하는 방법은 무엇입니까?

big-blog 2020. 6. 26. 07:48
반응형

파이썬에서 콘솔 로깅을 비활성화하고 다시 활성화하는 방법은 무엇입니까?


Python의 로깅 모듈을 사용하고 있으며 일정 시간 동안 콘솔 로깅을 비활성화하고 싶지만 작동하지 않습니다.

#!/usr/bin/python
import logging

logger = logging.getLogger() # this gets the root logger
# ... here I add my own handlers 
#logger.removeHandler(sys.stdout)
#logger.removeHandler(sys.stderr)

print logger.handlers 
# this will print [<logging.StreamHandler instance at ...>]
# but I may have other handlers there that I want to keep

logger.debug("bla bla")

위의 코드는 bla blastdout을 표시 하며 콘솔 핸들러를 안전하게 비활성화하는 방법을 모르겠습니다. 콘솔 StreamHandler를 다른 콘솔이 아닌 일시적으로 제거하려면 어떻게해야합니까?


나는 이것에 대한 해결책을 찾았다.

logger = logging.getLogger('my-logger')
logger.propagate = False
# now if you use logger it will not log to console.

이렇게하면 콘솔 로깅이 포함 된 상위 로거로 로깅이 전송되지 않습니다.


나는 사용한다:

logger = logging.getLogger()
logger.disabled = True
... whatever you want ...
logger.disabled = False

당신이 사용할 수있는:

logging.basicConfig(level=your_level)

여기서 your_level 은 다음 중 하나입니다.

      'debug': logging.DEBUG,
      'info': logging.INFO,
      'warning': logging.WARNING,
      'error': logging.ERROR,
      'critical': logging.CRITICAL

따라서 your_levellogging.CRITICAL로 설정 하면 다음을 통해 중요한 메시지 만 전송됩니다.

logging.critical('This is a critical error message')

your_levellogging.DEBUG로 설정하면 모든 로깅 수준이 표시됩니다.

자세한 내용은 로깅 예제 를 참조하십시오 .

각 핸들러의 레벨을 변경하는 것과 동일한 방식으로 Handler.setLevel () 함수를 사용하십시오.

import logging
import logging.handlers

LOG_FILENAME = '/tmp/logging_rotatingfile_example.out'

# Set up a specific logger with our desired output level
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.DEBUG)

# Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(
          LOG_FILENAME, maxBytes=20, backupCount=5)

handler.setLevel(logging.CRITICAL)

my_logger.addHandler(handler)

(긴 죽은 질문이지만 미래의 검색 자에게)

원래 포스터의 코드 / 의도에 더 가깝게 파이썬 2.6에서 작동합니다.

#!/usr/bin/python
import logging

logger = logging.getLogger() # this gets the root logger

lhStdout = logger.handlers[0]  # stdout is the only handler initially

# ... here I add my own handlers 
f = open("/tmp/debug","w")          # example handler
lh = logging.StreamHandler(f)
logger.addHandler(lh)

logger.removeHandler(lhStdout)

logger.debug("bla bla")

내가 해결해야 할 문제 는 새 처리기 추가 한 stdout 처리기를 제거하는 것이 었습니다 . 처리기가없는 경우 로거 코드는 stdout을 자동으로 다시 추가하는 것으로 보입니다.


컨텍스트 관리자

import logging 
class DisableLogger():
    def __enter__(self):
       logging.disable(logging.CRITICAL)
    def __exit__(self, a, b, c):
       logging.disable(logging.NOTSET)

사용 예 :

with DisableLogger():
    do_something()

로깅을 완전히 비활성화하려면 :

logging.disable(sys.maxint) # Python 2

logging.disable(sys.maxsize) # Python 3

로깅을 사용하려면 :

logging.disable(logging.NOTSET)

다른 답변은 문제를 완전히 해결하지 못하는 해결 방법을 제공합니다.

logging.getLogger().disabled = True

그리고, 일부 n(50)보다 큰,

logging.disable(n)

첫 번째 해결책의 문제점은 루트 로거에서만 작동한다는 것입니다. 예를 들어 생성 된 다른 로거 logging.getLogger(__name__)는이 방법으로 비활성화되지 않습니다.

두 번째 솔루션은 모든 로그에 영향을줍니다. 그러나 출력을 주어진 수준보다 높은 수준으로 제한하므로 50보다 큰 수준으로 로깅하여 출력을 무시할 수 있습니다.

그것은 예방할 수 있습니다

logging.disable(sys.maxint)

( 소스를 검토 한 후) 내가 알 수있는 한 로깅을 완전히 비활성화하는 유일한 방법입니다.


여기에 정말 좋은 답변이 있지만, 가장 간단한 것은 너무 많이 고려되지 않습니다 (인피니 토에서만).

root_logger = logging.getLogger()
root_logger.disabled = True

루트 로거와 다른 모든 로거를 비활성화합니다. 나는 실제로 테스트하지는 않았지만 가장 빠릅니다.

파이썬 2.7의 로깅 코드에서 나는 이것을 본다.

def handle(self, record):
    """
    Call the handlers for the specified record.

    This method is used for unpickled records received from a socket, as
    well as those created locally. Logger-level filtering is applied.
    """
    if (not self.disabled) and self.filter(record):
        self.callHandlers(record)

즉, 비활성화되면 핸들러가 호출되지 않으며 매우 높은 값으로 필터링하거나 no-op 핸들러를 설정하는 것이 더 효율적이어야합니다.


표준 출력을 전환 할 필요가 없습니다. 더 좋은 방법은 다음과 같습니다.

import logging
class MyLogHandler(logging.Handler):
    def emit(self, record):
        pass

logging.getLogger().addHandler(MyLogHandler())

더 간단한 방법은 다음과 같습니다.

logging.getLogger().setLevel(100)

로깅 모듈을 잘 모르지만 일반적으로 디버그 (또는 정보) 메시지 만 비활성화하려는 방식으로 로깅 모듈을 사용하고 있습니다. Handler.setLevel()로깅 레벨을 위험 또는 그 이상으로 설정하는 데 사용할 수 있습니다 .

또한 sys.stderr 및 sys.stdout을 쓰기 위해 열린 파일로 바꿀 수 있습니다. http://docs.python.org/library/sys.html#sys를 참조 하십시오. stdout . 그러나 나는 그것을 권장하지 않습니다.


당신은 또한 할 수 있습니다 :

handlers = app.logger.handlers
# detach console handler
app.logger.handlers = []
# attach
app.logger.handlers = handlers

import logging

log_file = 'test.log'
info_format = '%(asctime)s - %(levelname)s - %(message)s'
logging.config.dictConfig({
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'info_format': {
            'format': info_format
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'info_format'
        },
        'info_log_file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'level': 'INFO',
            'filename': log_file,
            'formatter': 'info_format'
        }
    },
    'loggers': {
        '': {
            'handlers': [
                'console',
                'info_log_file'
            ],
            'level': 'INFO'
        }
    }
})


class A:

    def __init__(self):
        logging.info('object created of class A')

        self.logger = logging.getLogger()
        self.console_handler = None

    def say(self, word):
        logging.info('A object says: {}'.format(word))

    def disable_console_log(self):
        if self.console_handler is not None:
            # Console log has already been disabled
            return

        for handler in self.logger.handlers:
            if type(handler) is logging.StreamHandler:
                self.console_handler = handler
                self.logger.removeHandler(handler)

    def enable_console_log(self):
        if self.console_handler is None:
            # Console log has already been enabled
            return

        self.logger.addHandler(self.console_handler)
        self.console_handler = None


if __name__ == '__main__':
    a = A()
    a.say('111')
    a.disable_console_log()
    a.say('222')
    a.enable_console_log()
    a.say('333')

콘솔 출력 :

2018-09-15 15:22:23,354 - INFO - object created of class A
2018-09-15 15:22:23,356 - INFO - A object says: 111
2018-09-15 15:22:23,358 - INFO - A object says: 333

test.log 파일 내용 :

2018-09-15 15:22:23,354 - INFO - object created of class A
2018-09-15 15:22:23,356 - INFO - A object says: 111
2018-09-15 15:22:23,357 - INFO - A object says: 222
2018-09-15 15:22:23,358 - INFO - A object says: 333

특정 로거를 일시적으로 비활성화하려면 여기가 수행됩니다.

로그 예

2019-10-02 21:28:45,663 django.request PID: 8  Internal Server Error: /service_portal/get_all_sites

암호

django_request_logger = logging.getLogger('django.request')
django_request_logger.disabled = True
django_request_logger.disabled = False

subclass the handler you want to be able to disable temporarily:

class ToggledHandler(logging.StreamHandler):
"""A handler one can turn on and off"""

def __init__(self, args, kwargs):
    super(ToggledHandler, self).__init__(*args, **kwargs)
    self.enabled = True  # enabled by default

def enable(self):
    """enables"""
    self.enabled = True

def disable(self):
    """disables"""
    self.enabled = False

def emit(self, record):
    """emits, if enabled"""
    if self.enabled:
        # this is taken from the super's emit, implement your own
        try:
            msg = self.format(record)
            stream = self.stream
            stream.write(msg)
            stream.write(self.terminator)
            self.flush()
        except Exception:
            self.handleError(record)

finding the handler by name is quite easy:

_handler = [x for x in logging.getLogger('').handlers if x.name == your_handler_name]
if len(_handler) == 1:
    _handler = _handler[0]
else:
    raise Exception('Expected one handler but found {}'.format(len(_handler))

once found:

_handler.disable()
doStuff()
_handler.enable()

참고URL : https://stackoverflow.com/questions/2266646/how-to-i-disable-and-re-enable-console-logging-in-python

반응형