Pythonの logging モジュールを使用しています。しばらくの間コンソールロギングを無効にしたいのですが、機能しません。
#!/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 bla
を標準出力に表示しますが、コンソールハンドラーを安全に無効にする方法はわかりません。コンソール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_levelをlogging.CRITICALに設定すると、以下によって送信された重要なメッセージのみ:
logging.critical('This is a critical error message')
your_levelをlogging.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)
(長い質問ですが、将来の検索者向け)
元のポスターのコード/意図に近い、これはpython 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ハンドラーを削除することでしたafter新しいハンドラーを追加します。ハンドラが存在しない場合、ロガーコードは自動的に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__)
を使用して作成された他のロガーは、このメソッドでは無効になりません。
2番目の解決策は、すべてのログに影響します。ただし、指定されたレベルを超えるレベルに出力が制限されるため、50を超えるレベルでログを記録することで出力をオーバーライドできます。
それを防ぐことができます
logging.disable(sys.maxint)
( source を確認した後)これがロギングを完全に無効にする唯一の方法です。
ここには本当に素敵な答えがいくつかありますが、明らかに最も単純なものはあまり考慮されていません(infinitoからのみ)。
root_logger = logging.getLogger()
root_logger.disabled = True
これにより、ルートロガーが無効になり、他のすべてのロガーも無効になります。私は実際にテストしていませんが、最速であるべきです。
python 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()
を使用して、ロギングレベルをCRITICAL以上に設定できます。
また、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 __== '__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
一時的に無効にできるようにするハンドラーをサブクラス化します。
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)
名前でハンドラーを見つけるのは非常に簡単です。
_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))
一度見つかった:
_handler.disable()
doStuff()
_handler.enable()