Skip to content

Commit

Permalink
Temporary logging is now shutdown when logging has been configured.
Browse files Browse the repository at this point in the history
Fixes #62005

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>
  • Loading branch information
s0undt3ch authored and Megan Wilhite committed May 5, 2022
1 parent 0bb5940 commit d5bfa7b
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog/62005.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Temporary logging is now shutdown when logging has been configured.
7 changes: 7 additions & 0 deletions salt/_logging/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ def shutdown_temp_handler():
if temp_handler is not None:
for handler in logging.root.handlers[:]:
if handler is temp_handler:
logging.root.handlers.remove(handler)
handler.sync_with_handlers(logging.root.handlers)
handler.close()
break
# Redefine the handler to None so it can be garbage collected
Expand Down Expand Up @@ -970,8 +972,13 @@ def setup_logging():
if opts.get("configure_granular_levels", True):
setup_log_granular_levels(opts["log_granular_levels"])

# Any logging that should be configured, is configured by now. Shutdown the temporary logging handler.
shutdown_temp_handler()


def shutdown_logging():
if is_temp_handler_configured():
shutdown_temp_handler()
if is_extended_logging_configured():
shutdown_extended_logging()
if is_logfile_handler_configured():
Expand Down
8 changes: 3 additions & 5 deletions salt/utils/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,11 +673,9 @@ def process_log_level(self):
)

def __shutdown_logging(self):
# In case we never got logging properly set up
temp_log_handler = salt._logging.get_temp_handler()
if temp_log_handler is not None:
temp_log_handler.flush()
salt._logging.shutdown_temp_handler()
salt._logging.shutdown_logging()
sys.stdout.flush()
sys.stderr.flush()

def process_log_file(self):
if not getattr(self.options, self._logfile_config_setting_name_, None):
Expand Down
74 changes: 74 additions & 0 deletions tests/pytests/integration/modules/test_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import logging
import subprocess

import pytest
from _pytest.outcomes import Failed
from _pytest.pytester import LineMatcher

log = logging.getLogger(__name__)


def test_logging_and_state_output_order(salt_master, salt_minion, salt_cli, tmp_path):
"""
This tests for any regressions for this issue:
https://github.com/saltstack/salt/issues/62005
"""
target_path = tmp_path / "file-target.txt"
sls_name = "file-target"
sls_contents = """
add_contents_pillar_sls:
file.managed:
- name: {}
- contents: foo
""".format(
target_path
)
sls_tempfile = salt_master.state_tree.base.temp_file(
"{}.sls".format(sls_name), sls_contents
)
with sls_tempfile:
# Get the command line to use
cmdline = salt_cli.cmdline(
"-ldebug", "state.sls", sls_name, minion_tgt=salt_minion.id
)
assert cmdline
# Use subprocess.run since we want the output of stdout(state output) and stderr(logging)
# mixed so we can check for the order
ret = subprocess.run(
cmdline,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
check=False,
shell=False,
universal_newlines=True,
)
assert ret.stdout
assert not ret.stderr
log.debug("STDOUT:\n>>>>>>>>\n%s\n<<<<<<<\n", ret.stdout)
matcher = LineMatcher(ret.stdout.splitlines())
assert ret.returncode == 0
assert target_path.is_file()
# Check for proper order of state output and logging
try:
# This output order should not match and should trigger a _pytest.outcomes.Failed exception
matcher.fnmatch_lines(
[
'"{}":*'.format(salt_minion.id),
'"file_*',
"*Reading configuration from*",
]
)
except Failed:
# We caught the expected failure regarding the output matching above,
# nonetheless, let's confirm proper output order
matcher.fnmatch_lines(
[
# Confirm we have logging going on...
"*Reading configuration from*",
# And that after logging, we have the state output
'"{}":*'.format(salt_minion.id),
'"file_*',
]
)
else:
pytest.fail("The state and logging output order is wrong")

0 comments on commit d5bfa7b

Please sign in to comment.