Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of loggers with propagate=False #44

Open
blueyed opened this issue May 30, 2016 · 5 comments
Open

Handling of loggers with propagate=False #44

blueyed opened this issue May 30, 2016 · 5 comments

Comments

@blueyed
Copy link
Contributor

blueyed commented May 30, 2016

What is the recommended way to handle loggers that are configured with propagate=False, which appears to cause the message not to reach the caplog handler?

I can manually change the propagate setting in the test (setup), but there might be a better way?!

import logging
logging.getLogger('project.app').propagate = True

Could pytest-catchlog take care of this automatically, e.g. by attaching its handler to all loggers with propagate=False?

Would it be feasible to have something like caplog.with_logger, where you could pass in a logger name and caplog would attach it's handler there directly?

@blueyed
Copy link
Contributor Author

blueyed commented May 30, 2016

This seems to do the trick:

@pytest.yield_fixture
def caplog(caplog):
    import logging

    restore = []
    for logger in logging.Logger.manager.loggerDict.values():
        try:
            if not logger.propagate:
                restore += [(logger, logger.propagate)]
                logger.propagate = True
        except AttributeError:
            pass
    yield caplog

    for logger, value in restore:
        logger.propagate = value

@blueyed
Copy link
Contributor Author

blueyed commented Jun 17, 2016

It might be better to add the caplog handler to the loggers with propagate=False (logger.addHandler(caplog.handler)), but that resulted in some ValueError: I/O operation on closed file, and the handler is probably not meant to be used like that.

@abusalimov
Copy link
Collaborator

Sound good! I wish I had more spare time time to investigate that...

@blueyed
Copy link
Contributor Author

blueyed commented Jul 7, 2016

FWIW, this is the current function I am using:

@pytest.yield_fixture
def caplog(caplog):
    import logging

    restore = []
    for logger in logging.Logger.manager.loggerDict.values():
        try:
            if not logger.propagate:
                logger.propagate = True
                restore += [logger]
        except AttributeError:
            pass
    yield caplog
    for logger in restore:
        logger.propagate = False

dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 5, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 5, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 11, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 12, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 18, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 19, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 19, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 19, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 19, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 19, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 24, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 24, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 24, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 24, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 24, 2016
dwaynebailey added a commit to dwaynebailey/pootle that referenced this issue Aug 24, 2016
@marc1n
Copy link

marc1n commented May 30, 2018

My solution is:

@contextlib.contextmanager
def caplog_for_logger(caplog, logger_name):
    caplog.clear()
    caplog.set_level(logging.CRITICAL)  # Mute the root-logger
    logger = logging.getLogger(logger_name)
    logger.addHandler(caplog.handler)
    yield
    logger.removeHandler(caplog.handler)

def test_foobar(self, caplog):
        with caplog_for_logger(caplog, 'my-logger-name):
            # testing ....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants