mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Merged revisions 77967,77969,77973,77979,77985-77986,78009,78029,78031-78033,78081,78085,78103,78105-78106,78108,78246,78703,78728,78731,78853,78855 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r77967 | vinay.sajip | 2010-02-04 12:48:53 -0600 (Thu, 04 Feb 2010) | 1 line Logging: Implemented PEP 391. ........ r77969 | vinay.sajip | 2010-02-04 14:18:28 -0600 (Thu, 04 Feb 2010) | 1 line Removed spurious print statement. ........ r77973 | vinay.sajip | 2010-02-04 14:23:45 -0600 (Thu, 04 Feb 2010) | 1 line Issue #7851: logging: clarification on logging configuration files. ........ r77979 | vinay.sajip | 2010-02-04 15:40:56 -0600 (Thu, 04 Feb 2010) | 1 line Added unit test for cfg:// resolution. ........ r77985 | vinay.sajip | 2010-02-05 08:52:05 -0600 (Fri, 05 Feb 2010) | 1 line Issue #7857: test_logging: listener test now uses find_unused_port(). ........ r77986 | vinay.sajip | 2010-02-05 09:40:20 -0600 (Fri, 05 Feb 2010) | 1 line Issue #7857: test_logging: listener tests disabled for now. ........ r78009 | vinay.sajip | 2010-02-05 17:43:11 -0600 (Fri, 05 Feb 2010) | 1 line test_logging: minor tweaks to timeouts, listening tests marked as skipped. ........ r78029 | vinay.sajip | 2010-02-06 14:00:43 -0600 (Sat, 06 Feb 2010) | 1 line Issue #7857: Tentatively re-enabling one test to see effect on buildbots. ........ r78031 | vinay.sajip | 2010-02-06 14:28:36 -0600 (Sat, 06 Feb 2010) | 1 line Issue #7857: Gave server thread more time to get ready, and re-enabled a skipped test. ........ r78032 | georg.brandl | 2010-02-06 15:54:40 -0600 (Sat, 06 Feb 2010) | 1 line Remove unused imports from test_logging. ........ r78033 | benjamin.peterson | 2010-02-06 16:08:15 -0600 (Sat, 06 Feb 2010) | 1 line make waiting for the server to start robust ........ r78081 | vinay.sajip | 2010-02-07 06:56:54 -0600 (Sun, 07 Feb 2010) | 1 line Issue #7869: logging: improved format-time diagnostics and removed some 1.5.2 support code. ........ r78085 | vinay.sajip | 2010-02-07 07:06:51 -0600 (Sun, 07 Feb 2010) | 1 line logging: Removed some more 1.5.2 support code. ........ r78103 | vinay.sajip | 2010-02-08 00:50:14 -0600 (Mon, 08 Feb 2010) | 1 line Removed spurious print statement in test. ........ r78105 | vinay.sajip | 2010-02-08 09:32:08 -0600 (Mon, 08 Feb 2010) | 1 line logging: skipped listening tests because they're not working reliably. ........ r78106 | vinay.sajip | 2010-02-08 10:05:50 -0600 (Mon, 08 Feb 2010) | 1 line Issue #7857: Another attempt to keep the buildbots happy. ........ r78108 | vinay.sajip | 2010-02-08 15:18:15 -0600 (Mon, 08 Feb 2010) | 1 line logging: gingerly re-enabling skipped tests after improving thread sync code in configurator. ........ r78246 | vinay.sajip | 2010-02-19 17:53:17 -0600 (Fri, 19 Feb 2010) | 1 line logging: Documented warnings module integration. ........ r78703 | vinay.sajip | 2010-03-05 16:11:24 -0600 (Fri, 05 Mar 2010) | 1 line Factored out time usage determination into a method, to facilitate alternative formatting implementations in the future. ........ r78728 | vinay.sajip | 2010-03-06 09:12:08 -0600 (Sat, 06 Mar 2010) | 1 line Added schema version test in dictConfig. ........ r78731 | vinay.sajip | 2010-03-06 09:56:03 -0600 (Sat, 06 Mar 2010) | 1 line Added checks for tuples in dictConfig. ........ r78853 | vinay.sajip | 2010-03-12 00:01:21 -0600 (Fri, 12 Mar 2010) | 1 line Issue #8117: logging: Improved algorithm for computing initial rollover time. ........ r78855 | vinay.sajip | 2010-03-12 03:16:10 -0600 (Fri, 12 Mar 2010) | 1 line Issue #8117: Updated NEWS entry and added to logging documentation. ........
This commit is contained in:
parent
7ad96a5ac2
commit
9451a1c6ae
5 changed files with 159 additions and 20 deletions
|
@ -420,6 +420,13 @@ You can see that the config file approach has a few advantages over the Python
|
||||||
code approach, mainly separation of configuration and code and the ability of
|
code approach, mainly separation of configuration and code and the ability of
|
||||||
noncoders to easily modify the logging properties.
|
noncoders to easily modify the logging properties.
|
||||||
|
|
||||||
|
Note that the class names referenced in config files need to be either relative
|
||||||
|
to the logging module, or absolute values which can be resolved using normal
|
||||||
|
import mechanisms. Thus, you could use either `handlers.WatchedFileHandler`
|
||||||
|
(relative to the logging module) or `mypackage.mymodule.MyHandler` (for a
|
||||||
|
class defined in package `mypackage` and module `mymodule`, where `mypackage`
|
||||||
|
is available on the Python import path).
|
||||||
|
|
||||||
.. _library-config:
|
.. _library-config:
|
||||||
|
|
||||||
Configuring Logging for a Library
|
Configuring Logging for a Library
|
||||||
|
@ -1849,6 +1856,11 @@ timed intervals.
|
||||||
The extensions are date-and-time based, using the strftime format
|
The extensions are date-and-time based, using the strftime format
|
||||||
``%Y-%m-%d_%H-%M-%S`` or a leading portion thereof, depending on the
|
``%Y-%m-%d_%H-%M-%S`` or a leading portion thereof, depending on the
|
||||||
rollover interval.
|
rollover interval.
|
||||||
|
|
||||||
|
When computing the next rollover time for the first time (when the handler
|
||||||
|
is created), the last modification time of an existing log file, or else
|
||||||
|
the current time, is used to compute when the next rotation will occur.
|
||||||
|
|
||||||
If the *utc* argument is true, times in UTC will be used; otherwise
|
If the *utc* argument is true, times in UTC will be used; otherwise
|
||||||
local time is used.
|
local time is used.
|
||||||
|
|
||||||
|
@ -2401,6 +2413,28 @@ module, you may not be able to use logging from within such handlers. This is
|
||||||
because lock implementations in the :mod:`threading` module are not always
|
because lock implementations in the :mod:`threading` module are not always
|
||||||
re-entrant, and so cannot be invoked from such signal handlers.
|
re-entrant, and so cannot be invoked from such signal handlers.
|
||||||
|
|
||||||
|
|
||||||
|
Integration with the warnings module
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
The :func:`captureWarnings` function can be used to integrate :mod:`logging`
|
||||||
|
with the :mod:`warnings` module.
|
||||||
|
|
||||||
|
.. function:: captureWarnings(capture)
|
||||||
|
|
||||||
|
This function is used to turn the capture of warnings by logging on and
|
||||||
|
off.
|
||||||
|
|
||||||
|
If `capture` is `True`, warnings issued by the :mod:`warnings` module
|
||||||
|
will be redirected to the logging system. Specifically, a warning will be
|
||||||
|
formatted using :func:`warnings.formatwarning` and the resulting string
|
||||||
|
logged to a logger named "py.warnings" with a severity of `WARNING`.
|
||||||
|
|
||||||
|
If `capture` is `False`, the redirection of warnings to the logging system
|
||||||
|
will stop, and warnings will be redirected to their original destinations
|
||||||
|
(i.e. those in effect before `captureWarnings(True)` was called).
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -432,6 +432,12 @@ class Formatter(object):
|
||||||
s = s[:-1]
|
s = s[:-1]
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
def usesTime(self):
|
||||||
|
"""
|
||||||
|
Check if the format uses the creation time of the record.
|
||||||
|
"""
|
||||||
|
return self._fmt.find("%(asctime)") >= 0
|
||||||
|
|
||||||
def format(self, record):
|
def format(self, record):
|
||||||
"""
|
"""
|
||||||
Format the specified record as text.
|
Format the specified record as text.
|
||||||
|
@ -440,13 +446,13 @@ class Formatter(object):
|
||||||
string formatting operation which yields the returned string.
|
string formatting operation which yields the returned string.
|
||||||
Before formatting the dictionary, a couple of preparatory steps
|
Before formatting the dictionary, a couple of preparatory steps
|
||||||
are carried out. The message attribute of the record is computed
|
are carried out. The message attribute of the record is computed
|
||||||
using LogRecord.getMessage(). If the formatting string contains
|
using LogRecord.getMessage(). If the formatting string uses the
|
||||||
"%(asctime)", formatTime() is called to format the event time.
|
time (as determined by a call to usesTime(), formatTime() is
|
||||||
If there is exception information, it is formatted using
|
called to format the event time. If there is exception information,
|
||||||
formatException() and appended to the message.
|
it is formatted using formatException() and appended to the message.
|
||||||
"""
|
"""
|
||||||
record.message = record.getMessage()
|
record.message = record.getMessage()
|
||||||
if self._fmt.find("%(asctime)") >= 0:
|
if self.usesTime():
|
||||||
record.asctime = self.formatTime(record, self.datefmt)
|
record.asctime = self.formatTime(record, self.datefmt)
|
||||||
s = self._fmt % record.__dict__
|
s = self._fmt % record.__dict__
|
||||||
if record.exc_info:
|
if record.exc_info:
|
||||||
|
|
|
@ -261,7 +261,6 @@ def _install_loggers(cp, handlers, disable_existing_loggers):
|
||||||
logger.disabled = 1
|
logger.disabled = 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
|
IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
|
||||||
|
|
||||||
|
|
||||||
|
@ -448,7 +447,7 @@ class BaseConfigurator(object):
|
||||||
isinstance(value, tuple):
|
isinstance(value, tuple):
|
||||||
value = ConvertingTuple(value)
|
value = ConvertingTuple(value)
|
||||||
value.configurator = self
|
value.configurator = self
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str): # str for py3k
|
||||||
m = self.CONVERT_PATTERN.match(value)
|
m = self.CONVERT_PATTERN.match(value)
|
||||||
if m:
|
if m:
|
||||||
d = m.groupdict()
|
d = m.groupdict()
|
||||||
|
@ -474,6 +473,12 @@ class BaseConfigurator(object):
|
||||||
setattr(result, name, value)
|
setattr(result, name, value)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def as_tuple(self, value):
|
||||||
|
"""Utility function which converts lists to tuples."""
|
||||||
|
if isinstance(value, list):
|
||||||
|
value = tuple(value)
|
||||||
|
return value
|
||||||
|
|
||||||
class DictConfigurator(BaseConfigurator):
|
class DictConfigurator(BaseConfigurator):
|
||||||
"""
|
"""
|
||||||
Configure logging using a dictionary-like object to describe the
|
Configure logging using a dictionary-like object to describe the
|
||||||
|
@ -484,6 +489,10 @@ class DictConfigurator(BaseConfigurator):
|
||||||
"""Do the configuration."""
|
"""Do the configuration."""
|
||||||
|
|
||||||
config = self.config
|
config = self.config
|
||||||
|
if 'version' not in config:
|
||||||
|
raise ValueError("dictionary doesn't specify a version")
|
||||||
|
if config['version'] != 1:
|
||||||
|
raise ValueError("Unsupported version: %s" % config['version'])
|
||||||
incremental = config.pop('incremental', False)
|
incremental = config.pop('incremental', False)
|
||||||
EMPTY_DICT = {}
|
EMPTY_DICT = {}
|
||||||
logging._acquireLock()
|
logging._acquireLock()
|
||||||
|
@ -684,6 +693,12 @@ class DictConfigurator(BaseConfigurator):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise ValueError('Unable to set target handler '
|
raise ValueError('Unable to set target handler '
|
||||||
'%r: %s' % (config['target'], e))
|
'%r: %s' % (config['target'], e))
|
||||||
|
elif issubclass(klass, logging.handlers.SMTPHandler) and\
|
||||||
|
'mailhost' in config:
|
||||||
|
config['mailhost'] = self.as_tuple(config['mailhost'])
|
||||||
|
elif issubclass(klass, logging.handlers.SysLogHandler) and\
|
||||||
|
'address' in config:
|
||||||
|
config['address'] = self.as_tuple(config['address'])
|
||||||
factory = klass
|
factory = klass
|
||||||
kwargs = dict([(k, config[k]) for k in config if valid_ident(k)])
|
kwargs = dict([(k, config[k]) for k in config if valid_ident(k)])
|
||||||
try:
|
try:
|
||||||
|
@ -788,7 +803,7 @@ def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
|
||||||
chunk = self.connection.recv(slen)
|
chunk = self.connection.recv(slen)
|
||||||
while len(chunk) < slen:
|
while len(chunk) < slen:
|
||||||
chunk = chunk + conn.recv(slen - len(chunk))
|
chunk = chunk + conn.recv(slen - len(chunk))
|
||||||
chunk = chunk.decode('utf-8')
|
chunk = chunk.decode("utf-8")
|
||||||
try:
|
try:
|
||||||
import json
|
import json
|
||||||
d =json.loads(chunk)
|
d =json.loads(chunk)
|
||||||
|
|
|
@ -25,7 +25,7 @@ To use, simply 'import logging.handlers' and log away!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import logging, socket, os, pickle, struct, time, re
|
import logging, socket, os, pickle, struct, time, re
|
||||||
from stat import ST_DEV, ST_INO
|
from stat import ST_DEV, ST_INO, ST_MTIME
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import codecs
|
import codecs
|
||||||
|
@ -203,7 +203,11 @@ class TimedRotatingFileHandler(BaseRotatingHandler):
|
||||||
|
|
||||||
self.extMatch = re.compile(self.extMatch, re.ASCII)
|
self.extMatch = re.compile(self.extMatch, re.ASCII)
|
||||||
self.interval = self.interval * interval # multiply by units requested
|
self.interval = self.interval * interval # multiply by units requested
|
||||||
self.rolloverAt = self.computeRollover(int(time.time()))
|
if os.path.exists(filename):
|
||||||
|
t = os.stat(filename)[ST_MTIME]
|
||||||
|
else:
|
||||||
|
t = int(time.time())
|
||||||
|
self.rolloverAt = self.computeRollover(t)
|
||||||
|
|
||||||
def computeRollover(self, currentTime):
|
def computeRollover(self, currentTime):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright 2001-2010 by Vinay Sajip. All Rights Reserved.
|
# Copyright 2001-2010 by Vinay Sajip. All Rights Reserved.
|
||||||
#
|
#
|
||||||
|
@ -26,7 +26,6 @@ import logging.handlers
|
||||||
import logging.config
|
import logging.config
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
import copy
|
|
||||||
import pickle
|
import pickle
|
||||||
import io
|
import io
|
||||||
import gc
|
import gc
|
||||||
|
@ -36,7 +35,6 @@ import re
|
||||||
import select
|
import select
|
||||||
import socket
|
import socket
|
||||||
from socketserver import ThreadingTCPServer, StreamRequestHandler
|
from socketserver import ThreadingTCPServer, StreamRequestHandler
|
||||||
import string
|
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -44,8 +42,6 @@ from test.support import captured_stdout, run_with_locale, run_unittest,\
|
||||||
find_unused_port
|
find_unused_port
|
||||||
import textwrap
|
import textwrap
|
||||||
import threading
|
import threading
|
||||||
import time
|
|
||||||
import types
|
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
import warnings
|
||||||
import weakref
|
import weakref
|
||||||
|
@ -361,7 +357,7 @@ class CustomLevelsAndFiltersTest(BaseTest):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
BaseTest.setUp(self)
|
BaseTest.setUp(self)
|
||||||
for k, v in list(my_logging_levels.items()):
|
for k, v in my_logging_levels.items():
|
||||||
logging.addLevelName(k, v)
|
logging.addLevelName(k, v)
|
||||||
|
|
||||||
def log_at_all_levels(self, logger):
|
def log_at_all_levels(self, logger):
|
||||||
|
@ -831,7 +827,7 @@ class MemoryTest(BaseTest):
|
||||||
# Trigger cycle breaking.
|
# Trigger cycle breaking.
|
||||||
gc.collect()
|
gc.collect()
|
||||||
dead = []
|
dead = []
|
||||||
for (id_, repr_), ref in list(self._survivors.items()):
|
for (id_, repr_), ref in self._survivors.items():
|
||||||
if ref() is None:
|
if ref() is None:
|
||||||
dead.append(repr_)
|
dead.append(repr_)
|
||||||
if dead:
|
if dead:
|
||||||
|
@ -870,7 +866,7 @@ class EncodingTest(BaseTest):
|
||||||
# the non-ascii data we write to the log.
|
# the non-ascii data we write to the log.
|
||||||
data = "foo\x80"
|
data = "foo\x80"
|
||||||
try:
|
try:
|
||||||
handler = logging.FileHandler(fn, encoding="utf8")
|
handler = logging.FileHandler(fn, encoding="utf-8")
|
||||||
log.addHandler(handler)
|
log.addHandler(handler)
|
||||||
try:
|
try:
|
||||||
# write non-ascii data to the log.
|
# write non-ascii data to the log.
|
||||||
|
@ -879,7 +875,7 @@ class EncodingTest(BaseTest):
|
||||||
log.removeHandler(handler)
|
log.removeHandler(handler)
|
||||||
handler.close()
|
handler.close()
|
||||||
# check we wrote exactly those bytes, ignoring trailing \n etc
|
# check we wrote exactly those bytes, ignoring trailing \n etc
|
||||||
f = open(fn, encoding="utf8")
|
f = open(fn, encoding="utf-8")
|
||||||
try:
|
try:
|
||||||
self.assertEqual(f.read().rstrip(), data)
|
self.assertEqual(f.read().rstrip(), data)
|
||||||
finally:
|
finally:
|
||||||
|
@ -956,6 +952,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
# config0 is a standard configuration.
|
# config0 is a standard configuration.
|
||||||
config0 = {
|
config0 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -977,6 +974,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
# config1 adds a little to the standard configuration.
|
# config1 adds a little to the standard configuration.
|
||||||
config1 = {
|
config1 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1003,6 +1001,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
# config2 has a subtle configuration error that should be reported
|
# config2 has a subtle configuration error that should be reported
|
||||||
config2 = {
|
config2 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1029,6 +1028,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
#As config1 but with a misspelt level on a handler
|
#As config1 but with a misspelt level on a handler
|
||||||
config2a = {
|
config2a = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1056,6 +1056,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
#As config1 but with a misspelt level on a logger
|
#As config1 but with a misspelt level on a logger
|
||||||
config2b = {
|
config2b = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1082,6 +1083,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
# config3 has a less subtle configuration error
|
# config3 has a less subtle configuration error
|
||||||
config3 = {
|
config3 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1108,6 +1110,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
# config4 specifies a custom formatter class to be loaded
|
# config4 specifies a custom formatter class to be loaded
|
||||||
config4 = {
|
config4 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'()' : __name__ + '.ExceptionFormatter',
|
'()' : __name__ + '.ExceptionFormatter',
|
||||||
|
@ -1130,6 +1133,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
# As config4 but using an actual callable rather than a string
|
# As config4 but using an actual callable rather than a string
|
||||||
config4a = {
|
config4a = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'()' : ExceptionFormatter,
|
'()' : ExceptionFormatter,
|
||||||
|
@ -1163,6 +1167,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
# config5 specifies a custom handler class to be loaded
|
# config5 specifies a custom handler class to be loaded
|
||||||
config5 = {
|
config5 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1190,6 +1195,7 @@ class ConfigDictTest(BaseTest):
|
||||||
# config6 specifies a custom handler class to be loaded
|
# config6 specifies a custom handler class to be loaded
|
||||||
# but has bad arguments
|
# but has bad arguments
|
||||||
config6 = {
|
config6 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1218,6 +1224,7 @@ class ConfigDictTest(BaseTest):
|
||||||
#config 7 does not define compiler.parser but defines compiler.lexer
|
#config 7 does not define compiler.parser but defines compiler.lexer
|
||||||
#so compiler.parser should be disabled after applying it
|
#so compiler.parser should be disabled after applying it
|
||||||
config7 = {
|
config7 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1243,6 +1250,7 @@ class ConfigDictTest(BaseTest):
|
||||||
}
|
}
|
||||||
|
|
||||||
config8 = {
|
config8 = {
|
||||||
|
'version': 1,
|
||||||
'disable_existing_loggers' : False,
|
'disable_existing_loggers' : False,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
|
@ -1271,6 +1279,7 @@ class ConfigDictTest(BaseTest):
|
||||||
}
|
}
|
||||||
|
|
||||||
config9 = {
|
config9 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1296,6 +1305,7 @@ class ConfigDictTest(BaseTest):
|
||||||
}
|
}
|
||||||
|
|
||||||
config9a = {
|
config9a = {
|
||||||
|
'version': 1,
|
||||||
'incremental' : True,
|
'incremental' : True,
|
||||||
'handlers' : {
|
'handlers' : {
|
||||||
'hand1' : {
|
'hand1' : {
|
||||||
|
@ -1310,6 +1320,7 @@ class ConfigDictTest(BaseTest):
|
||||||
}
|
}
|
||||||
|
|
||||||
config9b = {
|
config9b = {
|
||||||
|
'version': 1,
|
||||||
'incremental' : True,
|
'incremental' : True,
|
||||||
'handlers' : {
|
'handlers' : {
|
||||||
'hand1' : {
|
'hand1' : {
|
||||||
|
@ -1325,6 +1336,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
#As config1 but with a filter added
|
#As config1 but with a filter added
|
||||||
config10 = {
|
config10 = {
|
||||||
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1358,6 +1370,68 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
#As config1 but using cfg:// references
|
#As config1 but using cfg:// references
|
||||||
config11 = {
|
config11 = {
|
||||||
|
'version': 1,
|
||||||
|
'true_formatters': {
|
||||||
|
'form1' : {
|
||||||
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'handler_configs': {
|
||||||
|
'hand1' : {
|
||||||
|
'class' : 'logging.StreamHandler',
|
||||||
|
'formatter' : 'form1',
|
||||||
|
'level' : 'NOTSET',
|
||||||
|
'stream' : 'ext://sys.stdout',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'formatters' : 'cfg://true_formatters',
|
||||||
|
'handlers' : {
|
||||||
|
'hand1' : 'cfg://handler_configs[hand1]',
|
||||||
|
},
|
||||||
|
'loggers' : {
|
||||||
|
'compiler.parser' : {
|
||||||
|
'level' : 'DEBUG',
|
||||||
|
'handlers' : ['hand1'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'root' : {
|
||||||
|
'level' : 'WARNING',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#As config11 but missing the version key
|
||||||
|
config12 = {
|
||||||
|
'true_formatters': {
|
||||||
|
'form1' : {
|
||||||
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'handler_configs': {
|
||||||
|
'hand1' : {
|
||||||
|
'class' : 'logging.StreamHandler',
|
||||||
|
'formatter' : 'form1',
|
||||||
|
'level' : 'NOTSET',
|
||||||
|
'stream' : 'ext://sys.stdout',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'formatters' : 'cfg://true_formatters',
|
||||||
|
'handlers' : {
|
||||||
|
'hand1' : 'cfg://handler_configs[hand1]',
|
||||||
|
},
|
||||||
|
'loggers' : {
|
||||||
|
'compiler.parser' : {
|
||||||
|
'level' : 'DEBUG',
|
||||||
|
'handlers' : ['hand1'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'root' : {
|
||||||
|
'level' : 'WARNING',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#As config11 but using an unsupported version
|
||||||
|
config13 = {
|
||||||
|
'version': 2,
|
||||||
'true_formatters': {
|
'true_formatters': {
|
||||||
'form1' : {
|
'form1' : {
|
||||||
'format' : '%(levelname)s ++ %(message)s',
|
'format' : '%(levelname)s ++ %(message)s',
|
||||||
|
@ -1573,13 +1647,19 @@ class ConfigDictTest(BaseTest):
|
||||||
def test_config11_ok(self):
|
def test_config11_ok(self):
|
||||||
self.test_config1_ok(self.config11)
|
self.test_config1_ok(self.config11)
|
||||||
|
|
||||||
|
def test_config12_failure(self):
|
||||||
|
self.assertRaises(Exception, self.apply_config, self.config12)
|
||||||
|
|
||||||
|
def test_config13_failure(self):
|
||||||
|
self.assertRaises(Exception, self.apply_config, self.config13)
|
||||||
|
|
||||||
def setup_via_listener(self, text):
|
def setup_via_listener(self, text):
|
||||||
|
text = text.encode("utf-8")
|
||||||
port = find_unused_port()
|
port = find_unused_port()
|
||||||
t = logging.config.listen(port)
|
t = logging.config.listen(port)
|
||||||
t.start()
|
t.start()
|
||||||
t.ready.wait()
|
t.ready.wait()
|
||||||
t.ready.clear()
|
t.ready.clear()
|
||||||
text = text.encode('utf-8')
|
|
||||||
try:
|
try:
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
sock.settimeout(2.0)
|
sock.settimeout(2.0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue