14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#!/usr/bin/env python 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Copyright 2001-2010 by Vinay Sajip. All Rights Reserved. 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Permission to use, copy, modify, and distribute this software and its 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# documentation for any purpose and without fee is hereby granted, 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# provided that the above copyright notice appear in all copies and that 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# both that copyright notice and this permission notice appear in 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# supporting documentation, and that the name of Vinay Sajip 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# not be used in advertising or publicity pertaining to distribution 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# of the software without specific, written prior permission. 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Test harness for the logging module. Run all tests. 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmCopyright (C) 2001-2010 Vinay Sajip. All Rights Reserved. 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport logging 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport logging.handlers 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport logging.config 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport codecs 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport cPickle 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport cStringIO 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport gc 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport json 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport os 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport re 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport select 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport socket 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom SocketServer import ThreadingTCPServer, StreamRequestHandler 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport struct 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport sys 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport tempfile 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom test.test_support import captured_stdout, run_with_locale, run_unittest 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport textwrap 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport warnings 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport weakref 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import threading 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept ImportError: 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm threading = None 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass BaseTest(unittest.TestCase): 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Base class for logging tests.""" 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log_format = "%(name)s -> %(levelname)s: %(message)s" 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm expected_log_pat = r"^([\w.]+) -> ([\w]+): ([\d]+)$" 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm message_num = 0 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def setUp(self): 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Setup the default logging stream to an internal StringIO instance, 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm so that we can examine log output as we want.""" 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger_dict = logging.getLogger().manager.loggerDict 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._acquireLock() 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.saved_handlers = logging._handlers.copy() 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.saved_handler_list = logging._handlerList[:] 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.saved_loggers = logger_dict.copy() 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.saved_level_names = logging._levelNames.copy() 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._releaseLock() 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Set two unused loggers: one non-ASCII and one Unicode. 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This is to test correct operation when sorting existing 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # loggers in the configuration code. See issue 8201. 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.getLogger("\xab\xd7\xbb") 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.getLogger(u"\u013f\u00d6\u0047") 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger = logging.getLogger("") 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.original_logging_level = self.root_logger.getEffectiveLevel() 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stream = cStringIO.StringIO() 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.setLevel(logging.DEBUG) 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_hdlr = logging.StreamHandler(self.stream) 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_formatter = logging.Formatter(self.log_format) 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_hdlr.setFormatter(self.root_formatter) 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.addHandler(self.root_hdlr) 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def tearDown(self): 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Remove our logging stream, and restore the original logging 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level.""" 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.stream.close() 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.removeHandler(self.root_hdlr) 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while self.root_logger.handlers: 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h = self.root_logger.handlers[0] 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.removeHandler(h) 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h.close() 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.setLevel(self.original_logging_level) 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._acquireLock() 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._levelNames.clear() 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._levelNames.update(self.saved_level_names) 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._handlers.clear() 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._handlers.update(self.saved_handlers) 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._handlerList[:] = self.saved_handler_list 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm loggerDict = logging.getLogger().manager.loggerDict 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm loggerDict.clear() 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm loggerDict.update(self.saved_loggers) 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging._releaseLock() 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def assert_log_lines(self, expected_values, stream=None): 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Match the collected log lines against the regular expression 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.expected_log_pat, and compare the extracted group values to 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the expected_values list of tuples.""" 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stream = stream or self.stream 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pat = re.compile(self.expected_log_pat) 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stream.reset() 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm actual_lines = stream.readlines() 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except AttributeError: 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # StringIO.StringIO lacks a reset() method. 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm actual_lines = stream.getvalue().splitlines() 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(len(actual_lines), len(expected_values)) 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for actual, expected in zip(actual_lines, expected_values): 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm match = pat.search(actual) 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if not match: 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fail("Log line does not match expected pattern:\n" + 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm actual) 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(tuple(match.groups()), expected) 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = stream.read() 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if s: 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fail("Remaining output at end of log stream:\n" + s) 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def next_message(self): 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Generate a message consisting solely of an auto-incrementing 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm integer.""" 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.message_num += 1 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return "%d" % self.message_num 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass BuiltinLevelsTest(BaseTest): 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Test builtin levels and their inheritance.""" 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_flat(self): 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Logging levels in a flat logger namespace. 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = self.next_message 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERR = logging.getLogger("ERR") 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERR.setLevel(logging.ERROR) 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF = logging.getLogger("INF") 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.setLevel(logging.INFO) 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DEB = logging.getLogger("DEB") 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DEB.setLevel(logging.DEBUG) 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # These should log. 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERR.log(logging.CRITICAL, m()) 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERR.error(m()) 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.log(logging.CRITICAL, m()) 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.error(m()) 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.warn(m()) 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.info(m()) 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DEB.log(logging.CRITICAL, m()) 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DEB.error(m()) 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DEB.warn (m()) 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DEB.info (m()) 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm DEB.debug(m()) 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # These should not log. 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERR.warn(m()) 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERR.info(m()) 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ERR.debug(m()) 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.debug(m()) 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERR', 'CRITICAL', '1'), 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERR', 'ERROR', '2'), 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF', 'CRITICAL', '3'), 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF', 'ERROR', '4'), 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF', 'WARNING', '5'), 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF', 'INFO', '6'), 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('DEB', 'CRITICAL', '7'), 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('DEB', 'ERROR', '8'), 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('DEB', 'WARNING', '9'), 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('DEB', 'INFO', '10'), 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('DEB', 'DEBUG', '11'), 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_nested_explicit(self): 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Logging levels in a nested namespace, all explicitly set. 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = self.next_message 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF = logging.getLogger("INF") 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.setLevel(logging.INFO) 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR = logging.getLogger("INF.ERR") 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR.setLevel(logging.ERROR) 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # These should log. 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR.log(logging.CRITICAL, m()) 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR.error(m()) 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # These should not log. 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR.warn(m()) 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR.info(m()) 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR.debug(m()) 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.ERR', 'CRITICAL', '1'), 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.ERR', 'ERROR', '2'), 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_nested_inherited(self): 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Logging levels in a nested namespace, inherited from parent loggers. 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = self.next_message 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF = logging.getLogger("INF") 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.setLevel(logging.INFO) 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR = logging.getLogger("INF.ERR") 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR.setLevel(logging.ERROR) 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_UNDEF = logging.getLogger("INF.UNDEF") 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF") 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm UNDEF = logging.getLogger("UNDEF") 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # These should log. 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_UNDEF.log(logging.CRITICAL, m()) 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_UNDEF.error(m()) 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_UNDEF.warn(m()) 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_UNDEF.info(m()) 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR_UNDEF.log(logging.CRITICAL, m()) 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR_UNDEF.error(m()) 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # These should not log. 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_UNDEF.debug(m()) 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR_UNDEF.warn(m()) 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR_UNDEF.info(m()) 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF_ERR_UNDEF.debug(m()) 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.UNDEF', 'CRITICAL', '1'), 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.UNDEF', 'ERROR', '2'), 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.UNDEF', 'WARNING', '3'), 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.UNDEF', 'INFO', '4'), 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.ERR.UNDEF', 'CRITICAL', '5'), 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.ERR.UNDEF', 'ERROR', '6'), 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_nested_with_virtual_parent(self): 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Logging levels when some parent does not exist yet. 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm m = self.next_message 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF = logging.getLogger("INF") 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF") 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHILD = logging.getLogger("INF.BADPARENT") 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm INF.setLevel(logging.INFO) 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # These should log. 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm GRANDCHILD.log(logging.FATAL, m()) 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm GRANDCHILD.info(m()) 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHILD.log(logging.FATAL, m()) 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHILD.info(m()) 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # These should not log. 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm GRANDCHILD.debug(m()) 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHILD.debug(m()) 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.BADPARENT.UNDEF', 'CRITICAL', '1'), 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.BADPARENT.UNDEF', 'INFO', '2'), 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.BADPARENT', 'CRITICAL', '3'), 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INF.BADPARENT', 'INFO', '4'), 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass BasicFilterTest(BaseTest): 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Test the bundled Filter class.""" 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_filter(self): 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Only messages satisfying the specified criteria pass through the 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # filter. 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm filter_ = logging.Filter("spam.eggs") 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler = self.root_logger.handlers[0] 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler.addFilter(filter_) 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm spam = logging.getLogger("spam") 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm spam_eggs = logging.getLogger("spam.eggs") 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm spam_eggs_fish = logging.getLogger("spam.eggs.fish") 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm spam_bakedbeans = logging.getLogger("spam.bakedbeans") 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm spam.info(self.next_message()) 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm spam_eggs.info(self.next_message()) # Good. 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm spam_eggs_fish.info(self.next_message()) # Good. 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm spam_bakedbeans.info(self.next_message()) 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('spam.eggs', 'INFO', '2'), 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('spam.eggs.fish', 'INFO', '3'), 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler.removeFilter(filter_) 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# First, we define our levels. There can be as many as you want - the only 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# limitations are that they should be integers, the lowest should be > 0 and 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# larger values mean less information being logged. If you need specific 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# level values which do not fit into these limitations, you can use a 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# mapping dictionary to convert between your application levels and the 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# logging system. 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSILENT = 120 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTACITURN = 119 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTERSE = 118 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmEFFUSIVE = 117 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSOCIABLE = 116 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmVERBOSE = 115 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTALKATIVE = 114 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmGARRULOUS = 113 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmCHATTERBOX = 112 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmBORING = 111 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmLEVEL_RANGE = range(BORING, SILENT + 1) 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Next, we define names for our levels. You don't need to do this - in which 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# case the system will use "Level n" to denote the text for the level. 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmy_logging_levels = { 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm SILENT : 'Silent', 3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm TACITURN : 'Taciturn', 3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm TERSE : 'Terse', 3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm EFFUSIVE : 'Effusive', 3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm SOCIABLE : 'Sociable', 3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm VERBOSE : 'Verbose', 3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm TALKATIVE : 'Talkative', 3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm GARRULOUS : 'Garrulous', 3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CHATTERBOX : 'Chatterbox', 3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm BORING : 'Boring', 3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass GarrulousFilter(logging.Filter): 3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """A filter which blocks garrulous messages.""" 3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def filter(self, record): 3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return record.levelno != GARRULOUS 3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass VerySpecificFilter(logging.Filter): 3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """A filter which blocks sociable and taciturn messages.""" 3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def filter(self, record): 3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return record.levelno not in [SOCIABLE, TACITURN] 3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass CustomLevelsAndFiltersTest(BaseTest): 3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Test various filtering possibilities with custom logging levels.""" 3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Skip the logger name group. 3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm expected_log_pat = r"^[\w.]+ -> ([\w]+): ([\d]+)$" 3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def setUp(self): 3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm BaseTest.setUp(self) 3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for k, v in my_logging_levels.items(): 3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.addLevelName(k, v) 3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def log_at_all_levels(self, logger): 3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for lvl in LEVEL_RANGE: 3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.log(lvl, self.next_message()) 3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_logger_filter(self): 3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Filter at logger level. 3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.setLevel(VERBOSE) 3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Levels >= 'Verbose' are good. 3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.log_at_all_levels(self.root_logger) 3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Verbose', '5'), 3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Sociable', '6'), 3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Effusive', '7'), 3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Terse', '8'), 3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Taciturn', '9'), 3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Silent', '10'), 3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_handler_filter(self): 3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Filter at handler level. 3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.handlers[0].setLevel(SOCIABLE) 3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Levels >= 'Sociable' are good. 3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.log_at_all_levels(self.root_logger) 3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Sociable', '6'), 3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Effusive', '7'), 3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Terse', '8'), 3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Taciturn', '9'), 3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Silent', '10'), 4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.handlers[0].setLevel(logging.NOTSET) 4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_specific_filters(self): 4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Set a specific filter object on the handler, and then add another 4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # filter object on the logger itself. 4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler = self.root_logger.handlers[0] 4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm specific_filter = None 4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm garr = GarrulousFilter() 4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler.addFilter(garr) 4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.log_at_all_levels(self.root_logger) 4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm first_lines = [ 4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Notice how 'Garrulous' is missing 4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Boring', '1'), 4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Chatterbox', '2'), 4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Talkative', '4'), 4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Verbose', '5'), 4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Sociable', '6'), 4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Effusive', '7'), 4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Terse', '8'), 4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Taciturn', '9'), 4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Silent', '10'), 4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ] 4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines(first_lines) 4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm specific_filter = VerySpecificFilter() 4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.addFilter(specific_filter) 4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.log_at_all_levels(self.root_logger) 4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines(first_lines + [ 4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Not only 'Garrulous' is still missing, but also 'Sociable' 4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # and 'Taciturn' 4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Boring', '11'), 4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Chatterbox', '12'), 4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Talkative', '14'), 4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Verbose', '15'), 4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Effusive', '17'), 4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Terse', '18'), 4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('Silent', '20'), 4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if specific_filter: 4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.removeFilter(specific_filter) 4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler.removeFilter(garr) 4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass MemoryHandlerTest(BaseTest): 4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Tests for the MemoryHandler.""" 4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Do not bother with a logger name group. 4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm expected_log_pat = r"^[\w.]+ -> ([\w]+): ([\d]+)$" 4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def setUp(self): 4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm BaseTest.setUp(self) 4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_hdlr = logging.handlers.MemoryHandler(10, logging.WARNING, 4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_hdlr) 4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger = logging.getLogger('mem') 4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger.propagate = 0 4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger.addHandler(self.mem_hdlr) 4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def tearDown(self): 4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_hdlr.close() 4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm BaseTest.tearDown(self) 4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_flush(self): 4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The memory handler flushes to its target handler based on specific 4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # criteria (message count and message level). 4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger.debug(self.next_message()) 4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger.info(self.next_message()) 4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This will flush because the level is >= logging.WARNING 4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger.warn(self.next_message()) 4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lines = [ 4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('DEBUG', '1'), 4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '2'), 4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('WARNING', '3'), 4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ] 4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines(lines) 4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for n in (4, 14): 4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i in range(9): 4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger.debug(self.next_message()) 4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines(lines) 4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # This will flush because it's the 10th message since the last 4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # flush. 4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger.debug(self.next_message()) 4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm lines = lines + [('DEBUG', str(i)) for i in range(n, n + 10)] 4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines(lines) 4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.mem_logger.debug(self.next_message()) 4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines(lines) 4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass ExceptionFormatter(logging.Formatter): 4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """A special exception formatter.""" 4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def formatException(self, ei): 4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return "Got a [%s]" % ei[0].__name__ 4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass ConfigFileTest(BaseTest): 5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Reading logging config from a .ini-style config file.""" 5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm expected_log_pat = r"^([\w]+) \+\+ ([\w]+)$" 5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config0 is a standard configuration. 5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config0 = """ 5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [loggers] 5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=root 5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handlers] 5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=hand1 5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatters] 5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=form1 5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_root] 5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=WARNING 5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers=hand1 5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handler_hand1] 5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class=StreamHandler 5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=NOTSET 5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm formatter=form1 5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args=(sys.stdout,) 5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatter_form1] 5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm format=%(levelname)s ++ %(message)s 5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datefmt= 5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config1 adds a little to the standard configuration. 5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config1 = """ 5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [loggers] 5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=root,parser 5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handlers] 5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=hand1 5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatters] 5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=form1 5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_root] 5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=WARNING 5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers= 5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_parser] 5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=DEBUG 5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers=hand1 5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm propagate=1 5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm qualname=compiler.parser 5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handler_hand1] 5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class=StreamHandler 5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=NOTSET 5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm formatter=form1 5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args=(sys.stdout,) 5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatter_form1] 5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm format=%(levelname)s ++ %(message)s 5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datefmt= 5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config1a moves the handler to the root. 5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config1a = """ 5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [loggers] 5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=root,parser 5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handlers] 5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=hand1 5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatters] 5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=form1 5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_root] 5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=WARNING 5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers=hand1 5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_parser] 5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=DEBUG 5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers= 5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm propagate=1 5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm qualname=compiler.parser 5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handler_hand1] 5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class=StreamHandler 5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=NOTSET 5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm formatter=form1 5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args=(sys.stdout,) 5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatter_form1] 5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm format=%(levelname)s ++ %(message)s 5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datefmt= 5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config2 has a subtle configuration error that should be reported 5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config2 = config1.replace("sys.stdout", "sys.stbout") 5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config3 has a less subtle configuration error 6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config3 = config1.replace("formatter=form1", "formatter=misspelled_name") 6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config4 specifies a custom formatter class to be loaded 6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config4 = """ 6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [loggers] 6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=root 6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handlers] 6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=hand1 6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatters] 6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=form1 6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_root] 6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=NOTSET 6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers=hand1 6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handler_hand1] 6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class=StreamHandler 6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=NOTSET 6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm formatter=form1 6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args=(sys.stdout,) 6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatter_form1] 6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class=""" + __name__ + """.ExceptionFormatter 6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm format=%(levelname)s:%(name)s:%(message)s 6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datefmt= 6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config5 specifies a custom handler class to be loaded 6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config5 = config1.replace('class=StreamHandler', 'class=logging.StreamHandler') 6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config6 uses ', ' delimiters in the handlers and formatters sections 6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config6 = """ 6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [loggers] 6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=root,parser 6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handlers] 6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=hand1, hand2 6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatters] 6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=form1, form2 6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_root] 6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=WARNING 6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers= 6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_parser] 6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=DEBUG 6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers=hand1 6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm propagate=1 6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm qualname=compiler.parser 6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handler_hand1] 6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class=StreamHandler 6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=NOTSET 6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm formatter=form1 6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args=(sys.stdout,) 6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handler_hand2] 6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class=StreamHandler 6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=NOTSET 6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm formatter=form1 6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args=(sys.stderr,) 6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatter_form1] 6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm format=%(levelname)s ++ %(message)s 6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datefmt= 6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatter_form2] 6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm format=%(message)s 6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datefmt= 6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config7 adds a compiler logger. 6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config7 = """ 6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [loggers] 6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=root,parser,compiler 6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handlers] 6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=hand1 6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatters] 6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keys=form1 6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_root] 6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=WARNING 6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers=hand1 6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_compiler] 6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=DEBUG 6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers= 6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm propagate=1 6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm qualname=compiler 6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [logger_parser] 6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=DEBUG 6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handlers= 6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm propagate=1 7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm qualname=compiler.parser 7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [handler_hand1] 7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class=StreamHandler 7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm level=NOTSET 7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm formatter=form1 7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args=(sys.stdout,) 7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm [formatter_form1] 7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm format=%(levelname)s ++ %(message)s 7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm datefmt= 7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def apply_config(self, conf): 7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = cStringIO.StringIO(textwrap.dedent(conf)) 7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.config.fileConfig(file) 7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config0_ok(self): 7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A simple config file which overrides the default settings. 7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config0) 7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger() 7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Won't output anything 7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Outputs a message 7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '2'), 7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config1_ok(self, config=config1): 7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A config file defining a sub-parser as well. 7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(config) 7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '1'), 7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '2'), 7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config2_failure(self): 7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A simple config file which overrides the default settings. 7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config2) 7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config3_failure(self): 7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A simple config file which overrides the default settings. 7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config3) 7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config4_ok(self): 7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A config file specifying a custom formatter class. 7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config4) 7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger() 7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError() 7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except RuntimeError: 7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.exception("just testing") 7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout.seek(0) 7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(output.getvalue(), 7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "ERROR:root:just testing\nGot a [RuntimeError]\n") 7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty 7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 7694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config5_ok(self): 7714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.test_config1_ok(config=self.config5) 7724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config6_ok(self): 7744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.test_config1_ok(config=self.config6) 7754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 7764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config7_ok(self): 7774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 7784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config1a) 7794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 7804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # See issue #11424. compiler-hyphenated sorts 7814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # between compiler and compiler.xyz and this 7824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # was preventing compiler.xyz from being included 7834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # in the child loggers of compiler because of an 7844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # overzealous loop termination condition. 7854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm hyphenated = logging.getLogger('compiler-hyphenated') 7864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # All will output a message 7874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 7884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 7894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm hyphenated.critical(self.next_message()) 7904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 7914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '1'), 7924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '2'), 7934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('CRITICAL', '3'), 7944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 7954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 7964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 7974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 7984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config7) 7994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 8004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertFalse(logger.disabled) 8014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 8024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 8034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 8044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.lexer") 8054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 8064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 8074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 8084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Will not appear 8094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm hyphenated.critical(self.next_message()) 8104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 8114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '4'), 8124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '5'), 8134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '6'), 8144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '7'), 8154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 8164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 8174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 8184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass LogRecordStreamHandler(StreamRequestHandler): 8204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Handler for a streaming logging request. It saves the log message in the 8224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm TCP server's 'log_output' attribute.""" 8234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm TCP_LOG_END = "!!!END!!!" 8254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def handle(self): 8274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Handle multiple requests - each expected to be of 4-byte length, 8284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm followed by the LogRecord in pickle format. Logs the record 8294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm according to whatever policy is configured locally.""" 8304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while True: 8314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunk = self.connection.recv(4) 8324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if len(chunk) < 4: 8334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break 8344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm slen = struct.unpack(">L", chunk)[0] 8354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunk = self.connection.recv(slen) 8364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while len(chunk) < slen: 8374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm chunk = chunk + self.connection.recv(slen - len(chunk)) 8384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm obj = self.unpickle(chunk) 8394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm record = logging.makeLogRecord(obj) 8404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.handle_log_record(record) 8414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def unpickle(self, data): 8434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return cPickle.loads(data) 8444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def handle_log_record(self, record): 8464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # If the end-of-messages sentinel is seen, tell the server to 8474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # terminate. 8484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if self.TCP_LOG_END in record.msg: 8494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.server.abort = 1 8504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 8514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.server.log_output += record.msg + "\n" 8524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass LogRecordSocketReceiver(ThreadingTCPServer): 8554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """A simple-minded TCP socket-based logging receiver suitable for test 8574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm purposes.""" 8584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm allow_reuse_address = 1 8604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log_output = "" 8614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, host='localhost', 8634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm port=logging.handlers.DEFAULT_TCP_LOGGING_PORT, 8644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler=LogRecordStreamHandler): 8654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ThreadingTCPServer.__init__(self, (host, port), handler) 8664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.abort = False 8674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.timeout = 0.1 8684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.finished = threading.Event() 8694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def serve_until_stopped(self): 8714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while not self.abort: 8724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rd, wr, ex = select.select([self.socket.fileno()], [], [], 8734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.timeout) 8744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if rd: 8754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.handle_request() 8764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Notify the main thread that we're about to exit 8774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.finished.set() 8784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # close the listen socket 8794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.server_close() 8804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm@unittest.skipUnless(threading, 'Threading required for this test.') 8834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass SocketHandlerTest(BaseTest): 8844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Test for SocketHandler objects.""" 8864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def setUp(self): 8884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Set up a TCP server to receive log messages, and a SocketHandler 8894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pointing to that server's address and port.""" 8904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm BaseTest.setUp(self) 8914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.tcpserver = LogRecordSocketReceiver(port=0) 8924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.port = self.tcpserver.socket.getsockname()[1] 8934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.threads = [ 8944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm threading.Thread(target=self.tcpserver.serve_until_stopped)] 8954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for thread in self.threads: 8964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm thread.start() 8974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 8984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.sock_hdlr = logging.handlers.SocketHandler('localhost', self.port) 8994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.sock_hdlr.setFormatter(self.root_formatter) 9004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.removeHandler(self.root_logger.handlers[0]) 9014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.addHandler(self.sock_hdlr) 9024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def tearDown(self): 9044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Shutdown the TCP server.""" 9054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 9064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.tcpserver.abort = True 9074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del self.tcpserver 9084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.removeHandler(self.sock_hdlr) 9094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.sock_hdlr.close() 9104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for thread in self.threads: 9114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm thread.join(2.0) 9124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 9134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm BaseTest.tearDown(self) 9144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def get_output(self): 9164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Get the log output as received by the TCP server.""" 9174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Signal the TCP receiver and wait for it to terminate. 9184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.critical(LogRecordStreamHandler.TCP_LOG_END) 9194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.tcpserver.finished.wait(2.0) 9204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return self.tcpserver.log_output 9214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_output(self): 9234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # The log message sent to the SocketHandler is properly received. 9244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("tcp") 9254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error("spam") 9264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.debug("eggs") 9274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(self.get_output(), "spam\neggs\n") 9284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass MemoryTest(BaseTest): 9314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Test memory persistence of logger objects.""" 9334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def setUp(self): 9354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Create a dict to remember potentially destroyed objects.""" 9364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm BaseTest.setUp(self) 9374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._survivors = {} 9384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _watch_for_survival(self, *args): 9404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Watch the given objects for survival, by creating weakrefs to 9414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm them.""" 9424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for obj in args: 9434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm key = id(obj), repr(obj) 9444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._survivors[key] = weakref.ref(obj) 9454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _assertTruesurvival(self): 9474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Assert that all objects watched for survival have survived.""" 9484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Trigger cycle breaking. 9494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm gc.collect() 9504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dead = [] 9514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (id_, repr_), ref in self._survivors.items(): 9524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if ref() is None: 9534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dead.append(repr_) 9544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if dead: 9554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fail("%d objects should have survived " 9564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "but have been destroyed: %s" % (len(dead), ", ".join(dead))) 9574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_persistent_loggers(self): 9594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Logger objects are persistent and retain their configuration, even 9604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # if visible references are destroyed. 9614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.setLevel(logging.INFO) 9624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm foo = logging.getLogger("foo") 9634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._watch_for_survival(foo) 9644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm foo.setLevel(logging.DEBUG) 9654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.root_logger.debug(self.next_message()) 9664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm foo.debug(self.next_message()) 9674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 9684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('foo', 'DEBUG', '2'), 9694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 9704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm del foo 9714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # foo has survived. 9724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self._assertTruesurvival() 9734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # foo has retained its settings. 9744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm bar = logging.getLogger("foo") 9754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm bar.debug(self.next_message()) 9764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 9774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('foo', 'DEBUG', '2'), 9784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('foo', 'DEBUG', '3'), 9794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ]) 9804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 9824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass EncodingTest(BaseTest): 9834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_encoding_plain_file(self): 9844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # In Python 2.x, a plain file object is treated as having no encoding. 9854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log = logging.getLogger("test") 9864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm fn = tempfile.mktemp(".log") 9874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # the non-ascii data we write to the log. 9884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm data = "foo\x80" 9894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 9904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler = logging.FileHandler(fn) 9914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log.addHandler(handler) 9924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 9934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # write non-ascii data to the log. 9944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log.warning(data) 9954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 9964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log.removeHandler(handler) 9974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler.close() 9984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # check we wrote exactly those bytes, ignoring trailing \n etc 9994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f = open(fn) 10004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 10014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(f.read().rstrip(), data) 10024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 10034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm f.close() 10044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 10054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if os.path.isfile(fn): 10064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm os.remove(fn) 10074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_encoding_cyrillic_unicode(self): 10094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log = logging.getLogger("test") 10104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Get a message in Unicode: Do svidanya in Cyrillic (meaning goodbye) 10114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm message = u'\u0434\u043e \u0441\u0432\u0438\u0434\u0430\u043d\u0438\u044f' 10124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Ensure it's written in a Cyrillic encoding 10134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm writer_class = codecs.getwriter('cp1251') 10144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm writer_class.encoding = 'cp1251' 10154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm stream = cStringIO.StringIO() 10164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm writer = writer_class(stream, 'strict') 10174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler = logging.StreamHandler(writer) 10184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log.addHandler(handler) 10194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 10204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log.warning(message) 10214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 10224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm log.removeHandler(handler) 10234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm handler.close() 10244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # check we wrote exactly those bytes, ignoring trailing \n etc 10254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = stream.getvalue() 10264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Compare against what the data should be when encoded in CP-1251 10274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(s, '\xe4\xee \xf1\xe2\xe8\xe4\xe0\xed\xe8\xff\n') 10284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass WarningsTest(BaseTest): 10314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_warnings(self): 10334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with warnings.catch_warnings(): 10344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.captureWarnings(True) 10354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 10364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm warnings.filterwarnings("always", category=UserWarning) 10374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = cStringIO.StringIO() 10384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h = logging.StreamHandler(file) 10394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("py.warnings") 10404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.addHandler(h) 10414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm warnings.warn("I'm warning you...") 10424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.removeHandler(h) 10434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = file.getvalue() 10444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm h.close() 10454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(s.find("UserWarning: I'm warning you...\n") > 0) 10464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #See if an explicit file uses the original implementation 10484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = cStringIO.StringIO() 10494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm warnings.showwarning("Explicit", UserWarning, "dummy.py", 42, 10504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file, "Dummy line") 10514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = file.getvalue() 10524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file.close() 10534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(s, 10544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "dummy.py:42: UserWarning: Explicit\n Dummy line\n") 10554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 10564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.captureWarnings(False) 10574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef formatFunc(format, datefmt=None): 10604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return logging.Formatter(format, datefmt) 10614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef handlerFunc(): 10634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return logging.StreamHandler() 10644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass CustomHandler(logging.StreamHandler): 10664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 10674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass ConfigDictTest(BaseTest): 10694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Reading logging config from a dictionary.""" 10714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm expected_log_pat = r"^([\w]+) \+\+ ([\w]+)$" 10734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config0 is a standard configuration. 10754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config0 = { 10764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 10774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 10784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 10794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 10804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 10814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 10824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 10834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 10844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 10854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 10864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 10874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 10884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 10894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 10904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 10914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 10924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 10934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 10944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 10954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 10964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config1 adds a little to the standard configuration. 10974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config1 = { 10984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 10994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 11004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 11014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 11024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 11054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 11064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 11074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 11084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 11094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 11104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 11134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 11144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 11154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 11164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 11194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 11204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 11224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config2 has a subtle configuration error that should be reported 11244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config2 = { 11254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 11264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 11274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 11284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 11294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 11324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 11334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 11344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 11354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 11364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdbout', 11374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 11404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 11414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 11424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 11434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 11464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 11474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 11494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #As config1 but with a misspelt level on a handler 11514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config2a = { 11524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 11534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 11544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 11554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 11564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 11594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 11604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 11614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 11624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NTOSET', 11634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 11644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 11674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 11684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 11694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 11704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 11734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 11744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 11764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 11784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #As config1 but with a misspelt level on a logger 11794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config2b = { 11804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 11814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 11824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 11834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 11844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 11874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 11884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 11894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 11904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 11914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 11924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 11954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 11964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 11974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 11984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 11994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 12014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WRANING', 12024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config3 has a less subtle configuration error 12064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config3 = { 12074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 12084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 12094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 12104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 12114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 12144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 12154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 12164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'misspelled_name', 12174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 12184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 12194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 12224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 12234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 12244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 12254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 12284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 12294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config4 specifies a custom formatter class to be loaded 12334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config4 = { 12344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 12354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 12364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 12374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '()' : __name__ + '.ExceptionFormatter', 12384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s:%(name)s:%(message)s', 12394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 12424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 12434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 12444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 12454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 12464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 12474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 12504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 12514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 12524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # As config4 but using an actual callable rather than a string 12564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config4a = { 12574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 12584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 12594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 12604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '()' : ExceptionFormatter, 12614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s:%(name)s:%(message)s', 12624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form2' : { 12644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '()' : __name__ + '.formatFunc', 12654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s:%(name)s:%(message)s', 12664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form3' : { 12684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '()' : formatFunc, 12694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s:%(name)s:%(message)s', 12704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 12734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 12744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 12754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 12764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 12774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 12784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand2' : { 12804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '()' : handlerFunc, 12814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 12844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 12854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 12864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 12884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 12894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config5 specifies a custom handler class to be loaded 12904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config5 = { 12914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 12924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 12934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 12944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 12954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 12974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 12984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 12994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : __name__ + '.CustomHandler', 13004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 13014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 13024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 13034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 13064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 13074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 13084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 13094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 13124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 13134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # config6 specifies a custom handler class to be loaded 13174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # but has bad arguments 13184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config6 = { 13194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 13204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 13214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 13224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 13234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 13264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 13274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : __name__ + '.CustomHandler', 13284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 13294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 13304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 13314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm '9' : 'invalid parameter name', 13324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 13354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 13364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 13374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 13384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 13414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 13424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #config 7 does not define compiler.parser but defines compiler.lexer 13464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #so compiler.parser should be disabled after applying it 13474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config7 = { 13484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 13494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 13504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 13514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 13524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 13554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 13564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 13574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 13584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 13594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 13604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 13634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.lexer' : { 13644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 13654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 13664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 13694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 13704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 13724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 13734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config8 = { 13744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 13754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'disable_existing_loggers' : False, 13764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 13774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 13784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 13794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 13824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 13834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 13844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 13854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 13864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 13874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 13904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler' : { 13914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 13924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 13934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.lexer' : { 13954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 13974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 13984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 13994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config9 = { 14034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 14044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 14054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 14064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 14074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 14104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 14114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 14124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 14134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 14144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 14154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 14184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 14194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 14204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 14214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 14244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 14254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config9a = { 14294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 14304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'incremental' : True, 14314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 14324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 14334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 14344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 14374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 14384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'INFO', 14394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config9b = { 14444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 14454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'incremental' : True, 14464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 14474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 14484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'INFO', 14494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 14524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 14534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'INFO', 14544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #As config1 but with a filter added 14594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config10 = { 14604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 14614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters': { 14624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 14634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 14644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'filters' : { 14674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'filt1' : { 14684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'name' : 'compiler.parser', 14694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 14724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 14734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 14744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 14754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 14764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 14774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'filters' : ['filt1'], 14784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 14814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 14824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 14834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'filters' : ['filt1'], 14844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 14874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 14884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 14894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 14914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 14924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #As config1 but using cfg:// references 14934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config11 = { 14944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 1, 14954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'true_formatters': { 14964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 14974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 14984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 14994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handler_configs': { 15014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 15024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 15034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 15044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 15054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 15064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters' : 'cfg://true_formatters', 15094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 15104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : 'cfg://handler_configs[hand1]', 15114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 15134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 15144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 15154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 15164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 15194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 15204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #As config11 but missing the version key 15244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config12 = { 15254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'true_formatters': { 15264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 15274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 15284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handler_configs': { 15314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 15324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 15334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 15344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 15354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 15364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters' : 'cfg://true_formatters', 15394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 15404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : 'cfg://handler_configs[hand1]', 15414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 15434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 15444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 15454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 15464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 15494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 15504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #As config11 but using an unsupported version 15544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm config13 = { 15554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'version': 2, 15564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'true_formatters': { 15574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'form1' : { 15584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'format' : '%(levelname)s ++ %(message)s', 15594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handler_configs': { 15624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : { 15634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'class' : 'logging.StreamHandler', 15644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatter' : 'form1', 15654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'NOTSET', 15664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'stream' : 'ext://sys.stdout', 15674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'formatters' : 'cfg://true_formatters', 15704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : { 15714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'hand1' : 'cfg://handler_configs[hand1]', 15724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'loggers' : { 15744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'compiler.parser' : { 15754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'DEBUG', 15764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'handlers' : ['hand1'], 15774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'root' : { 15804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 'level' : 'WARNING', 15814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm }, 15824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 15834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def apply_config(self, conf): 15854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.config.dictConfig(conf) 15864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 15874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config0_ok(self): 15884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A simple config which overrides the default settings. 15894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 15904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config0) 15914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger() 15924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Won't output anything 15934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 15944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Outputs a message 15954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 15964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 15974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '2'), 15984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 15994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 16004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 16014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config1_ok(self, config=config1): 16034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A config defining a sub-parser as well. 16044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 16054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(config) 16064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 16074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 16084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 16094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 16104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 16114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '1'), 16124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '2'), 16134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 16144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 16154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 16164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config2_failure(self): 16184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A simple config which overrides the default settings. 16194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config2) 16204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config2a_failure(self): 16224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A simple config which overrides the default settings. 16234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config2a) 16244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config2b_failure(self): 16264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A simple config which overrides the default settings. 16274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config2b) 16284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config3_failure(self): 16304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A simple config which overrides the default settings. 16314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config3) 16324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config4_ok(self): 16344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A config specifying a custom formatter class. 16354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 16364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config4) 16374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #logger = logging.getLogger() 16384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 16394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError() 16404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except RuntimeError: 16414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.exception("just testing") 16424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout.seek(0) 16434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(output.getvalue(), 16444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "ERROR:root:just testing\nGot a [RuntimeError]\n") 16454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty 16464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 16474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config4a_ok(self): 16494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # A config specifying a custom formatter class. 16504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 16514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config4a) 16524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #logger = logging.getLogger() 16534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 16544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise RuntimeError() 16554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except RuntimeError: 16564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.exception("just testing") 16574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sys.stdout.seek(0) 16584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(output.getvalue(), 16594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "ERROR:root:just testing\nGot a [RuntimeError]\n") 16604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty 16614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 16624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config5_ok(self): 16644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.test_config1_ok(config=self.config5) 16654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config6_failure(self): 16674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config6) 16684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config7_ok(self): 16704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 16714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config1) 16724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 16734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 16744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 16754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 16764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 16774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '1'), 16784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '2'), 16794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 16804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 16814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 16824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 16834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config7) 16844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 16854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(logger.disabled) 16864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.lexer") 16874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 16884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 16894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 16904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 16914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '3'), 16924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '4'), 16934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 16944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 16954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 16964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 16974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Same as test_config_7_ok but don't disable old loggers. 16984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config_8_ok(self): 16994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 17004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config1) 17014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 17024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 17034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 17044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 17054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 17064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '1'), 17074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '2'), 17084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 17094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 17104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 17114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 17124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config8) 17134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 17144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertFalse(logger.disabled) 17154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 17164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 17174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 17184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.lexer") 17194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 17204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 17214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 17224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 17234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '3'), 17244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '4'), 17254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '5'), 17264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '6'), 17274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 17284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 17294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 17304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config_9_ok(self): 17324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 17334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config9) 17344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 17354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Nothing will be output since both handler and logger are set to WARNING 17364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 17374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([], stream=output) 17384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config9a) 17394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Nothing will be output since both handler is still set to WARNING 17404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 17414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([], stream=output) 17424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config9b) 17434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Message should now be output 17444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 17454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 17464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '3'), 17474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 17484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config_10_ok(self): 17504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 17514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.apply_config(self.config10) 17524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 17534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.warning(self.next_message()) 17544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger('compiler') 17554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Not output, because filtered 17564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.warning(self.next_message()) 17574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger('compiler.lexer') 17584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Not output, because filtered 17594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.warning(self.next_message()) 17604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser.codegen") 17614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Output, as not filtered 17624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 17634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 17644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('WARNING', '1'), 17654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '4'), 17664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 17674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config11_ok(self): 17694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.test_config1_ok(self.config11) 17704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config12_failure(self): 17724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config12) 17734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_config13_failure(self): 17754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(StandardError, self.apply_config, self.config13) 17764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm @unittest.skipUnless(threading, 'listen() needs threading to work') 17784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def setup_via_listener(self, text): 17794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Ask for a randomly assigned port (by using port 0) 17804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t = logging.config.listen(0) 17814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t.start() 17824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t.ready.wait() 17834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Now get the port allocated 17844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm port = t.port 17854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t.ready.clear() 17864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 17874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 17884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sock.settimeout(2.0) 17894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sock.connect(('localhost', port)) 17904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 17914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm slen = struct.pack('>L', len(text)) 17924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm s = slen + text 17934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sentsofar = 0 17944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm left = len(s) 17954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while left > 0: 17964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sent = sock.send(s[sentsofar:]) 17974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sentsofar += sent 17984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm left -= sent 17994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm sock.close() 18004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm finally: 18014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t.ready.wait(2.0) 18024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.config.stopListening() 18034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t.join(2.0) 18044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_listen_config_10_ok(self): 18064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 18074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.setup_via_listener(json.dumps(self.config10)) 18084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 18094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.warning(self.next_message()) 18104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger('compiler') 18114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Not output, because filtered 18124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.warning(self.next_message()) 18134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger('compiler.lexer') 18144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Not output, because filtered 18154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.warning(self.next_message()) 18164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser.codegen") 18174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm #Output, as not filtered 18184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 18194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 18204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('WARNING', '1'), 18214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '4'), 18224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 18234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_listen_config_1_ok(self): 18254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm with captured_stdout() as output: 18264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.setup_via_listener(textwrap.dedent(ConfigFileTest.config1)) 18274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = logging.getLogger("compiler.parser") 18284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Both will output a message 18294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.info(self.next_message()) 18304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.error(self.next_message()) 18314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([ 18324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('INFO', '1'), 18334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ('ERROR', '2'), 18344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ], stream=output) 18354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # Original logger output is empty. 18364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assert_log_lines([]) 18374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass ManagerTest(BaseTest): 18404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_manager_loggerclass(self): 18414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logged = [] 18424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class MyLogger(logging.Logger): 18444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def _log(self, level, msg, args, exc_info=None, extra=None): 18454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logged.append(msg) 18464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm man = logging.Manager(None) 18484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertRaises(TypeError, man.setLoggerClass, int) 18494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm man.setLoggerClass(MyLogger) 18504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger = man.getLogger('test') 18514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logger.warning('should appear in logged') 18524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm logging.warning('should not appear in logged') 18534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertEqual(logged, ['should appear in logged']) 18554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass ChildLoggerTest(BaseTest): 18584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def test_child_loggers(self): 18594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm r = logging.getLogger() 18604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l1 = logging.getLogger('abc') 18614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l2 = logging.getLogger('def.ghi') 18624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm c1 = r.getChild('xyz') 18634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm c2 = r.getChild('uvw.xyz') 18644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(c1 is logging.getLogger('xyz')) 18654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(c2 is logging.getLogger('uvw.xyz')) 18664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm c1 = l1.getChild('def') 18674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm c2 = c1.getChild('ghi') 18684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm c3 = l1.getChild('def.ghi') 18694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(c1 is logging.getLogger('abc.def')) 18704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(c2 is logging.getLogger('abc.def.ghi')) 18714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.assertTrue(c2 is c3) 18724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Set the locale to the platform-dependent default. I have no idea 18754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# why the test does this, but in any case we save the current locale 18764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# first and restore it at the end. 18774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm@run_with_locale('LC_ALL', '') 18784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_main(): 18794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm run_unittest(BuiltinLevelsTest, BasicFilterTest, 18804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm CustomLevelsAndFiltersTest, MemoryHandlerTest, 18814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ConfigFileTest, SocketHandlerTest, MemoryTest, 18824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm EncodingTest, WarningsTest, ConfigDictTest, ManagerTest, 18834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm ChildLoggerTest) 18844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 18854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__": 18864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm test_main() 1887