diff options
author | Christian Heimes <christian@cheimes.de> | 2008-02-17 13:31:39 (GMT) |
---|---|---|
committer | Christian Heimes <christian@cheimes.de> | 2008-02-17 13:31:39 (GMT) |
commit | 18c66898b0a14761786161c07d89d65c8f088601 (patch) | |
tree | d3130f0d046909b261bc96d4ad332db14f260d7e /Lib/test/test_logging.py | |
parent | a156e09b19cd239176a9316ddca7641784eea99e (diff) | |
download | cpython-18c66898b0a14761786161c07d89d65c8f088601.zip cpython-18c66898b0a14761786161c07d89d65c8f088601.tar.gz cpython-18c66898b0a14761786161c07d89d65c8f088601.tar.bz2 |
Merged revisions 60481,60485,60489-60492,60494-60496,60498-60499,60501-60503,60505-60506,60508-60509,60523-60524,60532,60543,60545,60547-60548,60552,60554,60556-60559,60561-60562,60569,60571-60572,60574,60576-60583,60585-60586,60589,60591,60594-60595,60597-60598,60600-60601,60606-60612,60615,60617,60619-60621,60623-60625,60627-60629,60631,60633,60635,60647,60650,60652,60654,60656,60658-60659,60664-60666,60668-60670,60672,60676,60678,60680-60683,60685-60686,60688,60690,60692-60694,60697-60700,60705-60706,60708,60711,60714,60720,60724-60730,60732,60736,60742,60744,60746,60748,60750-60751,60753,60756-60757,60759-60761,60763-60764,60766,60769-60770,60774-60784,60787-60789,60793,60796,60799-60809,60812-60813,60815-60821,60823-60826,60828-60829,60831-60834,60836,60838-60839,60846-60873 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r60850 | amaury.forgeotdarc | 2008-02-16 01:16:50 +0100 (Sat, 16 Feb 2008) | 3 lines
mmap.PROT_READ does not exists on win32;
Skip this test created by r60830.
........
r60851 | raymond.hettinger | 2008-02-16 02:22:54 +0100 (Sat, 16 Feb 2008) | 1 line
Add __all__ to logging module.
........
r60855 | georg.brandl | 2008-02-16 10:37:32 +0100 (Sat, 16 Feb 2008) | 2 lines
#2120: broken links in advocacy document.
........
r60860 | amaury.forgeotdarc | 2008-02-16 15:34:57 +0100 (Sat, 16 Feb 2008) | 23 lines
Crashers of the day: Py_CLEAR must be used when there is a chance that the
function can be called recursively.
This was discussed in issue1020188.
In python codebase, all occurrences of Py_[X]DECREF(xxx->yyy) are suspect,
except when they appear in tp_new or tp_dealloc functions, or when
the member cannot be of a user-defined class.
Note that tp_init is not safe.
I do have a (crashing) example for every changed line.
Is it worth adding them to the test suite?
Example:
class SpecialStr(str):
def __del__(self):
s.close()
import cStringIO
s = cStringIO.StringIO(SpecialStr("text"))
s.close() # Segfault
........
r60871 | amaury.forgeotdarc | 2008-02-16 21:55:24 +0100 (Sat, 16 Feb 2008) | 3 lines
Prevent a crash with nested scopes, again caused by calling Py_DECREF when the pointer
is still present in the containing structure.
........
r60872 | brett.cannon | 2008-02-17 02:59:18 +0100 (Sun, 17 Feb 2008) | 4 lines
Move test_logging over to doctest.
Thanks to Christopher White from GHOP.
........
r60873 | georg.brandl | 2008-02-17 12:33:38 +0100 (Sun, 17 Feb 2008) | 2 lines
#2131: note that codecs.open() always opens files in binary mode.
........
Diffstat (limited to 'Lib/test/test_logging.py')
-rw-r--r-- | Lib/test/test_logging.py | 2452 |
1 files changed, 2006 insertions, 446 deletions
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 127cf84..a31ad37 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1,38 +1,1883 @@ #!/usr/bin/env python -# -# Copyright 2001-2004 by Vinay Sajip. All Rights Reserved. -# -# Permission to use, copy, modify, and distribute this software and its -# documentation for any purpose and without fee is hereby granted, -# provided that the above copyright notice appear in all copies and that -# both that copyright notice and this permission notice appear in -# supporting documentation, and that the name of Vinay Sajip -# not be used in advertising or publicity pertaining to distribution -# of the software without specific, written prior permission. -# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL -# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER -# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT -# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# -# This file is part of the Python logging distribution. See -# http://www.red-dove.com/python_logging.html -# -"""Test harness for the logging module. Run all tests. - -Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved. """ +Test 0 +====== +Some preliminaries: +>>> import sys +>>> import logging +>>> def nextmessage(): +... global msgcount +... rv = "Message %d" % msgcount +... msgcount = msgcount + 1 +... return rv + +Set a few variables, then go through the logger autoconfig and set the default threshold. +>>> msgcount = 0 +>>> FINISH_UP = "Finish up, it's closing time. Messages should bear numbers 0 through 24." +>>> logging.basicConfig(stream=sys.stdout) +>>> rootLogger = logging.getLogger("") +>>> rootLogger.setLevel(logging.DEBUG) + +Now, create a bunch of loggers, and set their thresholds. +>>> ERR = logging.getLogger("ERR0") +>>> ERR.setLevel(logging.ERROR) +>>> INF = logging.getLogger("INFO0") +>>> INF.setLevel(logging.INFO) +>>> INF_ERR = logging.getLogger("INFO0.ERR") +>>> INF_ERR.setLevel(logging.ERROR) +>>> DEB = logging.getLogger("DEB0") +>>> DEB.setLevel(logging.DEBUG) +>>> INF_UNDEF = logging.getLogger("INFO0.UNDEF") +>>> INF_ERR_UNDEF = logging.getLogger("INFO0.ERR.UNDEF") +>>> UNDEF = logging.getLogger("UNDEF0") +>>> GRANDCHILD = logging.getLogger("INFO0.BADPARENT.UNDEF") +>>> CHILD = logging.getLogger("INFO0.BADPARENT") + + +And finally, run all the tests. + +>>> ERR.log(logging.FATAL, nextmessage()) +CRITICAL:ERR0:Message 0 + +>>> ERR.error(nextmessage()) +ERROR:ERR0:Message 1 + +>>> INF.log(logging.FATAL, nextmessage()) +CRITICAL:INFO0:Message 2 + +>>> INF.error(nextmessage()) +ERROR:INFO0:Message 3 + +>>> INF.warn(nextmessage()) +WARNING:INFO0:Message 4 + +>>> INF.info(nextmessage()) +INFO:INFO0:Message 5 + +>>> INF_UNDEF.log(logging.FATAL, nextmessage()) +CRITICAL:INFO0.UNDEF:Message 6 + +>>> INF_UNDEF.error(nextmessage()) +ERROR:INFO0.UNDEF:Message 7 + +>>> INF_UNDEF.warn (nextmessage()) +WARNING:INFO0.UNDEF:Message 8 + +>>> INF_UNDEF.info (nextmessage()) +INFO:INFO0.UNDEF:Message 9 + +>>> INF_ERR.log(logging.FATAL, nextmessage()) +CRITICAL:INFO0.ERR:Message 10 + +>>> INF_ERR.error(nextmessage()) +ERROR:INFO0.ERR:Message 11 + +>>> INF_ERR_UNDEF.log(logging.FATAL, nextmessage()) +CRITICAL:INFO0.ERR.UNDEF:Message 12 + +>>> INF_ERR_UNDEF.error(nextmessage()) +ERROR:INFO0.ERR.UNDEF:Message 13 + +>>> DEB.log(logging.FATAL, nextmessage()) +CRITICAL:DEB0:Message 14 + +>>> DEB.error(nextmessage()) +ERROR:DEB0:Message 15 + +>>> DEB.warn (nextmessage()) +WARNING:DEB0:Message 16 + +>>> DEB.info (nextmessage()) +INFO:DEB0:Message 17 + +>>> DEB.debug(nextmessage()) +DEBUG:DEB0:Message 18 + +>>> UNDEF.log(logging.FATAL, nextmessage()) +CRITICAL:UNDEF0:Message 19 + +>>> UNDEF.error(nextmessage()) +ERROR:UNDEF0:Message 20 + +>>> UNDEF.warn (nextmessage()) +WARNING:UNDEF0:Message 21 + +>>> UNDEF.info (nextmessage()) +INFO:UNDEF0:Message 22 + +>>> GRANDCHILD.log(logging.FATAL, nextmessage()) +CRITICAL:INFO0.BADPARENT.UNDEF:Message 23 + +>>> CHILD.log(logging.FATAL, nextmessage()) +CRITICAL:INFO0.BADPARENT:Message 24 + +These should not log: + +>>> ERR.warn(nextmessage()) + +>>> ERR.info(nextmessage()) + +>>> ERR.debug(nextmessage()) + +>>> INF.debug(nextmessage()) + +>>> INF_UNDEF.debug(nextmessage()) + +>>> INF_ERR.warn(nextmessage()) + +>>> INF_ERR.info(nextmessage()) + +>>> INF_ERR.debug(nextmessage()) + +>>> INF_ERR_UNDEF.warn(nextmessage()) + +>>> INF_ERR_UNDEF.info(nextmessage()) + +>>> INF_ERR_UNDEF.debug(nextmessage()) + +>>> INF.info(FINISH_UP) +INFO:INFO0:Finish up, it's closing time. Messages should bear numbers 0 through 24. + +Test 1 +====== + +>>> import sys, logging +>>> logging.basicConfig(stream=sys.stdout) + +First, we define our levels. There can be as many as you want - the only +limitations are that they should be integers, the lowest should be > 0 and +larger values mean less information being logged. If you need specific +level values which do not fit into these limitations, you can use a +mapping dictionary to convert between your application levels and the +logging system. + +>>> SILENT = 10 +>>> TACITURN = 9 +>>> TERSE = 8 +>>> EFFUSIVE = 7 +>>> SOCIABLE = 6 +>>> VERBOSE = 5 +>>> TALKATIVE = 4 +>>> GARRULOUS = 3 +>>> CHATTERBOX = 2 +>>> BORING = 1 +>>> LEVEL_RANGE = range(BORING, SILENT + 1) + + +Next, we define names for our levels. You don't need to do this - in which + case the system will use "Level n" to denote the text for the level. +' + + +>>> my_logging_levels = { +... SILENT : 'SILENT', +... TACITURN : 'TACITURN', +... TERSE : 'TERSE', +... EFFUSIVE : 'EFFUSIVE', +... SOCIABLE : 'SOCIABLE', +... VERBOSE : 'VERBOSE', +... TALKATIVE : 'TALKATIVE', +... GARRULOUS : 'GARRULOUS', +... CHATTERBOX : 'CHATTERBOX', +... BORING : 'BORING', +... } + + +Now, to demonstrate filtering: suppose for some perverse reason we only +want to print out all except GARRULOUS messages. We create a filter for +this purpose... + +>>> class SpecificLevelFilter(logging.Filter): +... def __init__(self, lvl): +... self.level = lvl +... +... def filter(self, record): +... return self.level != record.levelno + +>>> class GarrulousFilter(SpecificLevelFilter): +... def __init__(self): +... SpecificLevelFilter.__init__(self, GARRULOUS) + + +Now, demonstrate filtering at the logger. This time, use a filter +which excludes SOCIABLE and TACITURN messages. Note that GARRULOUS events +are still excluded. + + +>>> class VerySpecificFilter(logging.Filter): +... def filter(self, record): +... return record.levelno not in [SOCIABLE, TACITURN] + +>>> SHOULD1 = "This should only be seen at the '%s' logging level (or lower)" + +Configure the logger, and tell the logging system to associate names with our levels. +>>> logging.basicConfig(stream=sys.stdout) +>>> rootLogger = logging.getLogger("") +>>> rootLogger.setLevel(logging.DEBUG) +>>> for lvl in my_logging_levels.keys(): +... logging.addLevelName(lvl, my_logging_levels[lvl]) +>>> log = logging.getLogger("") +>>> hdlr = log.handlers[0] +>>> from test.test_logging import message + +Set the logging level to each different value and call the utility +function to log events. In the output, you should see that each time +round the loop, the number of logging events which are actually output +decreases. + +>>> log.setLevel(1) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) +BORING:root:This should only be seen at the '1' logging level (or lower) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) +CHATTERBOX:root:This should only be seen at the '2' logging level (or lower) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) +GARRULOUS:root:This should only be seen at the '3' logging level (or lower) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(2) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) +CHATTERBOX:root:This should only be seen at the '2' logging level (or lower) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) +GARRULOUS:root:This should only be seen at the '3' logging level (or lower) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(3) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) +GARRULOUS:root:This should only be seen at the '3' logging level (or lower) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(4) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(5) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + + +>>> log.setLevel(6) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(7) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(8) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(9) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(10) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> hdlr.setLevel(SOCIABLE) + +>>> log.setLevel(1) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(2) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(3) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(4) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(5) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(6) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(7) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(8) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(9) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(10) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> + +>>> hdlr.setLevel(0) + +>>> garr = GarrulousFilter() + +>>> hdlr.addFilter(garr) + +>>> log.setLevel(1) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) +BORING:root:This should only be seen at the '1' logging level (or lower) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) +CHATTERBOX:root:This should only be seen at the '2' logging level (or lower) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(2) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) +CHATTERBOX:root:This should only be seen at the '2' logging level (or lower) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(3) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(4) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(5) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.setLevel(6) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) +SOCIABLE:root:This should only be seen at the '6' logging level (or lower) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(7) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(8) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(9) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) +TACITURN:root:This should only be seen at the '9' logging level (or lower) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(10) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> spec = VerySpecificFilter() + +>>> log.addFilter(spec) + +>>> log.setLevel(1) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) +BORING:root:This should only be seen at the '1' logging level (or lower) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) +CHATTERBOX:root:This should only be seen at the '2' logging level (or lower) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(2) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) +CHATTERBOX:root:This should only be seen at the '2' logging level (or lower) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(3) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(4) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) +TALKATIVE:root:This should only be seen at the '4' logging level (or lower) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(5) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) +VERBOSE:root:This should only be seen at the '5' logging level (or lower) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(6) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(7) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) +EFFUSIVE:root:This should only be seen at the '7' logging level (or lower) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(8) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) +TERSE:root:This should only be seen at the '8' logging level (or lower) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(9) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(10) + +>>> log.log(1, "This should only be seen at the '%s' logging level (or lower)", BORING) + +>>> log.log(2, "This should only be seen at the '%s' logging level (or lower)", CHATTERBOX) + +>>> log.log(3, "This should only be seen at the '%s' logging level (or lower)", GARRULOUS) + +>>> log.log(4, "This should only be seen at the '%s' logging level (or lower)", TALKATIVE) + +>>> log.log(5, "This should only be seen at the '%s' logging level (or lower)", VERBOSE) + +>>> log.log(6, "This should only be seen at the '%s' logging level (or lower)", SOCIABLE) + +>>> log.log(7, "This should only be seen at the '%s' logging level (or lower)", EFFUSIVE) + +>>> log.log(8, "This should only be seen at the '%s' logging level (or lower)", TERSE) + +>>> log.log(9, "This should only be seen at the '%s' logging level (or lower)", TACITURN) + +>>> log.log(10, "This should only be seen at the '%s' logging level (or lower)", SILENT) +SILENT:root:This should only be seen at the '10' logging level (or lower) + +>>> log.setLevel(0) + +>>> log.removeFilter(spec) + +>>> hdlr.removeFilter(garr) + +>>> logging.addLevelName(logging.DEBUG, "DEBUG") + + +Test 2 +====== +Test memory handlers. These are basically buffers for log messages: they take so many messages, and then print them all. + +>>> import logging.handlers + +>>> sys.stderr = sys.stdout +>>> logger = logging.getLogger("") +>>> sh = logger.handlers[0] +>>> sh.close() +>>> logger.removeHandler(sh) +>>> mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh) +>>> logger.setLevel(logging.DEBUG) +>>> logger.addHandler(mh) + +>>> logger.debug("Debug message") + +-- logging at INFO, nothing should be seen yet -- + +>>> logger.info("Info message") + +-- logging at WARNING, 3 messages should be seen -- + +>>> logger.warn("Warn message") +DEBUG:root:Debug message +INFO:root:Info message +WARNING:root:Warn message + +>>> logger.info("Info index = 0") + +>>> logger.info("Info index = 1") + +>>> logger.info("Info index = 2") + +>>> logger.info("Info index = 3") + +>>> logger.info("Info index = 4") + +>>> logger.info("Info index = 5") + +>>> logger.info("Info index = 6") + +>>> logger.info("Info index = 7") + +>>> logger.info("Info index = 8") + +>>> logger.info("Info index = 9") +INFO:root:Info index = 0 +INFO:root:Info index = 1 +INFO:root:Info index = 2 +INFO:root:Info index = 3 +INFO:root:Info index = 4 +INFO:root:Info index = 5 +INFO:root:Info index = 6 +INFO:root:Info index = 7 +INFO:root:Info index = 8 +INFO:root:Info index = 9 + +>>> logger.info("Info index = 10") + +>>> logger.info("Info index = 11") + +>>> logger.info("Info index = 12") + +>>> logger.info("Info index = 13") + +>>> logger.info("Info index = 14") + +>>> logger.info("Info index = 15") + +>>> logger.info("Info index = 16") + +>>> logger.info("Info index = 17") + +>>> logger.info("Info index = 18") + +>>> logger.info("Info index = 19") +INFO:root:Info index = 10 +INFO:root:Info index = 11 +INFO:root:Info index = 12 +INFO:root:Info index = 13 +INFO:root:Info index = 14 +INFO:root:Info index = 15 +INFO:root:Info index = 16 +INFO:root:Info index = 17 +INFO:root:Info index = 18 +INFO:root:Info index = 19 + +>>> logger.info("Info index = 20") + +>>> logger.info("Info index = 21") + +>>> logger.info("Info index = 22") + +>>> logger.info("Info index = 23") + +>>> logger.info("Info index = 24") + +>>> logger.info("Info index = 25") + +>>> logger.info("Info index = 26") + +>>> logger.info("Info index = 27") + +>>> logger.info("Info index = 28") + +>>> logger.info("Info index = 29") +INFO:root:Info index = 20 +INFO:root:Info index = 21 +INFO:root:Info index = 22 +INFO:root:Info index = 23 +INFO:root:Info index = 24 +INFO:root:Info index = 25 +INFO:root:Info index = 26 +INFO:root:Info index = 27 +INFO:root:Info index = 28 +INFO:root:Info index = 29 + +>>> logger.info("Info index = 30") + +>>> logger.info("Info index = 31") + +>>> logger.info("Info index = 32") + +>>> logger.info("Info index = 33") + +>>> logger.info("Info index = 34") + +>>> logger.info("Info index = 35") + +>>> logger.info("Info index = 36") + +>>> logger.info("Info index = 37") + +>>> logger.info("Info index = 38") + +>>> logger.info("Info index = 39") +INFO:root:Info index = 30 +INFO:root:Info index = 31 +INFO:root:Info index = 32 +INFO:root:Info index = 33 +INFO:root:Info index = 34 +INFO:root:Info index = 35 +INFO:root:Info index = 36 +INFO:root:Info index = 37 +INFO:root:Info index = 38 +INFO:root:Info index = 39 + +>>> logger.info("Info index = 40") + +>>> logger.info("Info index = 41") + +>>> logger.info("Info index = 42") + +>>> logger.info("Info index = 43") + +>>> logger.info("Info index = 44") + +>>> logger.info("Info index = 45") + +>>> logger.info("Info index = 46") + +>>> logger.info("Info index = 47") + +>>> logger.info("Info index = 48") + +>>> logger.info("Info index = 49") +INFO:root:Info index = 40 +INFO:root:Info index = 41 +INFO:root:Info index = 42 +INFO:root:Info index = 43 +INFO:root:Info index = 44 +INFO:root:Info index = 45 +INFO:root:Info index = 46 +INFO:root:Info index = 47 +INFO:root:Info index = 48 +INFO:root:Info index = 49 + +>>> logger.info("Info index = 50") + +>>> logger.info("Info index = 51") + +>>> logger.info("Info index = 52") + +>>> logger.info("Info index = 53") + +>>> logger.info("Info index = 54") + +>>> logger.info("Info index = 55") + +>>> logger.info("Info index = 56") + +>>> logger.info("Info index = 57") + +>>> logger.info("Info index = 58") + +>>> logger.info("Info index = 59") +INFO:root:Info index = 50 +INFO:root:Info index = 51 +INFO:root:Info index = 52 +INFO:root:Info index = 53 +INFO:root:Info index = 54 +INFO:root:Info index = 55 +INFO:root:Info index = 56 +INFO:root:Info index = 57 +INFO:root:Info index = 58 +INFO:root:Info index = 59 + +>>> logger.info("Info index = 60") + +>>> logger.info("Info index = 61") + +>>> logger.info("Info index = 62") + +>>> logger.info("Info index = 63") + +>>> logger.info("Info index = 64") + +>>> logger.info("Info index = 65") + +>>> logger.info("Info index = 66") + +>>> logger.info("Info index = 67") + +>>> logger.info("Info index = 68") + +>>> logger.info("Info index = 69") +INFO:root:Info index = 60 +INFO:root:Info index = 61 +INFO:root:Info index = 62 +INFO:root:Info index = 63 +INFO:root:Info index = 64 +INFO:root:Info index = 65 +INFO:root:Info index = 66 +INFO:root:Info index = 67 +INFO:root:Info index = 68 +INFO:root:Info index = 69 + +>>> logger.info("Info index = 70") + +>>> logger.info("Info index = 71") + +>>> logger.info("Info index = 72") + +>>> logger.info("Info index = 73") + +>>> logger.info("Info index = 74") + +>>> logger.info("Info index = 75") + +>>> logger.info("Info index = 76") + +>>> logger.info("Info index = 77") + +>>> logger.info("Info index = 78") + +>>> logger.info("Info index = 79") +INFO:root:Info index = 70 +INFO:root:Info index = 71 +INFO:root:Info index = 72 +INFO:root:Info index = 73 +INFO:root:Info index = 74 +INFO:root:Info index = 75 +INFO:root:Info index = 76 +INFO:root:Info index = 77 +INFO:root:Info index = 78 +INFO:root:Info index = 79 + +>>> logger.info("Info index = 80") + +>>> logger.info("Info index = 81") + +>>> logger.info("Info index = 82") + +>>> logger.info("Info index = 83") + +>>> logger.info("Info index = 84") + +>>> logger.info("Info index = 85") + +>>> logger.info("Info index = 86") + +>>> logger.info("Info index = 87") + +>>> logger.info("Info index = 88") + +>>> logger.info("Info index = 89") +INFO:root:Info index = 80 +INFO:root:Info index = 81 +INFO:root:Info index = 82 +INFO:root:Info index = 83 +INFO:root:Info index = 84 +INFO:root:Info index = 85 +INFO:root:Info index = 86 +INFO:root:Info index = 87 +INFO:root:Info index = 88 +INFO:root:Info index = 89 + +>>> logger.info("Info index = 90") + +>>> logger.info("Info index = 91") + +>>> logger.info("Info index = 92") + +>>> logger.info("Info index = 93") + +>>> logger.info("Info index = 94") + +>>> logger.info("Info index = 95") + +>>> logger.info("Info index = 96") + +>>> logger.info("Info index = 97") + +>>> logger.info("Info index = 98") + +>>> logger.info("Info index = 99") +INFO:root:Info index = 90 +INFO:root:Info index = 91 +INFO:root:Info index = 92 +INFO:root:Info index = 93 +INFO:root:Info index = 94 +INFO:root:Info index = 95 +INFO:root:Info index = 96 +INFO:root:Info index = 97 +INFO:root:Info index = 98 +INFO:root:Info index = 99 + +>>> logger.info("Info index = 100") + +>>> logger.info("Info index = 101") + +>>> mh.close() +INFO:root:Info index = 100 +INFO:root:Info index = 101 + +>>> logger.removeHandler(mh) +>>> logger.addHandler(sh) + + + +Test 3 +====== + +>>> import sys, logging +>>> sys.stderr = sys +>>> logging.basicConfig() +>>> FILTER = "a.b" +>>> root = logging.getLogger() +>>> root.setLevel(logging.DEBUG) +>>> hand = root.handlers[0] + +>>> logging.getLogger("a").info("Info 1") +INFO:a:Info 1 + +>>> logging.getLogger("a.b").info("Info 2") +INFO:a.b:Info 2 + +>>> logging.getLogger("a.c").info("Info 3") +INFO:a.c:Info 3 + +>>> logging.getLogger("a.b.c").info("Info 4") +INFO:a.b.c:Info 4 + +>>> logging.getLogger("a.b.c.d").info("Info 5") +INFO:a.b.c.d:Info 5 + +>>> logging.getLogger("a.bb.c").info("Info 6") +INFO:a.bb.c:Info 6 + +>>> logging.getLogger("b").info("Info 7") +INFO:b:Info 7 + +>>> logging.getLogger("b.a").info("Info 8") +INFO:b.a:Info 8 + +>>> logging.getLogger("c.a.b").info("Info 9") +INFO:c.a.b:Info 9 + +>>> logging.getLogger("a.bb").info("Info 10") +INFO:a.bb:Info 10 + +Filtered with 'a.b'... + +>>> filt = logging.Filter(FILTER) + +>>> hand.addFilter(filt) + +>>> logging.getLogger("a").info("Info 1") + +>>> logging.getLogger("a.b").info("Info 2") +INFO:a.b:Info 2 + +>>> logging.getLogger("a.c").info("Info 3") + +>>> logging.getLogger("a.b.c").info("Info 4") +INFO:a.b.c:Info 4 + +>>> logging.getLogger("a.b.c.d").info("Info 5") +INFO:a.b.c.d:Info 5 + +>>> logging.getLogger("a.bb.c").info("Info 6") + +>>> logging.getLogger("b").info("Info 7") + +>>> logging.getLogger("b.a").info("Info 8") + +>>> logging.getLogger("c.a.b").info("Info 9") + +>>> logging.getLogger("a.bb").info("Info 10") + +>>> hand.removeFilter(filt) + + +Test 4 +====== +>>> import sys, logging, logging.handlers, string +>>> import tempfile, logging.config, os, test.test_support +>>> sys.stderr = sys.stdout + +>>> from test.test_logging import config0, config1 + +config2 has a subtle configuration error that should be reported +>>> config2 = config1.replace("sys.stdout", "sys.stbout") + +config3 has a less subtle configuration error +>>> config3 = config1.replace("formatter=form1", "formatter=misspelled_name") + +>>> def test4(conf): +... loggerDict = logging.getLogger().manager.loggerDict +... logging._acquireLock() +... try: +... saved_handlers = logging._handlers.copy() +... saved_handler_list = logging._handlerList[:] +... saved_loggers = loggerDict.copy() +... finally: +... logging._releaseLock() +... try: +... fn = test.test_support.TESTFN +... f = open(fn, "w") +... f.write(conf) +... f.close() +... try: +... logging.config.fileConfig(fn) +... #call again to make sure cleanup is correct +... logging.config.fileConfig(fn) +... except: +... t = sys.exc_info()[0] +... message(str(t)) +... else: +... message('ok.') +... os.remove(fn) +... finally: +... logging._acquireLock() +... try: +... logging._handlers.clear() +... logging._handlers.update(saved_handlers) +... logging._handlerList[:] = saved_handler_list +... loggerDict = logging.getLogger().manager.loggerDict +... loggerDict.clear() +... loggerDict.update(saved_loggers) +... finally: +... logging._releaseLock() + +>>> test4(config0) +ok. + +>>> test4(config1) +ok. + +>>> test4(config2) +<type 'AttributeError'> + +>>> test4(config3) +<type 'KeyError'> + +>>> from test import test_logging +>>> test_logging.test5() +ERROR:root:just testing +<type 'KeyError'>... Don't panic! + + +Test Main +========= +>>> import select +>>> import os, sys, string, struct, types, pickle, io +>>> import socket, tempfile, threading, time +>>> import logging, logging.handlers, logging.config +>>> from test import test_logging + +XXX: The test is unstable! +#>>> test_logging.test_main_inner() +ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR) +ERR -> ERROR: Message 1 (via logrecv.tcp.ERR) +INF -> CRITICAL: Message 2 (via logrecv.tcp.INF) +INF -> ERROR: Message 3 (via logrecv.tcp.INF) +INF -> WARNING: Message 4 (via logrecv.tcp.INF) +INF -> INFO: Message 5 (via logrecv.tcp.INF) +INF.UNDEF -> CRITICAL: Message 6 (via logrecv.tcp.INF.UNDEF) +INF.UNDEF -> ERROR: Message 7 (via logrecv.tcp.INF.UNDEF) +INF.UNDEF -> WARNING: Message 8 (via logrecv.tcp.INF.UNDEF) +INF.UNDEF -> INFO: Message 9 (via logrecv.tcp.INF.UNDEF) +INF.ERR -> CRITICAL: Message 10 (via logrecv.tcp.INF.ERR) +INF.ERR -> ERROR: Message 11 (via logrecv.tcp.INF.ERR) +INF.ERR.UNDEF -> CRITICAL: Message 12 (via logrecv.tcp.INF.ERR.UNDEF) +INF.ERR.UNDEF -> ERROR: Message 13 (via logrecv.tcp.INF.ERR.UNDEF) +DEB -> CRITICAL: Message 14 (via logrecv.tcp.DEB) +DEB -> ERROR: Message 15 (via logrecv.tcp.DEB) +DEB -> WARNING: Message 16 (via logrecv.tcp.DEB) +DEB -> INFO: Message 17 (via logrecv.tcp.DEB) +DEB -> DEBUG: Message 18 (via logrecv.tcp.DEB) +UNDEF -> CRITICAL: Message 19 (via logrecv.tcp.UNDEF) +UNDEF -> ERROR: Message 20 (via logrecv.tcp.UNDEF) +UNDEF -> WARNING: Message 21 (via logrecv.tcp.UNDEF) +UNDEF -> INFO: Message 22 (via logrecv.tcp.UNDEF) +INF.BADPARENT.UNDEF -> CRITICAL: Message 23 (via logrecv.tcp.INF.BADPARENT.UNDEF) +INF.BADPARENT -> CRITICAL: Message 24 (via logrecv.tcp.INF.BADPARENT) +INF -> INFO: Finish up, it's closing time. Messages should bear numbers 0 through 24. (via logrecv.tcp.INF) +<BLANKLINE> +""" import select import os, sys, struct, pickle, io import socket, tempfile, threading, time -import logging, logging.handlers, logging.config -from test.test_support import run_with_locale +import logging, logging.handlers, logging.config, test.test_support + BANNER = "-- %-10s %-6s ---------------------------------------------------\n" FINISH_UP = "Finish up, it's closing time. Messages should bear numbers 0 through 24." +#---------------------------------------------------------------------------- +# Test 0 +#---------------------------------------------------------------------------- + +msgcount = 0 + +def nextmessage(): + global msgcount + rv = "Message %d" % msgcount + msgcount = msgcount + 1 + return rv #---------------------------------------------------------------------------- # Log receiver @@ -78,11 +1923,80 @@ class LogRecordStreamHandler(StreamRequestHandler): if record.msg == FINISH_UP: self.server.abort = 1 record.msg = record.msg + " (via " + logname + ")" - logger = logging.getLogger(logname) + logger = logging.getLogger("logrecv") logger.handle(record) # The server sets socketDataProcessed when it's done. socketDataProcessed = threading.Event() +#---------------------------------------------------------------------------- +# Test 5 +#---------------------------------------------------------------------------- + +test5_config = """ +[loggers] +keys=root + +[handlers] +keys=hand1 + +[formatters] +keys=form1 + +[logger_root] +level=NOTSET +handlers=hand1 + +[handler_hand1] +class=StreamHandler +level=NOTSET +formatter=form1 +args=(sys.stdout,) + +[formatter_form1] +class=test.test_logging.FriendlyFormatter +format=%(levelname)s:%(name)s:%(message)s +datefmt= +""" + +class FriendlyFormatter (logging.Formatter): + def formatException(self, ei): + return "%s... Don't panic!" % str(ei[0]) + + +def test5(): + loggerDict = logging.getLogger().manager.loggerDict + logging._acquireLock() + try: + saved_handlers = logging._handlers.copy() + saved_handler_list = logging._handlerList[:] + saved_loggers = loggerDict.copy() + finally: + logging._releaseLock() + try: + fn = test.test_support.TESTFN + f = open(fn, "w") + f.write(test5_config) + f.close() + logging.config.fileConfig(fn) + try: + raise KeyError + except KeyError: + logging.exception("just testing") + os.remove(fn) + hdlr = logging.getLogger().handlers[0] + logging.getLogger().handlers.remove(hdlr) + finally: + logging._acquireLock() + try: + logging._handlers.clear() + logging._handlers.update(saved_handlers) + logging._handlerList[:] = saved_handler_list + loggerDict = logging.getLogger().manager.loggerDict + loggerDict.clear() + loggerDict.update(saved_loggers) + finally: + logging._releaseLock() + class LogRecordSocketReceiver(ThreadingTCPServer): """ @@ -105,8 +2019,6 @@ class LogRecordSocketReceiver(ThreadingTCPServer): self.timeout) if rd: self.handle_request() - #notify the main thread that we're about to exit - socketDataProcessed.set() # close the listen socket self.server_close() @@ -119,17 +2031,10 @@ class LogRecordSocketReceiver(ThreadingTCPServer): def runTCP(tcpserver): tcpserver.serve_until_stopped() -#---------------------------------------------------------------------------- -# Test 0 -#---------------------------------------------------------------------------- - -msgcount = 0 - -def nextmessage(): - global msgcount - rv = "Message %d" % msgcount - msgcount = msgcount + 1 - return rv +def banner(nm, typ): + sep = BANNER % (nm, typ) + sys.stdout.write(sep) + sys.stdout.flush() def test0(): ERR = logging.getLogger("ERR") @@ -199,202 +2104,70 @@ def test0(): INF.info(FINISH_UP) -#---------------------------------------------------------------------------- -# Test 1 -#---------------------------------------------------------------------------- +def test_main_inner(): + rootLogger = logging.getLogger("") + rootLogger.setLevel(logging.DEBUG) -# -# First, we define our levels. There can be as many as you want - the only -# limitations are that they should be integers, the lowest should be > 0 and -# larger values mean less information being logged. If you need specific -# level values which do not fit into these limitations, you can use a -# mapping dictionary to convert between your application levels and the -# logging system. -# -SILENT = 10 -TACITURN = 9 -TERSE = 8 -EFFUSIVE = 7 -SOCIABLE = 6 -VERBOSE = 5 -TALKATIVE = 4 -GARRULOUS = 3 -CHATTERBOX = 2 -BORING = 1 - -LEVEL_RANGE = range(BORING, SILENT + 1) - -# -# Next, we define names for our levels. You don't need to do this - in which -# case the system will use "Level n" to denote the text for the level. -# -my_logging_levels = { - SILENT : 'Silent', - TACITURN : 'Taciturn', - TERSE : 'Terse', - EFFUSIVE : 'Effusive', - SOCIABLE : 'Sociable', - VERBOSE : 'Verbose', - TALKATIVE : 'Talkative', - GARRULOUS : 'Garrulous', - CHATTERBOX : 'Chatterbox', - BORING : 'Boring', -} - -# -# Now, to demonstrate filtering: suppose for some perverse reason we only -# want to print out all except GARRULOUS messages. Let's create a filter for -# this purpose... -# -class SpecificLevelFilter(logging.Filter): - def __init__(self, lvl): - self.level = lvl - - def filter(self, record): - return self.level != record.levelno - -class GarrulousFilter(SpecificLevelFilter): - def __init__(self): - SpecificLevelFilter.__init__(self, GARRULOUS) - -# -# Now, let's demonstrate filtering at the logger. This time, use a filter -# which excludes SOCIABLE and TACITURN messages. Note that GARRULOUS events -# are still excluded. -# -class VerySpecificFilter(logging.Filter): - def filter(self, record): - return record.levelno not in [SOCIABLE, TACITURN] + # Find an unused port number + port = logging.handlers.DEFAULT_TCP_LOGGING_PORT + while port < logging.handlers.DEFAULT_TCP_LOGGING_PORT+100: + try: + tcpserver = LogRecordSocketReceiver(port=port) + except socket.error: + port += 1 + else: + break + else: + raise ImportError("Could not find unused port") -def message(s): - sys.stdout.write("%s\n" % s) -SHOULD1 = "This should only be seen at the '%s' logging level (or lower)" - -def test1(): -# -# Now, tell the logging system to associate names with our levels. -# - for lvl in my_logging_levels.keys(): - logging.addLevelName(lvl, my_logging_levels[lvl]) - -# -# Now, define a test function which logs an event at each of our levels. -# - - def doLog(log): - for lvl in LEVEL_RANGE: - log.log(lvl, SHOULD1, logging.getLevelName(lvl)) - - log = logging.getLogger("") - hdlr = log.handlers[0] -# -# Set the logging level to each different value and call the utility -# function to log events. -# In the output, you should see that each time round the loop, the number of -# logging events which are actually output decreases. -# - for lvl in LEVEL_RANGE: - message("-- setting logging level to '%s' -----" % - logging.getLevelName(lvl)) - log.setLevel(lvl) - doLog(log) - # - # Now, we demonstrate level filtering at the handler level. Tell the - # handler defined above to filter at level 'SOCIABLE', and repeat the - # above loop. Compare the output from the two runs. - # - hdlr.setLevel(SOCIABLE) - message("-- Filtering at handler level to SOCIABLE --") - for lvl in LEVEL_RANGE: - message("-- setting logging level to '%s' -----" % - logging.getLevelName(lvl)) - log.setLevel(lvl) - doLog(log) - - hdlr.setLevel(0) #turn off level filtering at the handler - - garr = GarrulousFilter() - hdlr.addFilter(garr) - message("-- Filtering using GARRULOUS filter --") - for lvl in LEVEL_RANGE: - message("-- setting logging level to '%s' -----" % - logging.getLevelName(lvl)) - log.setLevel(lvl) - doLog(log) - spec = VerySpecificFilter() - log.addFilter(spec) - message("-- Filtering using specific filter for SOCIABLE, TACITURN --") - for lvl in LEVEL_RANGE: - message("-- setting logging level to '%s' -----" % - logging.getLevelName(lvl)) - log.setLevel(lvl) - doLog(log) - - log.removeFilter(spec) - hdlr.removeFilter(garr) - #Undo the one level which clashes...for regression tests - logging.addLevelName(logging.DEBUG, "DEBUG") + #Set up a handler such that all events are sent via a socket to the log + #receiver (logrecv). + #The handler will only be added to the rootLogger for some of the tests + shdlr = logging.handlers.SocketHandler('localhost', port) + rootLogger.addHandler(shdlr) -#---------------------------------------------------------------------------- -# Test 2 -#---------------------------------------------------------------------------- + #Configure the logger for logrecv so events do not propagate beyond it. + #The sockLogger output is buffered in memory until the end of the test, + #and printed at the end. + sockOut = io.StringIO() + sockLogger = logging.getLogger("logrecv") + sockLogger.setLevel(logging.DEBUG) + sockhdlr = logging.StreamHandler(sockOut) + sockhdlr.setFormatter(logging.Formatter( + "%(name)s -> %(levelname)s: %(message)s")) + sockLogger.addHandler(sockhdlr) + sockLogger.propagate = 0 -MSG = "-- logging %d at INFO, messages should be seen every 10 events --" -def test2(): - logger = logging.getLogger("") - sh = logger.handlers[0] - sh.close() - logger.removeHandler(sh) - mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh) - logger.setLevel(logging.DEBUG) - logger.addHandler(mh) - message("-- logging at DEBUG, nothing should be seen yet --") - logger.debug("Debug message") - message("-- logging at INFO, nothing should be seen yet --") - logger.info("Info message") - message("-- logging at WARNING, 3 messages should be seen --") - logger.warn("Warn message") - for i in range(102): - message(MSG % i) - logger.info("Info index = %d", i) - mh.close() - logger.removeHandler(mh) - logger.addHandler(sh) + #Set up servers + threads = [] + #sys.stdout.write("About to start TCP server...\n") + threads.append(threading.Thread(target=runTCP, args=(tcpserver,))) -#---------------------------------------------------------------------------- -# Test 3 -#---------------------------------------------------------------------------- + for thread in threads: + thread.start() + try: + test0() -FILTER = "a.b" - -def doLog3(): - logging.getLogger("a").info("Info 1") - logging.getLogger("a.b").info("Info 2") - logging.getLogger("a.c").info("Info 3") - logging.getLogger("a.b.c").info("Info 4") - logging.getLogger("a.b.c.d").info("Info 5") - logging.getLogger("a.bb.c").info("Info 6") - logging.getLogger("b").info("Info 7") - logging.getLogger("b.a").info("Info 8") - logging.getLogger("c.a.b").info("Info 9") - logging.getLogger("a.bb").info("Info 10") - -def test3(): - root = logging.getLogger() - root.setLevel(logging.DEBUG) - hand = root.handlers[0] - message("Unfiltered...") - doLog3() - message("Filtered with '%s'..." % FILTER) - filt = logging.Filter(FILTER) - hand.addFilter(filt) - doLog3() - hand.removeFilter(filt) + # XXX(nnorwitz): Try to fix timing related test failures. + # This sleep gives us some extra time to read messages. + # The test generally only fails on Solaris without this sleep. + #time.sleep(2.0) + shdlr.close() + rootLogger.removeHandler(shdlr) -#---------------------------------------------------------------------------- -# Test 4 -#---------------------------------------------------------------------------- + finally: + #wait for TCP receiver to terminate +# socketDataProcessed.wait() + # ensure the server dies + tcpserver.abort = 1 + for thread in threads: + thread.join(2.0) + print(sockOut.getvalue()) + sockOut.close() + sockLogger.removeHandler(sockhdlr) + sockhdlr.close() + sys.stdout.flush() # config0 is a standard configuration. config0 = """ @@ -454,231 +2227,18 @@ format=%(levelname)s:%(name)s:%(message)s datefmt= """ +def message(s): + sys.stdout.write("%s\n" % s) + # config2 has a subtle configuration error that should be reported config2 = config1.replace("sys.stdout", "sys.stbout") # config3 has a less subtle configuration error config3 = config1.replace("formatter=form1", "formatter=misspelled_name") -def test4(): - for i in range(4): - conf = globals()['config%d' % i] - sys.stdout.write('config%d: ' % i) - loggerDict = logging.getLogger().manager.loggerDict - logging._acquireLock() - try: - saved_handlers = logging._handlers.copy() - saved_handler_list = logging._handlerList[:] - saved_loggers = loggerDict.copy() - finally: - logging._releaseLock() - try: - fn = tempfile.mktemp(".ini") - f = open(fn, "w") - f.write(conf) - f.close() - try: - logging.config.fileConfig(fn) - #call again to make sure cleanup is correct - logging.config.fileConfig(fn) - except: - t = sys.exc_info()[0] - message(str(t)) - else: - message('ok.') - os.remove(fn) - finally: - logging._acquireLock() - try: - logging._handlers.clear() - logging._handlers.update(saved_handlers) - logging._handlerList[:] = saved_handler_list - loggerDict = logging.getLogger().manager.loggerDict - loggerDict.clear() - loggerDict.update(saved_loggers) - finally: - logging._releaseLock() - -#---------------------------------------------------------------------------- -# Test 5 -#---------------------------------------------------------------------------- - -test5_config = """ -[loggers] -keys=root - -[handlers] -keys=hand1 - -[formatters] -keys=form1 - -[logger_root] -level=NOTSET -handlers=hand1 - -[handler_hand1] -class=StreamHandler -level=NOTSET -formatter=form1 -args=(sys.stdout,) - -[formatter_form1] -class=test.test_logging.FriendlyFormatter -format=%(levelname)s:%(name)s:%(message)s -datefmt= -""" - -class FriendlyFormatter (logging.Formatter): - def formatException(self, ei): - return "%s... Don't panic!" % str(ei[0]) - - -def test5(): - loggerDict = logging.getLogger().manager.loggerDict - logging._acquireLock() - try: - saved_handlers = logging._handlers.copy() - saved_handler_list = logging._handlerList[:] - saved_loggers = loggerDict.copy() - finally: - logging._releaseLock() - try: - fn = tempfile.mktemp(".ini") - f = open(fn, "w") - f.write(test5_config) - f.close() - logging.config.fileConfig(fn) - try: - raise KeyError - except KeyError: - logging.exception("just testing") - os.remove(fn) - hdlr = logging.getLogger().handlers[0] - logging.getLogger().handlers.remove(hdlr) - finally: - logging._acquireLock() - try: - logging._handlers.clear() - logging._handlers.update(saved_handlers) - logging._handlerList[:] = saved_handler_list - loggerDict = logging.getLogger().manager.loggerDict - loggerDict.clear() - loggerDict.update(saved_loggers) - finally: - logging._releaseLock() - - -#---------------------------------------------------------------------------- -# Test Harness -#---------------------------------------------------------------------------- -def banner(nm, typ): - sep = BANNER % (nm, typ) - sys.stdout.write(sep) - sys.stdout.flush() - -def test_main_inner(): - rootLogger = logging.getLogger("") - rootLogger.setLevel(logging.DEBUG) - hdlr = logging.StreamHandler(sys.stdout) - fmt = logging.Formatter(logging.BASIC_FORMAT) - hdlr.setFormatter(fmt) - rootLogger.addHandler(hdlr) - - # Find an unused port number - port = logging.handlers.DEFAULT_TCP_LOGGING_PORT - while port < logging.handlers.DEFAULT_TCP_LOGGING_PORT+100: - try: - tcpserver = LogRecordSocketReceiver(port=port) - except socket.error: - port += 1 - else: - break - else: - raise ImportError("Could not find unused port") - - - #Set up a handler such that all events are sent via a socket to the log - #receiver (logrecv). - #The handler will only be added to the rootLogger for some of the tests - shdlr = logging.handlers.SocketHandler('localhost', port) - - #Configure the logger for logrecv so events do not propagate beyond it. - #The sockLogger output is buffered in memory until the end of the test, - #and printed at the end. - sockOut = io.StringIO() - sockLogger = logging.getLogger("logrecv") - sockLogger.setLevel(logging.DEBUG) - sockhdlr = logging.StreamHandler(sockOut) - sockhdlr.setFormatter(logging.Formatter( - "%(name)s -> %(levelname)s: %(message)s")) - sockLogger.addHandler(sockhdlr) - sockLogger.propagate = 0 - - #Set up servers - threads = [] - #sys.stdout.write("About to start TCP server...\n") - threads.append(threading.Thread(target=runTCP, args=(tcpserver,))) - - for thread in threads: - thread.start() - try: - banner("log_test0", "begin") - - rootLogger.addHandler(shdlr) - test0() - # XXX(nnorwitz): Try to fix timing related test failures. - # This sleep gives us some extra time to read messages. - # The test generally only fails on Solaris without this sleep. - time.sleep(2.0) - shdlr.close() - rootLogger.removeHandler(shdlr) - - banner("log_test0", "end") - - for t in range(1,6): - banner("log_test%d" % t, "begin") - globals()['test%d' % t]() - banner("log_test%d" % t, "end") - - finally: - #wait for TCP receiver to terminate - socketDataProcessed.wait() - # ensure the server dies - tcpserver.abort = 1 - for thread in threads: - thread.join(2.0) - banner("logrecv output", "begin") - sys.stdout.write(sockOut.getvalue()) - sockOut.close() - sockLogger.removeHandler(sockhdlr) - sockhdlr.close() - banner("logrecv output", "end") - sys.stdout.flush() - try: - hdlr.close() - except: - pass - rootLogger.removeHandler(hdlr) - -# Set the locale to the platform-dependent default. I have no idea -# why the test does this, but in any case we save the current locale -# first and restore it at the end. -@run_with_locale('LC_ALL', '') def test_main(): - # Save and restore the original root logger level across the tests. - # Otherwise, e.g., if any test using cookielib runs after test_logging, - # cookielib's debug-level logger tries to log messages, leading to - # confusing: - # No handlers could be found for logger "cookielib" - # output while the tests are running. - root_logger = logging.getLogger("") - original_logging_level = root_logger.getEffectiveLevel() - try: - test_main_inner() - finally: - root_logger.setLevel(original_logging_level) + from test import test_support, test_logging + test_support.run_doctest(test_logging) -if __name__ == "__main__": - sys.stdout.write("test_logging\n") +if __name__=="__main__": test_main() |