I want to log messages of a specific logger name, of a certain level and higher (say INFO
and up) to a specific log handler, say a file handler, while still getting all log messages to the console. Python is version 2.7.
What I tried until now was to create two loggers:
For the root logger, I attached a logging.StreamHandler
, and set the log level to logging.DEBUG
.
Then I attached a handler to the named logger and set level to logging.INFO
for that logger.
When I now call my module, which uses the named logger, I do not get DEBUG
logs propagated to the root logger any more.
Note: the extraLogger has a StreamHandler here to demonstrate the issue. In my production code I'd use a FileHandler
import logging
def do_logging(turn):
logger = logging.getLogger('extra')
logger.info('some info turn %d' % turn)
logger.debug('this is debug fudge turn %d' % turn)
rootLogger = logging.getLogger()
handler = logging.StreamHandler()
rootFormatter = logging.Formatter('root - %(levelname)s: %(msg)s')
handler.setFormatter(rootFormatter)
rootLogger.addHandler(handler)
rootLogger.setLevel(logging.DEBUG)
do_logging(1)
extraLogger = logging.getLogger('extra')
extraHandler = logging.StreamHandler()
extraFormatter = logging.Formatter('extra - %(levelname)s: %(msg)s')
extraHandler.setFormatter(extraFormatter)
extraLogger.addHandler(extraHandler)
extraLogger.setLevel(logging.INFO)
do_logging(2)
Actual Output:
root - INFO: some info turn 1
root - DEBUG: this is debug fudge turn 1
extra - INFO: some info turn 2
root - INFO: some info turn 2
Output that I would like to have:
root - INFO: some info turn 1
root - DEBUG: this is debug fudge turn 1
extra - INFO: some info turn 2
root - INFO: some info turn 2
root - DEBUG: this is debug fudge turn 2
I suspect that a custom Filter
would be helpful in this case, but I do not know how...
You could use robert's LevelFilter like this:
# Put the Filter on the Handler so only INFO and higher is handled
extraHandler.addFilter(LevelFilter(logging.INFO))
# Let the Logger process everything (so it can propagate records to root)
extraLogger.setLevel(logging.DEBUG)
import logging
class LevelFilter(logging.Filter):
"""
https://stackoverflow.com/a/7447596/190597 (robert)
"""
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno >= self.level
def do_logging(turn):
logger = logging.getLogger('extra')
logger.info('some info turn %d' % turn)
logger.debug('this is debug fudge turn %d' % turn)
rootLogger = logging.getLogger()
handler = logging.StreamHandler()
rootFormatter = logging.Formatter('root - %(levelname)s: %(msg)s')
handler.setFormatter(rootFormatter)
rootLogger.addHandler(handler)
rootLogger.setLevel(logging.DEBUG)
do_logging(1)
extraLogger = logging.getLogger('extra')
extraHandler = logging.StreamHandler()
extraFormatter = logging.Formatter('extra - %(levelname)s: %(msg)s')
extraHandler.setFormatter(extraFormatter)
extraLogger.addHandler(extraHandler)
# Put the Filter on the Handler so only INFO and higher is handled
extraHandler.addFilter(LevelFilter(logging.INFO))
# Handle everything (so it can propagate to root)
extraLogger.setLevel(logging.DEBUG)
do_logging(2)
If this attribute evaluates to true, events logged to this logger will be passed to the handlers of higher level (ancestor) loggers, in addition to any handlers attached to this logger. Messages are passed directly to the ancestor loggers' handlers - neither the level nor filters of the ancestor loggers in question are considered.
If this evaluates to false, logging messages are not passed to the handlers of ancestor loggers.
please visit official python site for detailed discussion regarding this.
import logging
handler = logging.StreamHandler()
parent = logging.getLogger("parent")
parent.addHandler(handler)
child = logging.getLogger("parent.child")
child.propagate = False
child.setLevel(logging.DEBUG)
child.addHandler(handler)
child.info("HELLO")
$ python3.10 propagate.py
HELLO
import logging
handler = logging.StreamHandler()
parent = logging.getLogger("parent")
parent.addHandler(handler)
child = logging.getLogger("parent.child")
#child.propagate = False
child.setLevel(logging.DEBUG)
child.addHandler(handler)
child.info("HELLO")
$ python3.10 propagate.py
HELLO
HELLO
记录器类中有一个名为“propagate”的方法似乎可以满足您的要求: http : //docs.python.org/2/library/logging.html#logger-objects
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.