Author: gstein
Date: Thu May 3 20:12:52 2012
New Revision: 1333602
URL: http://svn.apache.org/viewvc?rev=1333602&view=rev
Log:
As a followup to some recent logging changes in the tests, write a
custom Formatter in order to have "short" loglevel indicators.
This also takes some care to insert safeguards against code attempting
to use the logging module *before* we have had a chance to configure it.
* subversion/tests/cmdline/svntest/main.py:
(logger): set to None to catch early-usage in this module
(class AbbreviatedFormatter): a Formatter subclass to define a
"levelshort" substitution value for format strings
(execute_tests): set up the LOGGER global, and configure the root
logger after we have parsed the options.
Modified:
subversion/trunk/subversion/tests/cmdline/svntest/main.py
Modified: subversion/trunk/subversion/tests/cmdline/svntest/main.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svntest/main.py?rev=1333602&r1=1333601&r2=1333602&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svntest/main.py Thu May 3
20:12:52 2012
@@ -78,12 +78,8 @@ SVN_VER_MINOR = 8
default_num_threads = 5
-# Set up logging
-logger = logging.getLogger()
-handler = logging.StreamHandler(sys.stdout)
-formatter = logging.Formatter('%(message)s')
-handler.setFormatter(formatter)
-logger.addHandler(handler)
+# Don't try to use this before calling execute_tests()
+logger = None
class SVNProcessTerminatedBySignal(Failure):
@@ -1651,6 +1647,28 @@ def get_target_milestones_for_issues(iss
return issue_dict
+
+class AbbreviatedFormatter(logging.Formatter):
+ """A formatter with abbreviated loglevel indicators in the output.
+
+ Use %(levelshort)s in the format string to get a single character
+ representing the loglevel..
+ """
+
+ _level_short = {
+ logging.CRITICAL : 'C',
+ logging.ERROR : 'E',
+ logging.WARNING : 'W',
+ logging.INFO : 'I',
+ logging.DEBUG : 'D',
+ logging.NOTSET : '-',
+ }
+
+ def format(self, record):
+ record.levelshort = self._level_short[record.levelno]
+ return logging.Formatter.format(self, record)
+
+
# Main func. This is the "entry point" that all the test scripts call
# to run their list of tests.
#
@@ -1661,6 +1679,7 @@ def execute_tests(test_list, serial_only
exiting the process. This function can be used when a caller doesn't
want the process to die."""
+ global logger
global pristine_url
global pristine_greek_repos_url
global svn_binary
@@ -1677,6 +1696,19 @@ def execute_tests(test_list, serial_only
testnums = []
+ # Initialize the LOGGER global variable so the option parsing can set
+ # its loglevel, as appropriate.
+ logger = logging.getLogger()
+
+ # Did some chucklehead log something before we configured it? If they
+ # did, then a default handler/formatter would get installed. We want
+ # to be the one to install the first (and only) handler.
+ for handler in logger.handlers:
+ if not isinstance(handler.formatter, AbbreviatedFormatter):
+ raise Exception('Logging occurred before configuration. Some code'
+ ' path needs to be fixed. Examine the log output'
+ ' to find what/where logged something.')
+
if not options:
# Override which tests to run from the commandline
(parser, args) = _parse_options()
@@ -1684,10 +1716,17 @@ def execute_tests(test_list, serial_only
else:
parser = _create_parser()
+ # Now that we have some options, let's get the logger configured before
+ # doing anything more
if options.log_with_timestamps:
- formatter = logging.Formatter('[%(asctime)s] %(message)s',
- '%Y-%m-%d %H:%M:%S')
- handler.setFormatter(formatter)
+ formatter = AbbreviatedFormatter('%(levelshort)s:'
+ ' [%(asctime)s] %(message)s',
+ datefmt='%Y-%m-%d %H:%M:%S')
+ else:
+ formatter = AbbreviatedFormatter('%(levelshort)s: %(message)s')
+ handler = logging.StreamHandler(sys.stdout)
+ handler.setFormatter(formatter)
+ logger.addHandler(handler)
# parse the positional arguments (test nums, names)
for arg in test_selection: