Skip to content

fix(k8s-statefulset/daemonset-healthcheck): tasks that end with no report output - #783

Open
answersamir wants to merge 3 commits into
mainfrom
lazarus-sts-no-output
Open

answersamir wants to merge 3 commits into
mainfrom
lazarus-sts-no-output

Conversation

@answersamir

Copy link
Copy Markdown
Contributor

Problem

On the lazarus ring, four default k8s-statefulset-healthcheck tasks record no output on healthy StatefulSets. Skill Builder batch ae8711cb7ea5 scored 11 plan steps as data gaps because of it. Across the batch's 15 run sessions (12 StatefulSet SLXs):

Task Result on main Robot error
Check for Container Restarts FAIL 12/12 json.loads(r'''No containers with restarts found for StatefulSet … in the last 10m.''') → JSONDecodeError
Analyze Application Log Patterns FAIL 6/6 Variable '${LOG_PATTERN_CATEGORIES_STR}' not found
Detect Log Anomalies FAIL 1/1 Value of variable '@{issue["next_steps"]}' is not list or list-like
Inspect StatefulSet Replicas PASS 12/12, empty report (the healthy path never calls Add Pre To Report)

RBAC, the kubeconfig and the runner upload all work: other tasks in the same run requests uploaded output.

Causes and fixes

Check for Container Restarts

  • Cause: container_restarts.sh prints plain text when nothing restarted, and narrative lines before the JSON when something did. The runbook runs json.loads() on stdout, so the task fails in both cases. It never raises a real restart issue.
  • Fix: the narrative now goes to stderr, and stdout is always a JSON array. The runbook parses it defensively and raises an "Output Unreadable" issue when it cannot. It always adds a summary (window, threshold, issue count, narrative) to the report. It also defines ${issue_timestamp} on the script-failure path, where it was undefined.

Inspect StatefulSet Replicas

  • Cause: the healthy path adds nothing to the report.
  • Fix: the task always reports desired/ready/current/updated. It raises "Unable to Inspect StatefulSet Replicas" when kubectl … | jq returns nothing. There is no pipefail, so a Forbidden get used to exit 0 and pass silently.

Analyze Application Log Patterns

  • Fix: Set Suite Variable ${LOG_PATTERN_CATEGORIES_STR}, which is what k8s-deployment-healthcheck already does.

Detect Log Anomalies

  • Cause: RW.K8sLog.Analyze Log Anomalies returns next_steps as a newline-joined string.
  • Fix: join it only when it is a list.

Restart script, second commit

  • Cause: GNU date -d "10m ago" is invalid, so THRESHOLD_TIME was empty and CONTAINER_RESTART_AGE was ignored. Any restart in a pod's lifetime counted.
  • Fix: expand the m/h suffix the way k8s-deployment-healthcheck does. A failed kubectl get statefulset or get pods now exits 1, so the runbook raises "Container Restart Analysis Failed" instead of reading [] as "no restarts".

k8s-daemonset-healthcheck, third commit

  • Cause: this bundle is a copy and fails the same three ways (restarts, log patterns, anomalies). Its status task already reports.
  • Fix: the same changes, ported.

Testing

I ran runbook.robot in a Debian container with rw-core-keywords in production mode, so it writes report.jsonl and issues.jsonl. A stub kubectl replayed the real rw-lazarus-vault StatefulSet and pod JSON captured from lazarus, plus synthetic logs and restart variants.

Fixture main this branch
healthy StatefulSet 3 FAIL + Replicas empty; error text identical to lazarus 10/10 PASS, every task writes a report line
exit 137, 2 min ago Restarts FAIL (json.loads on narrative + JSON) PASS, 1 issue
exit 137, 2 h ago, CONTAINER_RESTART_AGE=10m — PASS, 0 issues (the window is honoured)
CONTAINER_RESTART_AGE=2d — "Container Restart Analysis Failed" issue (unsupported unit)
every get/logs Forbidden Replicas and Restarts PASS silently both raise issues
the same objects presented as a DaemonSet the same 3 failures 10/10 PASS with output

Not changed (pre-existing, RBAC-only):

  • Under Forbidden, the two log tasks still fail, because Fetch Workload Logs raises.
  • Under Forbidden, the probe and PVC tasks pass empty.
  • Under Forbidden, Inspect DaemonSet Status reports Ready=0/0 without an issue.

…tput

Four tasks in this bundle produced no task output on healthy StatefulSets:

- Check for Container Restarts: container_restarts.sh printed plain text
  when nothing restarted, and narrative lines before the JSON when
  something did; the runbook json.loads()-ed stdout and failed either way.
  The script now writes the narrative to stderr and always prints a JSON
  array; the runbook parses it defensively, raises an issue when it cannot,
  defines issue_timestamp on the script-failure path, and always adds a
  summary to the report.
- Inspect StatefulSet Replicas: the healthy path added nothing to the
  report. It now always reports the replica counts, and raises an issue
  when kubectl | jq returns nothing (no pipefail, so a failed get exits 0).
- Analyze Application Log Patterns: LOG_PATTERN_CATEGORIES_STR was never
  made a suite variable, so the summary line failed after issues were raised.
- Detect Log Anomalies: RW.K8sLog returns next_steps as a string; the
  runbook expanded it as a list and failed whenever an anomaly was found.
…il on unreadable pods

- GNU date rejects "10m ago" / "3h ago", so THRESHOLD_TIME was empty and
  the restart window was ignored: any restart in the pod's lifetime counted.
  Expand the m/h suffix the same way k8s-deployment-healthcheck does.
- A failed kubectl get statefulset / get pods (e.g. Forbidden) produced
  "[]", which read as "no restarts". Exit non-zero instead so the runbook
  raises "Container Restart Analysis Failed".
… fixes

k8s-daemonset-healthcheck is a copy of the StatefulSet bundle and fails the
same way: Check for Container Restarts json.loads() plain text, Analyze
Application Log Patterns hits the missing LOG_PATTERN_CATEGORIES_STR suite
variable, and Detect Log Anomalies expands the next_steps string as a list.
Port both StatefulSet commits (stdout is a JSON array, narrative on stderr,
defensive parsing, restart-age unit expansion, kubectl rc checks).
Inspect DaemonSet Status already reports on the healthy path.
@answersamir
answersamir requested a review from a team as a code owner October 28, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant