fix(profiling): let the task recap reach past the twenty slowest

ansible.cfg enables profile_tasks, whose output_limit defaults to 20. On a deploy round of this size the recap therefore cut off at 66.07s and printed nothing below, so a role whose cost is spread over many cheap tasks could not be attributed at all: in run 33828309745 that left 22.7 of sys-svc-compose 51.9 minutes unexplained, and the same blind spot covers web-app-nextcloud and web-app-keycloak almost entirely.

The callback accepts all, which disables the cap, but the recap prints one line per task execution and pass 1 alone ran over 7500 of them. Since the Actions worker dies silently on ENOSPC while writing its own logs, which is why utils/tests/swarm/matrix.py aborts a step at DISK_FLOOR_MB, the limit stays bounded at 300: about 600 extra lines across both passes.

Measured with a 30-task play: 30 recap entries with this config, 20 with the upstream default forced through PROFILE_TASKS_TASK_OUTPUT_LIMIT. The lint pins the setting so removing the section cannot silently restore the truncation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5 committed 2026-09-04 16:45:44 +02:00
1 parent 988d7ef11c
commit bbfd82f893
2 files changed
+54

No files matched your search

+3
View File
@@ -25,6 +25,9 @@ lookup_plugins = ./plugins/lookup
library = ./library
module_utils = ./utils
[callback_profile_tasks]
task_output_limit = 300
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=20s -o ControlPath=~/.ssh/ansible-%h-%p-%r -o ServerAliveInterval=15 -o ServerAliveCountMax=3 -o StrictHostKeyChecking=accept-new -o PreferredAuthentications=publickey,password,keyboard-interactive
pipelining = True
@@ -0,0 +1,51 @@
"""Lint check: the task profiler must not truncate its summary to the default.
``ansible.cfg`` enables ``profile_tasks``, whose ``output_limit`` defaults to
20. A deploy round of this size then reports only the twenty slowest tasks and
prints nothing below them, so any role whose cost is spread over many cheap
tasks cannot be attributed at all: in run 33828309745 the recap cut off at
66.07s, leaving 22.7 of ``sys-svc-compose``'s 51.9 minutes unaccounted.
The limit stays bounded rather than ``all`` because the recap prints one line
per task execution and the Actions worker dies silently on ENOSPC while writing
its own logs, which is the same reason ``utils/tests/swarm/matrix.py`` aborts a
step at ``DISK_FLOOR_MB``.
"""
from __future__ import annotations
import configparser
import unittest
from utils import PROJECT_ROOT
CONFIG = PROJECT_ROOT / "ansible.cfg"
SECTION = "callback_profile_tasks"
KEY = "task_output_limit"
DEFAULT_LIMIT = 20
class TestProfileTasksOutputLimit(unittest.TestCase):
def setUp(self) -> None:
self.parser = configparser.ConfigParser()
self.parser.read(CONFIG)
def test_the_profiler_is_enabled(self) -> None:
enabled = self.parser.get("defaults", "callbacks_enabled", fallback="")
self.assertIn("profile_tasks", enabled)
def test_the_summary_is_not_left_at_the_default_limit(self) -> None:
self.assertTrue(
self.parser.has_option(SECTION, KEY),
f"ansible.cfg must set [{SECTION}] {KEY}; without it the recap "
f"stops after {DEFAULT_LIMIT} tasks and the cost of a role spread "
"over many cheap tasks cannot be attributed",
)
value = self.parser.get(SECTION, KEY).strip()
if value == "all":
return
self.assertGreater(int(value), DEFAULT_LIMIT)
if __name__ == "__main__":
unittest.main()