fix: reduce startup log noise and surface only relevant plugin mappings (#1573)

* fix: reduce startup log noise and surface only relevant plugin mappings

Move the full plugin registry to DEBUG; at INFO log only the scenario
types configured for the current run. Warn when a configured type has
no matching plugin. Clean up redundant newlines, fix incorrect count
(now uses loaded_plugins count), and guard the reverse-map build
behind isEnabledFor(DEBUG) to skip unnecessary work at INFO level.

Signed-off-by: Darshan Jain <ddjain@redhat.com>
Signed-off-by: ddjain <darjain@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: address review — move run-specific log after triggers, guard DEBUG

Move the "Scenario plugins for this run" log block after trigger
evaluation so it reflects the actual scenarios that will execute
(triggers with on_timeout=skip can clear chaos_scenarios).

Guard the HealthCheckFactory DEBUG log with isEnabledFor(DEBUG) and
use %s formatting to avoid eager f-string evaluation at default
log levels, matching the pattern used for the scenario registry.

Signed-off-by: Darshan Jain <ddjain@redhat.com>
Signed-off-by: ddjain <darjain@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Signed-off-by: Darshan Jain <ddjain@redhat.com>
Signed-off-by: ddjain <darjain@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Darshan Jain
2026-08-18 12:50:27 +05:30
committed by GitHub
co-authored by Cursor
parent 7c1033589c
commit c765040d89
+45 -30
View File
@@ -404,49 +404,50 @@ def main(options, command: Optional[str], out: Optional[dict] = None) -> int:
chaos_telemetry.tag = elastic_run_tag
scenario_plugin_factory = ScenarioPluginFactory()
health_check_factory = HealthCheckFactory()
classes_and_types: dict[str, list[str]] = {}
for loaded in scenario_plugin_factory.loaded_plugins.keys():
if (
scenario_plugin_factory.loaded_plugins[loaded].__name__
not in classes_and_types.keys()
):
classes_and_types[
scenario_plugin_factory.loaded_plugins[loaded].__name__
] = []
classes_and_types[
scenario_plugin_factory.loaded_plugins[loaded].__name__
].append(loaded)
# Log loaded/failed plugin counts (INFO)
logging.info(
"📣 `ScenarioPluginFactory`: types from config.yaml mapped to respective classes for execution:"
f"📣 `ScenarioPluginFactory`: {len(scenario_plugin_factory.loaded_plugins)} scenario types loaded"
f" ({len(scenario_plugin_factory.failed_plugins)} failed)"
)
for class_loaded in classes_and_types.keys():
if len(classes_and_types[class_loaded]) <= 1:
logging.info(
f" ✅ type: {classes_and_types[class_loaded][0]} ➡️ `{class_loaded}` "
)
else:
logging.info(
f" ✅ types: [{', '.join(classes_and_types[class_loaded])}] ➡️ `{class_loaded}` "
)
logging.info("\n")
if len(scenario_plugin_factory.failed_plugins) > 0:
logging.info("Failed to load Scenario Plugins:\n")
for failed in scenario_plugin_factory.failed_plugins:
module_name, class_name, error = failed
logging.error(f"⛔ Class: {class_name} Module: {module_name}")
logging.error(f"⚠️ {error}\n")
logging.error(f"⚠️ {error}")
# Log loaded health check plugins
# Full plugin registry at DEBUG for troubleshooting
if logging.getLogger().isEnabledFor(logging.DEBUG):
classes_and_types: dict[str, list[str]] = {}
for loaded in scenario_plugin_factory.loaded_plugins.keys():
cls_name = scenario_plugin_factory.loaded_plugins[loaded].__name__
if cls_name not in classes_and_types:
classes_and_types[cls_name] = []
classes_and_types[cls_name].append(loaded)
logging.debug("Full plugin registry:")
for class_loaded, types in classes_and_types.items():
if len(types) <= 1:
logging.debug(f" type: {types[0]} ➡️ `{class_loaded}`")
else:
logging.debug(
f" types: [{', '.join(types)}] ➡️ `{class_loaded}`"
)
# Log health check plugins
logging.info(
"📣 `HealthCheckFactory`: Available health check plugins: "
f"{list(health_check_factory.loaded_plugins.keys())}"
f"📣 `HealthCheckFactory`: {len(health_check_factory.loaded_plugins)} health check plugins loaded"
f" ({len(health_check_factory.failed_plugins)} failed)"
)
if logging.getLogger().isEnabledFor(logging.DEBUG):
logging.debug(
"Available health check plugins: %s",
list(health_check_factory.loaded_plugins.keys()),
)
if len(health_check_factory.failed_plugins) > 0:
logging.info("Failed to load Health Check Plugins:\n")
for failed in health_check_factory.failed_plugins:
module_name, class_name, error = failed
logging.error(f"⛔ Class: {class_name} Module: {module_name}")
logging.error(f"⚠️ {error}\n")
logging.error(f"⚠️ {error}")
# Evaluate top-level triggers before starting health checks or chaos
trigger_config = config.get("triggers")
@@ -478,6 +479,20 @@ def main(options, command: Optional[str], out: Optional[dict] = None) -> int:
logging.error("invalid trigger configuration: %s", e)
return 1
# Log run-specific plugin mappings (after triggers may have cleared chaos_scenarios)
configured_types: set[str] = set()
for scenario in chaos_scenarios:
if isinstance(scenario, dict):
configured_types.add(list(scenario.keys())[0])
if configured_types:
logging.info("Scenario plugins for this run:")
for stype in sorted(configured_types):
if stype in scenario_plugin_factory.loaded_plugins:
cls_name = scenario_plugin_factory.loaded_plugins[stype].__name__
logging.info(f"{stype} ➡️ `{cls_name}`")
else:
logging.warning(f" ⚠️ {stype} ➡️ no matching plugin found")
# Start all health check plugins discovered via config_key_map.
# Returns list of (plugin, worker_thread, telemetry_queue);
# worker_thread is None for self-threading plugins (e.g. virt).