Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
0c8f5556
Commit
0c8f5556
authored
Dec 10, 2010
by
Vinay Sajip
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
logging: added handler of last resort.
parent
c24a81df
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
87 additions
and
14 deletions
+87
-14
Lib/logging/__init__.py
Lib/logging/__init__.py
+50
-14
Lib/test/test_logging.py
Lib/test/test_logging.py
+35
-0
Misc/NEWS
Misc/NEWS
+2
-0
No files found.
Lib/logging/__init__.py
View file @
0c8f5556
...
@@ -33,7 +33,7 @@ __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
...
@@ -33,7 +33,7 @@ __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
'captureWarnings'
,
'critical'
,
'debug'
,
'disable'
,
'error'
,
'captureWarnings'
,
'critical'
,
'debug'
,
'disable'
,
'error'
,
'exception'
,
'fatal'
,
'getLevelName'
,
'getLogger'
,
'getLoggerClass'
,
'exception'
,
'fatal'
,
'getLevelName'
,
'getLogger'
,
'getLoggerClass'
,
'info'
,
'log'
,
'makeLogRecord'
,
'setLoggerClass'
,
'warn'
,
'warning'
,
'info'
,
'log'
,
'makeLogRecord'
,
'setLoggerClass'
,
'warn'
,
'warning'
,
'getLogRecordFactory'
,
'setLogRecordFactory'
]
'getLogRecordFactory'
,
'setLogRecordFactory'
,
'lastResort'
]
try
:
try
:
import
codecs
import
codecs
...
@@ -997,6 +997,26 @@ class FileHandler(StreamHandler):
...
@@ -997,6 +997,26 @@ class FileHandler(StreamHandler):
self
.
stream
=
self
.
_open
()
self
.
stream
=
self
.
_open
()
StreamHandler
.
emit
(
self
,
record
)
StreamHandler
.
emit
(
self
,
record
)
class
_StderrHandler
(
StreamHandler
):
"""
This class is like a StreamHandler using sys.stderr, but always uses
whatever sys.stderr is currently set to rather than the value of
sys.stderr at handler construction time.
"""
def
__init__
(
self
,
level
=
NOTSET
):
"""
Initialize the handler.
"""
Handler
.
__init__
(
self
,
level
)
@
property
def
stream
(
self
):
return
sys
.
stderr
_defaultLastResort
=
_StderrHandler
(
WARNING
)
lastResort
=
_defaultLastResort
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
# Manager classes and functions
# Manager classes and functions
#---------------------------------------------------------------------------
#---------------------------------------------------------------------------
...
@@ -1056,7 +1076,7 @@ class Manager(object):
...
@@ -1056,7 +1076,7 @@ class Manager(object):
"""
"""
self
.
root
=
rootnode
self
.
root
=
rootnode
self
.
disable
=
0
self
.
disable
=
0
self
.
emittedNoHandlerWarning
=
0
self
.
emittedNoHandlerWarning
=
False
self
.
loggerDict
=
{}
self
.
loggerDict
=
{}
self
.
loggerClass
=
None
self
.
loggerClass
=
None
self
.
logRecordFactory
=
None
self
.
logRecordFactory
=
None
...
@@ -1415,10 +1435,13 @@ class Logger(Filterer):
...
@@ -1415,10 +1435,13 @@ class Logger(Filterer):
c
=
None
#break out
c
=
None
#break out
else
:
else
:
c
=
c
.
parent
c
=
c
.
parent
if
(
found
==
0
)
and
raiseExceptions
and
not
self
.
manager
.
emittedNoHandlerWarning
:
if
(
found
==
0
):
sys
.
stderr
.
write
(
"No handlers could be found for logger"
if
lastResort
:
"
\
"
%s
\
"
\
n
"
%
self
.
name
)
lastResort
.
handle
(
record
)
self
.
manager
.
emittedNoHandlerWarning
=
1
elif
raiseExceptions
and
not
self
.
manager
.
emittedNoHandlerWarning
:
sys
.
stderr
.
write
(
"No handlers could be found for logger"
"
\
"
%s
\
"
\
n
"
%
self
.
name
)
self
.
manager
.
emittedNoHandlerWarning
=
True
def
getEffectiveLevel
(
self
):
def
getEffectiveLevel
(
self
):
"""
"""
...
@@ -1676,7 +1699,9 @@ def getLogger(name=None):
...
@@ -1676,7 +1699,9 @@ def getLogger(name=None):
def
critical
(
msg
,
*
args
,
**
kwargs
):
def
critical
(
msg
,
*
args
,
**
kwargs
):
"""
"""
Log a message with severity 'CRITICAL' on the root logger.
Log a message with severity 'CRITICAL' on the root logger. If the logger
has no handlers, call basicConfig() to add a console handler with a
pre-defined format.
"""
"""
if
len
(
root
.
handlers
)
==
0
:
if
len
(
root
.
handlers
)
==
0
:
basicConfig
()
basicConfig
()
...
@@ -1686,7 +1711,9 @@ fatal = critical
...
@@ -1686,7 +1711,9 @@ fatal = critical
def
error
(
msg
,
*
args
,
**
kwargs
):
def
error
(
msg
,
*
args
,
**
kwargs
):
"""
"""
Log a message with severity 'ERROR' on the root logger.
Log a message with severity 'ERROR' on the root logger. If the logger has
no handlers, call basicConfig() to add a console handler with a pre-defined
format.
"""
"""
if
len
(
root
.
handlers
)
==
0
:
if
len
(
root
.
handlers
)
==
0
:
basicConfig
()
basicConfig
()
...
@@ -1694,15 +1721,18 @@ def error(msg, *args, **kwargs):
...
@@ -1694,15 +1721,18 @@ def error(msg, *args, **kwargs):
def
exception
(
msg
,
*
args
,
**
kwargs
):
def
exception
(
msg
,
*
args
,
**
kwargs
):
"""
"""
Log a message with severity 'ERROR' on the root logger,
Log a message with severity 'ERROR' on the root logger, with exception
with exception information.
information. If the logger has no handlers, basicConfig() is called to add
a console handler with a pre-defined format.
"""
"""
kwargs
[
'exc_info'
]
=
True
kwargs
[
'exc_info'
]
=
True
error
(
msg
,
*
args
,
**
kwargs
)
error
(
msg
,
*
args
,
**
kwargs
)
def
warning
(
msg
,
*
args
,
**
kwargs
):
def
warning
(
msg
,
*
args
,
**
kwargs
):
"""
"""
Log a message with severity 'WARNING' on the root logger.
Log a message with severity 'WARNING' on the root logger. If the logger has
no handlers, call basicConfig() to add a console handler with a pre-defined
format.
"""
"""
if
len
(
root
.
handlers
)
==
0
:
if
len
(
root
.
handlers
)
==
0
:
basicConfig
()
basicConfig
()
...
@@ -1712,7 +1742,9 @@ warn = warning
...
@@ -1712,7 +1742,9 @@ warn = warning
def
info
(
msg
,
*
args
,
**
kwargs
):
def
info
(
msg
,
*
args
,
**
kwargs
):
"""
"""
Log a message with severity 'INFO' on the root logger.
Log a message with severity 'INFO' on the root logger. If the logger has
no handlers, call basicConfig() to add a console handler with a pre-defined
format.
"""
"""
if
len
(
root
.
handlers
)
==
0
:
if
len
(
root
.
handlers
)
==
0
:
basicConfig
()
basicConfig
()
...
@@ -1720,7 +1752,9 @@ def info(msg, *args, **kwargs):
...
@@ -1720,7 +1752,9 @@ def info(msg, *args, **kwargs):
def
debug
(
msg
,
*
args
,
**
kwargs
):
def
debug
(
msg
,
*
args
,
**
kwargs
):
"""
"""
Log a message with severity 'DEBUG' on the root logger.
Log a message with severity 'DEBUG' on the root logger. If the logger has
no handlers, call basicConfig() to add a console handler with a pre-defined
format.
"""
"""
if
len
(
root
.
handlers
)
==
0
:
if
len
(
root
.
handlers
)
==
0
:
basicConfig
()
basicConfig
()
...
@@ -1728,7 +1762,9 @@ def debug(msg, *args, **kwargs):
...
@@ -1728,7 +1762,9 @@ def debug(msg, *args, **kwargs):
def
log
(
level
,
msg
,
*
args
,
**
kwargs
):
def
log
(
level
,
msg
,
*
args
,
**
kwargs
):
"""
"""
Log 'msg % args' with the integer severity 'level' on the root logger.
Log 'msg % args' with the integer severity 'level' on the root logger. If
the logger has no handlers, call basicConfig() to add a console handler
with a pre-defined format.
"""
"""
if
len
(
root
.
handlers
)
==
0
:
if
len
(
root
.
handlers
)
==
0
:
basicConfig
()
basicConfig
()
...
...
Lib/test/test_logging.py
View file @
0c8f5556
...
@@ -1927,6 +1927,40 @@ class FormatterTest(unittest.TestCase):
...
@@ -1927,6 +1927,40 @@ class FormatterTest(unittest.TestCase):
f = logging.Formatter('asctime', style='$')
f = logging.Formatter('asctime', style='$')
self.assertFalse(f.usesTime())
self.assertFalse(f.usesTime())
class LastResortTest(BaseTest):
def test_last_resort(self):
"
Test
the
last
resort
handler
"
root = self.root_logger
root.removeHandler(self.root_hdlr)
old_stderr = sys.stderr
old_lastresort = logging.lastResort
old_raise_exceptions = logging.raiseExceptions
try:
sys.stderr = sio = io.StringIO()
root.warning('This is your final chance!')
self.assertEqual(sio.getvalue(), 'This is your final chance!
\
n
')
#No handlers and no last resort, so 'No handlers' message
logging.lastResort = None
sys.stderr = sio = io.StringIO()
root.warning('This is your final chance!')
self.assertEqual(sio.getvalue(), 'No handlers could be found for logger "
root
"
\
n
')
# 'No handlers' message only printed once
sys.stderr = sio = io.StringIO()
root.warning('This is your final chance!')
self.assertEqual(sio.getvalue(), '')
root.manager.emittedNoHandlerWarning = False
#If raiseExceptions is False, no message is printed
logging.raiseExceptions = False
sys.stderr = sio = io.StringIO()
root.warning('This is your final chance!')
self.assertEqual(sio.getvalue(), '')
finally:
sys.stderr = old_stderr
root.addHandler(self.root_hdlr)
logging.lastResort = old_lastresort
logging.raiseExceptions = old_raise_exceptions
class BaseFileTest(BaseTest):
class BaseFileTest(BaseTest):
"
Base
class
for
handler
tests
that
write
log
files
"
"
Base
class
for
handler
tests
that
write
log
files
"
...
@@ -2017,6 +2051,7 @@ def test_main():
...
@@ -2017,6 +2051,7 @@ def test_main():
FormatterTest,
FormatterTest,
LogRecordFactoryTest, ChildLoggerTest, QueueHandlerTest,
LogRecordFactoryTest, ChildLoggerTest, QueueHandlerTest,
RotatingFileHandlerTest,
RotatingFileHandlerTest,
LastResortTest,
#TimedRotatingFileHandlerTest
#TimedRotatingFileHandlerTest
)
)
...
...
Misc/NEWS
View file @
0c8f5556
...
@@ -63,6 +63,8 @@ Core and Builtins
...
@@ -63,6 +63,8 @@ Core and Builtins
Library
Library
-------
-------
- logging: added "handler of last resort". See http://bit.ly/last-resort-handler
- test.support: Added TestHandler and Matcher classes for better support of
- test.support: Added TestHandler and Matcher classes for better support of
assertions about logging.
assertions about logging.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment