If you dont want to write the module name as a string, you can also use imported_module. __name__. If you want to go a level higher and only want to log messages when they are errors or critical, you can do replace logging.
The inbuilt logging module in python requires some handful of lines of code to configure log4j-like features viz - file appender, file rotation based on both time & size. For one-liner implementation of the features in your code, you can use the package autopylogger .
The problem is that calling getLogger
without arguments returns the root logger so when you set the level to logging.DEBUG
you are also setting the level for other modules that use that logger.
You can solve this by simply not using the root logger. To do this just pass a name as argument, for example the name of your module:
logger = logging.getLogger('my_module_name')
# as before
this will create a new logger and thus it wont inadvertently change logging level for other modules.
Obviously you have to use logger.debug
instead of logging.debug
since the latter is a convenience function that calls the debug
method of the root logger.
This is mentioned in the Advanced Logging Tutorial. It also allows you to know which module triggered the log message in a simple way.
If you're going to use the python logging
package, it's a common convention to define a logger in every module that uses it.
logger = logging.getLogger(__name__)
Many popular python packages do this, including requests
. If a package uses this convention, it's easy to enable/disable logging for it, because the logger name will be the same name as the package (or will be a child of that logger). You can even log it to the same file as your other loggers.
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
requests_logger = logging.getLogger('requests')
requests_logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
requests_logger.addHandler(handler)
Not sure if this is appropriate to post, but I was stuck for a long time & wanted to help out anyone with the same issue, as I hadn't found it anywhere else!
I was getting debug logs from matplotlib despite following the pretty straightforward documentation at the logging advanced tutorial
and the troubleshooting. I was initiating my logger in main()
of one file and importing a function to create a plot from another file (where I had imported matplotlib).
What worked for me was setting the level of matplotlib before importing it, rather than after as I had for other modules in my main file. This seemed counterintuitive to me so if anyone has insight into how you can set the config for a logger that hasn't been imported yet I'd be curious to find out how this works. Thanks!
In my main file:
import logging
import requests
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logging.getLogger('requests').setLevel(logging.DEBUG)
def main():
...
In my plot.py
file:
import logging
logging.getLogger('matplotlib').setLevel(logging.WARNING)
import matplotlib.pyplot as plt
def generatePlot():
...
This disables all existing loggers, such as those created by imported modules, while still using the root logger (and without having to load an external file).
import logging.config
logging.config.dictConfig({
'version': 1,
'disable_existing_loggers': True,
})
Note that you need to import all modules you don't want logged first! Otherwise those won't be considered as "existing loggers". It will then disable all loggers from those modules. This might lead you to also miss out on important errors!
For more detailed examples using related options for configuration, see https://gist.github.com/st4lk/6287746, and here is a (partially working) example using YAML for config with the coloredlog
library.
@Bakuriu quite elegantly explains the function. Conversely, you can use the getLogger()
method to retrieve and reconfigure/disable the unwanted loggers.
I also wanted to add the logging.fileConfig()
method accepts a parameter called disable_existing_loggers
which will disable any loggers previously defined (i.e., in imported modules).
You could use something like:
logging.getLogger("imported_module").setLevel(logging.WARNING)
logging.getLogger("my_own_logger_name").setLevel(logging.DEBUG)
This will set my own module's log level to DEBUG, while preventing the imported module from using the same level.
Note:
"imported_module"
can be replaced with imported_module.__name__
(without quotes), and "my_own_logger_name"
can be replaced by __name__
if that's the way you prefer to do it.
After trying various answers in this thread and other forums, I found this method efficient at silencing other modules' loggers. This was inspired by the following link:
https://kmasif.com/2019-11-12-ignore-logging-from-imported-module/
import logging
# Initialize your own logger
logger = logging.getLogger('<module name>')
logger.setLevel(logging.DEBUG)
# Silence other loggers
for log_name, log_obj in logging.Logger.manager.loggerDict.items():
if log_name != '<module name>':
log_obj.disabled = True
Note that you would want to do this after importing other modules. However, I found this to be a convenient and fast way to disabled other modules' loggers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With