Skip to content

Commit 4d0d14e

Browse files
authored
util.config: add context manager to set logging level (#160)
1 parent f3c8727 commit 4d0d14e

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

climada/util/__init__.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
1919
init util
2020
"""
21+
import logging
2122
from pint import UnitRegistry
2223

2324
from .config import *
@@ -26,3 +27,37 @@
2627
from .save import *
2728

2829
ureg = UnitRegistry()
30+
31+
class log_level:
32+
"""Context manager that sets all loggers with names starting with
33+
name_prefix (default is "") to a given specified level.
34+
35+
Examples
36+
--------
37+
Set ALL loggers temporarily to the level 'WARNING'
38+
>>> with log_level(level='WARNING'):
39+
>>> ...
40+
41+
Set all the climada loggers temporarily to the level 'ERROR'
42+
>>> with log_level(level='ERROR', name_prefix='climada'):
43+
>>> ...
44+
45+
"""
46+
47+
def __init__(self, level, name_prefix=""):
48+
self.level = level
49+
self.loggers = {
50+
name: (logger, logger.level)
51+
for name, logger in logging.root.manager.loggerDict.items()
52+
if isinstance(logger, logging.Logger) and name.startswith(name_prefix)
53+
}
54+
if name_prefix == "":
55+
self.loggers[""] = (logging.getLogger(), logging.getLogger().level)
56+
57+
def __enter__(self):
58+
for logger, _ in self.loggers.values():
59+
logger.setLevel(self.level)
60+
61+
def __exit__(self, exception_type, exception, traceback):
62+
for logger, previous_level in self.loggers.values():
63+
logger.setLevel(previous_level)

climada/util/test/test__init__.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""
2+
This file is part of CLIMADA.
3+
4+
Copyright (C) 2017 ETH Zurich, CLIMADA contributors listed in AUTHORS.
5+
6+
CLIMADA is free software: you can redistribute it and/or modify it under the
7+
terms of the GNU Lesser General Public License as published by the Free
8+
Software Foundation, version 3.
9+
10+
CLIMADA is distributed in the hope that it will be useful, but WITHOUT ANY
11+
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
12+
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public License along
15+
with CLIMADA. If not, see <https://www.gnu.org/licenses/>.
16+
17+
---
18+
19+
Test config module.
20+
"""
21+
import unittest
22+
import logging
23+
24+
from climada.util import log_level
25+
26+
class TestUtilInit(unittest.TestCase):
27+
"""Test util __init__ methods"""
28+
29+
def test_log_level_pass(self):
30+
"""Test log level context manager passes"""
31+
#Check loggers are set to level
32+
with self.assertLogs('climada', level='INFO') as cm:
33+
with log_level('WARNING'):
34+
logging.getLogger('climada').info('info')
35+
logging.getLogger('climada').error('error')
36+
self.assertEqual(cm.output, ['ERROR:climada:error'])
37+
#Check if only climada loggers level change
38+
with self.assertLogs('matplotlib', level='DEBUG') as cm:
39+
with log_level('ERROR', name_prefix='climada'):
40+
logging.getLogger('climada').info('info')
41+
logging.getLogger('matplotlib').debug('debug')
42+
self.assertEqual(cm.output, ['DEBUG:matplotlib:debug'])
43+
44+
# Execute Tests
45+
if __name__ == "__main__":
46+
TESTS = unittest.TestLoader().loadTestsFromTestCase(TestUtilInit)
47+
unittest.TextTestRunner(verbosity=2).run(TESTS)

0 commit comments

Comments
 (0)