How to disable logging on the standard error stream?
Solution 1
I found a solution for this:
logger = logging.getLogger('my-logger')
logger.propagate = False
# now if you use logger it will not log to console.
This will prevent logging from being send to the upper logger that includes the console logging.
Solution 2
I use:
logger = logging.getLogger()
logger.disabled = True
... whatever you want ...
logger.disabled = False
Solution 3
You can use:
logging.basicConfig(level=your_level)
where your_level is one of those:
'debug': logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARNING,
'error': logging.ERROR,
'critical': logging.CRITICAL
So, if you set your_level to logging.CRITICAL, you will get only critical messages sent by:
logging.critical('This is a critical error message')
Setting your_level to logging.DEBUG will show all levels of logging.
For more details, please take a look at logging examples.
In the same manner to change level for each Handler use Handler.setLevel() function.
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)
Solution 4
Using Context manager - [ most simple ]
import logging
class DisableLogger():
def __enter__(self):
logging.disable(logging.CRITICAL)
def __exit__(self, exit_type, exit_value, exit_traceback):
logging.disable(logging.NOTSET)
Example of use:
with DisableLogger():
do_something()
If you need a [more COMPLEX] fine-grained solution you can look at AdvancedLogger
AdvancedLogger can be used for fine grained logging temporary modifications
How it works:
Modifications will be enabled when context_manager/decorator starts working and be reverted after
Usage:
AdvancedLogger can be used
- as decorator `@AdvancedLogger()`
- as context manager `with AdvancedLogger():`
It has three main functions/features:
- disable loggers and it's handlers by using disable_logger= argument
- enable/change loggers and it's handlers by using enable_logger= argument
- disable specific handlers for all loggers, by using disable_handler= argument
All features they can be used together
Use cases for AdvancedLogger
# Disable specific logger handler, for example for stripe logger disable console
AdvancedLogger(disable_logger={"stripe": "console"})
AdvancedLogger(disable_logger={"stripe": ["console", "console2"]})
# Enable/Set loggers
# Set level for "stripe" logger to 50
AdvancedLogger(enable_logger={"stripe": 50})
AdvancedLogger(enable_logger={"stripe": {"level": 50, "propagate": True}})
# Adjust already registered handlers
AdvancedLogger(enable_logger={"stripe": {"handlers": "console"}
Solution 5
(long dead question, but for future searchers)
Closer to the original poster's code/intent, this works for me under 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")
The gotcha I had to work out was to remove the stdout handler after adding a new one; the logger code appears to automatically re-add the stdout if no handlers are present.
IndexOutOfBound Fix: If you get a IndexOutOfBound Error while instantiating lhStdout, move the instantiation to after adding your file handler i.e.
...
logger.addHandler(lh)
lhStdout = logger.handlers[0]
logger.removeHandler(lhStdout)
Related videos on Youtube
sorin
Another geek still trying to decipher the meaning of “42”. It seems that amount his main interest are: online communities of practice and the way they evolve in time product design, simplicity in design and accessibility productivity and the way the IT solutions are impacting it
Updated on March 26, 2022Comments
-
sorin about 2 years
How to disable logging on the standard error stream in Python? This does not work:
import logging logger = logging.getLogger() logger.removeHandler(sys.stderr) logger.warning('foobar') # emits 'foobar' on sys.stderr
-
Stevoisiak about 6 yearsFor those wondering why anyone would want to disable logging: You wouldn't want to log private data like passwords or API keys.
-
Mad Physicist almost 6 years@StevenVascellaro. Why are those being sent to a logger in the first place then? That doesn't sound right...
-
Stevoisiak almost 6 years@MadPhysicist I have an application which sends XML requests to an external API. By default, these requests are logged to a file. However, the initial login requires authentication with a username and password, which I don't want logged.
-
Mad Physicist almost 6 years@StevenVascellaro. I see. Thanks for the explanation.
-
Piotr Dobrogost over 5 yearsYou do not show how/where you add your handlers. If they were added to the root logger this would prevent logging from adding default StreamHandler as described at docs.python.org/3/library/logging.html#logging.basicConfig Also, per linked description, the default StreamHandler is only added during first call emitting log message so when you print
logger.handlers
it should be empty (as it precedeslogger.debug()
call). The code in question displays only[]
(empty list of handlers). Verified with Python 2.7.15 and Python 3.6.6. -
random_forest_fanatic over 5 years@StevenM.Vascellaro Another reason for disabling logging is if a third-party package is way too verbose, and is making it hard to find the relevant logs among all the others.
-
-
sorin about 14 yearsThis could work if logger.handlers would be contain something, currently is
[]
. -
Chris about 10 yearsI really like this idiom, but I would rather be able to disable a particular namespace. For example, I just want the root logger temporarily disabled. Although using this idiom, we should be able to just temporarily add/remove handlers and the such.
-
Pierre almost 10 yearsIn Python 2.7+ this is available as NullHandler()
-
lsh almost 8 yearsthis also works at the
logging
module level to disable logging entirely, for example:import logging; logging.disable(logging.CRITICAL);
: docs.python.org/2/library/logging.html#logging.disable -
starfry almost 7 yearsUnless I am doing something wrong, this only disables the root logger and not any created like
log = logging.getLogger(__name__)
-
Joe almost 7 yearsThis is generally useful info, but the question asked how t o disable console logging, not how to add an additional handler. if you were to examine my_logger.handlers with the above code applied to the original example, you'd see two handlers -- your new file handler and the original stream handler.
-
Joe almost 7 yearsThis could be problematic if you're dealing with multiple loggers or multiple handlers. If, for example, you still want to log to a file but want to disable the stream handler in a specific case.
-
lfk over 6 yearsI don't think this is a good solution. Not propagating to higher loggers could have other undesirable consequences.
-
Hartley Brody over 6 yearsIf you wanted to only filter message below a certain log level (say, all
INFO
messages), you could change the second line to something likelogger.setLevel(logging.WARNING)
-
Stevoisiak about 6 yearsHow would you re-enable the log afterwards?
-
Mátray Márk over 5 yearsThis is much better than disabling propagation.
-
Piotr Dobrogost over 5 yearsThe reason why this works (disables default StreamHandler) can be seen when reading description of
logging.basicConfig()
function (emphasis mine): Does basic configuration for the logging system by creating a StreamHandler with a default Formatter and adding it to the root logger. The functions debug(), info(), warning(), error() and critical() will call basicConfig() automatically if no handlers are defined for the root logger. – docs.python.org/3/library/logging.html#logging.basicConfig -
Piotr Dobrogost over 5 yearsDownvote as the question asks how to disable standard StreamHandler only
-
Piotr Dobrogost over 5 yearsWhy are you using
app.logger
which you don't even specify instead of the root logger explicitly mentioned in the question (logging.getLogger()
) and most answers? How do you know you can safely modifyhandlers
property instead of callingLogger.addHandler
method? -
Piotr Dobrogost over 5 yearsThis disables the root logger, and thus all the other loggers – strictly speaking disabling the root logger does not disable any other loggers. Besides the question asks about disabling default StreamHandler only.
-
Piotr Dobrogost over 5 yearsThe question asks how to disable default StreamHandler only.
-
Piotr Dobrogost over 5 yearsThe sequence
logger = logging.getLogger(); lhStdout = logger.handlers[0]
is wrong as the root logger initially has no handlers –python -c "import logging; assert not logging.getLogger().handlers"
. Verified with Python 2.7.15 and Python 3.6.6. -
Piotr Dobrogost over 5 yearsNot an answer – the question asks how to disable default StreamHandler only.
-
Piotr Dobrogost over 5 yearsNot an answer as blocking propagation effectively disables all handlers of the root logger and the question clearly states (…) but I may have other handlers there that I want to keep which suggests the intention is to disable default StreamHandler of the root logger only.
-
Mathews Sunny over 5 yearsAdd some description about the code. It would help much better
-
KristianR over 5 yearsYou don’t need to roll your own class, you can use @contextmanager from contextlib and write a yielding function
-
Maggyero about 5 yearsThe
disabled
attribute is not part of the public API. See bugs.python.org/issue36318. -
Maggyero about 5 yearsThe
disabled
attribute is not part of the public API. See bugs.python.org/issue36318. -
user3504575 about 5 yearsIf you are into exotic fruits on your pizza. Sure.
-
Nishant about 5 yearsCRITICAL was the word I was looking for. Thanks.
-
Not a machine over 4 yearsI would love to see a debug level of OFF. It is unambiguous and simple.
-
Maggyero about 4 yearsStopping message propagation is not enough. Since Python 3.2, the
logging.lastResort
handler will still log messages of severitylogging.WARNING
and greater tosys.stderr
in the absence of other handlers. See my answer. -
pymen over 3 years@PiotrDobrogost i have added a link to AdvancedLogger which allows to temporary disable output to console (StreamHandler)
-
NealWalters over 3 yearsExcellent, but the question also asked how to re-enable it? For example, would you do a removeFilter and how?
-
Maggyero over 3 years@NealWalters For the 1st solution, you would create a handler:
handler = logging.NullHandler()
, add it to the logger and disable propagation to disable logging:logger.addHandler(handler); logger.propagate = False
, and remove it from the logger and re-enable propagation to re-enable logging:logger.removeHandler(handler); logger.propagate = True
. For the 2nd solution, you would create a filter:def filter(record): return False
, add it to the logger to disable logging:logger.addFilter(filter)
, and remove it from the logger to re-enable logging:logger.removeFilter(filter)
. -
yucer over 3 yearsshould this be enclosed in try / finally ? What happens if the code rises one exception ? Does the logger remain disabled ?
-
Piotr over 2 yearslogging.CRITICAL+1