Reputation: 509
I would like to log all warnings. I thought that setting captureWarnings
to True
should do the trick, but it doesn't. Code:
import logging
import warnings
from logging.handlers import RotatingFileHandler
logger_file_handler = RotatingFileHandler(u'./test.log')
logger_file_handler.setLevel(logging.DEBUG)
logging.captureWarnings(True)
logger = logging.getLogger(__name__)
logger.addHandler(logger_file_handler)
logger.setLevel(logging.DEBUG)
logger.info(u'Test')
warnings.warn(u'Warning test')
My expectation is that 'Warning test' should appear in test.log, but it doesn't; only 'Test' is put in the log file.
How to capture all warnings and redirect them to the log file?
Upvotes: 18
Views: 8016
Reputation: 14255
Not directly relevant for the OP, but may be useful for others winding up here based on the title:
Another reason for warnings not to show up in your logs would be if you use warnings.catch_warnings
with record=True
.
Here's a minimal example:
import logging
import warnings
logging.basicConfig() # configures the root logger
logging.captureWarnings(True)
warnings.warn('logged')
with warnings.catch_warnings():
warnings.warn('also logged')
with warnings.catch_warnings(record=True) as warnings_caught:
warnings.warn('not logged')
# show warnings recorded
print([w.message for w in warnings_caught])
Upvotes: 0
Reputation: 154785
In an application codebase, instead of explicitly configuring the py.warnings
logger as other answers here suggest, you instead can - and probably want to - configure the root logger. This will:
py.warnings
(the logger that the captureWarnings
integration logs with)logging.info
instead of making a logger objectThe following simple demo logs your warning as you want it to:
import logging
import warnings
from logging.handlers import RotatingFileHandler
logger_file_handler = RotatingFileHandler(u'./test.log')
logger_file_handler.setLevel(logging.DEBUG)
logging.captureWarnings(True)
root_logger = logging.getLogger()
root_logger.addHandler(logger_file_handler)
root_logger.setLevel(logging.DEBUG)
logging.info(u'Test')
warnings.warn(u'Warning test')
Upvotes: 6
Reputation: 9599
From the logging.captureWarnings
documentation:
Warnings issued by the warnings module will be redirected to the logging system. Specifically, a warning will be formatted using
warnings.formatwarning()
and the resulting string logged to a logger named 'py.warnings' with a severity of WARNING.
You probably want something like this:
import logging
import warnings
from logging.handlers import RotatingFileHandler
logger_file_handler = RotatingFileHandler(u'test.log')
logger_file_handler.setLevel(logging.DEBUG)
logging.captureWarnings(True)
logger = logging.getLogger(__name__)
warnings_logger = logging.getLogger("py.warnings")
logger.addHandler(logger_file_handler)
logger.setLevel(logging.DEBUG)
warnings_logger.addHandler(logger_file_handler)
logger.info(u'Test')
warnings.warn(u'Warning test')
Hope it helps!
Upvotes: 19
Reputation: 281252
logging.captureWarnings
is not using your logger. It uses a logger named 'py.warnings'
. You will need to configure that logger to do what you want.
Upvotes: 4