From 7358512f118b0a3c4e65c957ca08aa4fd17bd875 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 22 Dec 2016 01:20:17 +0900 Subject: [PATCH] logging.info() supports verbosity filter by app.verbosity --- sphinx/util/logging.py | 21 +++++++++++++ tests/test_util_logging.py | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py index 73d9d093b..9ebd661a4 100644 --- a/sphinx/util/logging.py +++ b/sphinx/util/logging.py @@ -13,6 +13,7 @@ from __future__ import absolute_import import logging import logging.handlers from contextlib import contextmanager +from collections import defaultdict from six import PY2, StringIO, string_types from docutils.utils import get_source_line @@ -27,6 +28,17 @@ if False: from sphinx.application import Sphinx # NOQA +VERBOSE = 15 +DEBUG2 = 5 +VERBOSITY_MAP = defaultdict(lambda: 0) # type: Dict[int, int] +VERBOSITY_MAP.update({ + 0: logging.INFO, + 1: VERBOSE, + 2: logging.DEBUG, + 3: DEBUG2, +}) + + def getLogger(name): # type: (str) -> SphinxLoggerAdapter """Get logger wrapped by SphinxLoggerAdapter.""" @@ -72,6 +84,14 @@ class SphinxLoggerAdapter(logging.LoggerAdapter): self.warning(message, **kwargs) + def verbose(self, msg, *args, **kwargs): + # type: (unicode, Any, Any) -> None + self.log(VERBOSE, msg, *args, **kwargs) + + def debug2(self, msg, *args, **kwargs): + # type: (unicode, Any, Any) -> None + self.log(DEBUG2, msg, *args, **kwargs) + def process(self, msg, kwargs): # type: ignore # type: (unicode, Dict) -> Tuple[unicode, Dict] extra = kwargs.setdefault('extra', {}) @@ -285,6 +305,7 @@ def setup(app, status, warning): info_handler = NewLineStreamHandler(status) info_handler.addFilter(InfoFilter()) + info_handler.setLevel(VERBOSITY_MAP.get(app.verbosity)) warning_handler = logging.StreamHandler(warning) warning_handler.addFilter(WarningSuppressor(app)) diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py index b7ce1ef10..6a4d0f315 100644 --- a/tests/test_util_logging.py +++ b/tests/test_util_logging.py @@ -21,6 +21,7 @@ from util import with_app, raises, strip_escseq @with_app() def test_info_and_warning(app, status, warning): + app.verbosity = 3 logging.setup(app, status, warning) logger = logging.getLogger(__name__) @@ -43,6 +44,69 @@ def test_info_and_warning(app, status, warning): assert 'message5' in warning.getvalue() +@with_app() +def test_verbosity_filter(app, status, warning): + # verbosity = 0: INFO + app.verbosity = 0 + logging.setup(app, status, warning) + logger = logging.getLogger(__name__) + + logger.info('message1') + logger.verbose('message2') + logger.debug('message3') + logger.debug2('message4') + + assert 'message1' in status.getvalue() + assert 'message2' not in status.getvalue() + assert 'message3' not in status.getvalue() + assert 'message4' not in status.getvalue() + + # verbosity = 1: VERBOSE + app.verbosity = 1 + logging.setup(app, status, warning) + logger = logging.getLogger(__name__) + + logger.info('message1') + logger.verbose('message2') + logger.debug('message3') + logger.debug2('message4') + + assert 'message1' in status.getvalue() + assert 'message2' in status.getvalue() + assert 'message3' not in status.getvalue() + assert 'message4' not in status.getvalue() + + # verbosity = 2: DEBUG + app.verbosity = 2 + logging.setup(app, status, warning) + logger = logging.getLogger(__name__) + + logger.info('message1') + logger.verbose('message2') + logger.debug('message3') + logger.debug2('message4') + + assert 'message1' in status.getvalue() + assert 'message2' in status.getvalue() + assert 'message3' in status.getvalue() + assert 'message4' not in status.getvalue() + + # verbosity = 3: DEBUG2 + app.verbosity = 3 + logging.setup(app, status, warning) + logger = logging.getLogger(__name__) + + logger.info('message1') + logger.verbose('message2') + logger.debug('message3') + logger.debug2('message4') + + assert 'message1' in status.getvalue() + assert 'message2' in status.getvalue() + assert 'message3' in status.getvalue() + assert 'message4' in status.getvalue() + + @with_app() def test_nonl_info_log(app, status, warning): logging.setup(app, status, warning)