mirror of https://github.com/python/cpython.git
bpo-33978: Close existing handlers before logging (re-)configuration. (GH-8008)
This commit is contained in:
parent
c6cd164cff
commit
087570af6d
|
@ -73,8 +73,8 @@ def fileConfig(fname, defaults=None, disable_existing_loggers=True):
|
||||||
# critical section
|
# critical section
|
||||||
logging._acquireLock()
|
logging._acquireLock()
|
||||||
try:
|
try:
|
||||||
logging._handlers.clear()
|
_clearExistingHandlers()
|
||||||
del logging._handlerList[:]
|
|
||||||
# Handlers add themselves to logging._handlers
|
# Handlers add themselves to logging._handlers
|
||||||
handlers = _install_handlers(cp, formatters)
|
handlers = _install_handlers(cp, formatters)
|
||||||
_install_loggers(cp, handlers, disable_existing_loggers)
|
_install_loggers(cp, handlers, disable_existing_loggers)
|
||||||
|
@ -265,6 +265,14 @@ def _install_loggers(cp, handlers, disable_existing):
|
||||||
# logger.disabled = 1
|
# logger.disabled = 1
|
||||||
_handle_existing_loggers(existing, child_loggers, disable_existing)
|
_handle_existing_loggers(existing, child_loggers, disable_existing)
|
||||||
|
|
||||||
|
|
||||||
|
def _clearExistingHandlers():
|
||||||
|
"""Clear and close existing handlers"""
|
||||||
|
logging._handlers.clear()
|
||||||
|
logging.shutdown(logging._handlerList[:])
|
||||||
|
del logging._handlerList[:]
|
||||||
|
|
||||||
|
|
||||||
IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
|
IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
|
||||||
|
|
||||||
|
|
||||||
|
@ -524,8 +532,7 @@ def configure(self):
|
||||||
else:
|
else:
|
||||||
disable_existing = config.pop('disable_existing_loggers', True)
|
disable_existing = config.pop('disable_existing_loggers', True)
|
||||||
|
|
||||||
logging._handlers.clear()
|
_clearExistingHandlers()
|
||||||
del logging._handlerList[:]
|
|
||||||
|
|
||||||
# Do formatters first - they don't refer to anything else
|
# Do formatters first - they don't refer to anything else
|
||||||
formatters = config.get('formatters', EMPTY_DICT)
|
formatters = config.get('formatters', EMPTY_DICT)
|
||||||
|
|
|
@ -1089,6 +1089,7 @@ class ConfigFileTest(BaseTest):
|
||||||
|
|
||||||
"""Reading logging config from a .ini-style config file."""
|
"""Reading logging config from a .ini-style config file."""
|
||||||
|
|
||||||
|
check_no_resource_warning = support.check_no_resource_warning
|
||||||
expected_log_pat = r"^(\w+) \+\+ (\w+)$"
|
expected_log_pat = r"^(\w+) \+\+ (\w+)$"
|
||||||
|
|
||||||
# config0 is a standard configuration.
|
# config0 is a standard configuration.
|
||||||
|
@ -1297,6 +1298,27 @@ class ConfigFileTest(BaseTest):
|
||||||
datefmt=
|
datefmt=
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# config 8, check for resource warning
|
||||||
|
config8 = r"""
|
||||||
|
[loggers]
|
||||||
|
keys=root
|
||||||
|
|
||||||
|
[handlers]
|
||||||
|
keys=file
|
||||||
|
|
||||||
|
[formatters]
|
||||||
|
keys=
|
||||||
|
|
||||||
|
[logger_root]
|
||||||
|
level=DEBUG
|
||||||
|
handlers=file
|
||||||
|
|
||||||
|
[handler_file]
|
||||||
|
class=FileHandler
|
||||||
|
level=DEBUG
|
||||||
|
args=("{tempfile}",)
|
||||||
|
"""
|
||||||
|
|
||||||
disable_test = """
|
disable_test = """
|
||||||
[loggers]
|
[loggers]
|
||||||
keys=root
|
keys=root
|
||||||
|
@ -1442,6 +1464,29 @@ def test_config7_ok(self):
|
||||||
# Original logger output is empty.
|
# Original logger output is empty.
|
||||||
self.assert_log_lines([])
|
self.assert_log_lines([])
|
||||||
|
|
||||||
|
def test_config8_ok(self):
|
||||||
|
|
||||||
|
def cleanup(h1, fn):
|
||||||
|
h1.close()
|
||||||
|
os.remove(fn)
|
||||||
|
|
||||||
|
with self.check_no_resource_warning():
|
||||||
|
fd, fn = tempfile.mkstemp(".log", "test_logging-X-")
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
# Replace single backslash with double backslash in windows
|
||||||
|
# to avoid unicode error during string formatting
|
||||||
|
if os.name == "nt":
|
||||||
|
fn = fn.replace("\\", "\\\\")
|
||||||
|
|
||||||
|
config8 = self.config8.format(tempfile=fn)
|
||||||
|
|
||||||
|
self.apply_config(config8)
|
||||||
|
self.apply_config(config8)
|
||||||
|
|
||||||
|
handler = logging.root.handlers[0]
|
||||||
|
self.addCleanup(cleanup, handler, fn)
|
||||||
|
|
||||||
def test_logger_disabling(self):
|
def test_logger_disabling(self):
|
||||||
self.apply_config(self.disable_test)
|
self.apply_config(self.disable_test)
|
||||||
logger = logging.getLogger('some_pristine_logger')
|
logger = logging.getLogger('some_pristine_logger')
|
||||||
|
@ -2022,6 +2067,7 @@ class ConfigDictTest(BaseTest):
|
||||||
|
|
||||||
"""Reading logging config from a dictionary."""
|
"""Reading logging config from a dictionary."""
|
||||||
|
|
||||||
|
check_no_resource_warning = support.check_no_resource_warning
|
||||||
expected_log_pat = r"^(\w+) \+\+ (\w+)$"
|
expected_log_pat = r"^(\w+) \+\+ (\w+)$"
|
||||||
|
|
||||||
# config0 is a standard configuration.
|
# config0 is a standard configuration.
|
||||||
|
@ -2896,6 +2942,35 @@ def test_config14_ok(self):
|
||||||
logging.warning('Exclamation')
|
logging.warning('Exclamation')
|
||||||
self.assertTrue(output.getvalue().endswith('Exclamation!\n'))
|
self.assertTrue(output.getvalue().endswith('Exclamation!\n'))
|
||||||
|
|
||||||
|
def test_config15_ok(self):
|
||||||
|
|
||||||
|
def cleanup(h1, fn):
|
||||||
|
h1.close()
|
||||||
|
os.remove(fn)
|
||||||
|
|
||||||
|
with self.check_no_resource_warning():
|
||||||
|
fd, fn = tempfile.mkstemp(".log", "test_logging-X-")
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"version": 1,
|
||||||
|
"handlers": {
|
||||||
|
"file": {
|
||||||
|
"class": "logging.FileHandler",
|
||||||
|
"filename": fn
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"handlers": ["file"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.apply_config(config)
|
||||||
|
self.apply_config(config)
|
||||||
|
|
||||||
|
handler = logging.root.handlers[0]
|
||||||
|
self.addCleanup(cleanup, handler, fn)
|
||||||
|
|
||||||
def setup_via_listener(self, text, verify=None):
|
def setup_via_listener(self, text, verify=None):
|
||||||
text = text.encode("utf-8")
|
text = text.encode("utf-8")
|
||||||
# Ask for a randomly assigned port (by using port 0)
|
# Ask for a randomly assigned port (by using port 0)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Closed existing logging handlers before reconfiguration via fileConfig
|
||||||
|
and dictConfig. Patch by Karthikeyan Singaravelan.
|
Loading…
Reference in New Issue