Let's say I have the following code:
import logging import logging.handlers a = logging.getLogger('myapp') h = logging.handlers.RotatingFileHandler('foo.log') h.setLevel(logging.DEBUG) a.addHandler(h) # The effective log level is still logging.WARN print a.getEffectiveLevel() a.debug('foo message') a.warn('warning message')
I expect that setting logging.DEBUG
on the handler would cause debug-level messages to be written to the log file. However, this prints 30 for the effective level (equal to logging.WARNING
, the default), and only logs the warn
message to the log file, not the debug message.
It appears that the handler's log level is being dropped on the floor, e.g. it's silently ignored. Which makes me wonder, why have setLevel
on the handler at all?
The level set in the logger determines which severity of messages it will pass to its handlers. The level set in each handler determines which messages that handler will send on." Check under Handlers: http://docs.python.org/2.7/howto/logging.html#logging-advanced-tutorial.
setLevel() method of a Logger class used to set the log level to describe which message levels will be logged by this logger. The level we want to set is passed as a parameter.
The getLogger() function accepts a single argument - the logger's name. It returns a reference to a logger instance with the specified name if provided, or root if not. Multiple calls to getLogger() with the same name will return a reference to the same logger object.
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 .
It allows finer control. By default the root logger has WARNING
level set, this means that it wont print messages with lower level(no matter how the handlers' levels are set!). But, if you set the root logger's level to DEBUG
, indeed the message get sent to the log file:
import logging import logging.handlers a = logging.getLogger('myapp') a.setLevel(logging.DEBUG) # set root's level h = logging.handlers.RotatingFileHandler('foo.log') h.setLevel(logging.DEBUG) a.addHandler(h) print a.getEffectiveLevel() a.debug('foo message') a.warn('warning message')
Now, image that you want to add a new handler that doesn't record debug information. You can do this by simply setting the handler logging level:
import logging import logging.handlers a = logging.getLogger('myapp') a.setLevel(logging.DEBUG) # set root's level h = logging.handlers.RotatingFileHandler('foo.log') h.setLevel(logging.DEBUG) a.addHandler(h) h2 = logging.handlers.RotatingFileHandler('foo2.log') h2.setLevel(logging.WARNING) a.addHandler(h2) print a.getEffectiveLevel() a.debug('foo message') a.warn('warning message')
Now, the log file foo.log
will contain both messages, while the file foo2.log
will only contain the warning message. You could be interested in having a log file of only error-level messages, then simply add a Handler
and set its level to logging.ERROR
, everything using the same Logger
.
You may think of the Logger
logging level as a global restriction on which messages are "interesting" for a given logger and its handlers. The messages that are considered by the logger afterwards get sent to the handlers, which perform their own filtering and logging process.
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