Repository navigation
feat(observability): correlate execution traces with Loki, incidents and mctl MCP #97
Description
Context
mctl-agent is the best home for the cross-signal correlation entry point because it already owns incident handling, operational MCP surfaces and structured logging, while mctl-agents owns Temporal/Argo execution state.
Relevant implementation points visible today include:
internal/mcp/server.gointernal/monitor/*internal/pipeline/*- existing structured logging via
slog
Related issues:
mctlhq/mctl-agent#38— OpenTelemetry tracing + token usagemctlhq/mctl-agents#195— end-to-end execution tracesmctlhq/mctl-agents#196— execution identity/runtime contextmctlhq/mctl-agents#199— auditable execution evidencemctlhq/mctl-gitops#902— OpenTelemetry Collector telemetry gatewaymctlhq/mctl-gitops#903— backend comparison (Traceway, Tempo, Langfuse, Phoenix, SigNoz) behind the Collector; not a Traceway POC
This issue should coordinate with mctl-agents where workflow-side log fields must be added, but the operator/incident/MCP correlation contract should live here.
Producer-side propagation in mctl-agents is owned by mctlhq/mctl-agents#195 and mctlhq/mctl-agents#196 and must not be reimplemented under this issue.
Dependencies
Depends on: mctlhq/mctl-agents#195 (end-to-end execution traces; this issue correlates spans that #195 and #38 emit). Part of roadmap epic mctlhq/.github#55, Phase 3.
Goal
Make it possible to move deterministically between:
incident / GitHub issue
↓
workflow execution
↓
trace / failed span
↓
related Loki logs
The long-term target is that an mctl incident investigator can start from an incident and programmatically discover the failed span and relevant logs without a human manually searching multiple systems.
Scope
Structured log correlation
Add/standardize correlation fields where available:
trace_idspan_idworkflow_nameand/orworkflow_idrun_id- incident/ticket ID where applicable
- GitHub issue/PR metadata where applicable
Use stable field names across mctl-agent and mctl-agents so Loki queries do not depend on service-specific naming.
Workflow → trace → Loki
Define and demonstrate the correlation path:
- start from workflow name/ID/run ID
- resolve trace ID / relevant execution span
- query related logs using trace/workflow identity
- identify failed/error spans and associated logs
Document the canonical query/navigation approach independently of the selected trace backend where possible.
Incident/evidence metadata
Where incidents or evidence records already carry workflow/execution metadata, add trace identity without duplicating full telemetry:
execution:
workflow_id: ...
run_id: ...
trace_id: ...Persist span_id only where it refers to a meaningful root/failure span; do not treat transient child span IDs as durable incident identity by default.
mctl operational / MCP interfaces
Where practical, expose trace_id (and workflow/run identifiers if missing) from operational MCP responses such as workflow/run/incident inspection so callers can pivot directly into observability data.
Do not make MCP responses depend on the trace backend being healthy. Stored/correlated identifiers should still be returned if Traceway/Tempo/etc. is unavailable.
Future investigator path
Validate the metadata model against this future autonomous flow:
mctl_get_incident(...)
→ workflow_id + trace_id
→ locate failed span
→ derive time window / service / pod
→ query Loki
→ feed relevant logs/evidence into investigator
Actual autonomous trace/Loki querying by an agent can be a follow-up; this issue establishes the correlation primitives and exposes the identifiers needed to make it possible.
Privacy / reliability
- Correlation must use IDs/metadata, not raw prompts/completions.
- Logging/tracing backend failures must not block incident or workflow processing.
- Avoid high-cardinality Loki labels for values like
trace_id; keep them as structured fields unless the existing Loki setup explicitly supports/indexes them safely.
Acceptance criteria
- Representative
mctl-agentlogs containtrace_id/span_idwhen emitted inside an active span. - Representative
mctl-agentsworkflow logs use the agreed workflow/run correlation fields through fix(api): log every Telegram callback press #195/feat(scoutspike): add the spike scaffold to drafts that omit it #196. - A workflow execution can be followed to its trace and from there to matching Loki logs using documented identifiers.
- Incident/evidence metadata includes
trace_idwhen a trace exists. - At least one mctl operational/MCP response exposes the relevant trace/workflow identity where practical.
- Correlation still degrades gracefully if the trace backend or Loki is unavailable.
- A concrete failed workflow/incident example demonstrates incident → workflow → failed span → related logs.
Non-goals
- Do not duplicate producer instrumentation already tracked in
mctlhq/mctl-agent#38ormctlhq/mctl-agents#195. - Do not reimplement execution identity/propagation owned by
mctlhq/mctl-agents#196. - Do not introduce a Traceway-specific correlation contract; identifiers and fields must remain OpenTelemetry/backend neutral.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
fix(observability): correlate the pipeline's failure-path log lines
mashkovd commentedon Oct 12, 2026
Evidence: organic failed incident → workflow → failed span → Loki (2026-10-12)
Recorded before the Tempo eval teardown (2026-10-24), because the trace store is temporary. Nothing here was manufactured. Both failures below happened organically on 2026-10-11, inside DevLoop runs that started after tracing was enabled.
Chain (AC 7)
argo-mctl-agents-implement-dae24112-1791756910(mctl-api,source=argo-workflows,type=workflow_failed, created 2026-10-11T22:15:10Z)mctl_list_incidents status=resolvedmctl-agents-implement-dae24112, phase Failed (child … assert-produced failed), 22:07:49Z → 22:15:16Z; DevLoopdev-loop-mctlhq-mctl-telegram-757, run01a12cf8-b7cb-700e-9d73-bf8f8aeab593(started 21:57:39Z)431486061c652efb376a860d9d656f25(80 spans)mctl_get_workflow_status mctl-agents-implement-dae24112→live.trace.trace_id(source: traceparent-argument), andaudit.parameters.traceparent = 00-431486061c652efb376a860d9d656f25-7a16c732dc164e9e-01argo.workflow mctl-agents-implement7a16c732dc164e9e(error.type=Failed) →implementer.run7a5cad2094fd54b9(exit_1) →invoke_agent implementer26c53dbda605f5f4(ImplementerOrphanedSubagent, 22:08:14Z) →execute_tool Bash8acf9997a91f7956(tool_error). Fallback attempt:implementer.runf2658bdce26b9a69→invoke_agentc27bb3b0b4b9d2c5(http_403) → chat span350b0c9a5933fc6f(oauth_org_not_allowed)GET /api/traces/431486061c652efb376a860d9d656f25through the Grafana datasource proxy (uidtempo-eval)P8E80F9AEF21F6940)The
github.api.readexit_1spans in this trace (5cc14bc48f2b1983,c23067abaea129e7) are the expected branch-existence 404 probe, as in #454. They are not used as the failure here.Loki lines, same service, pod and time window
Primary implementer pod,
{namespace="argo-workflows", pod="mctl-agents-implement-dae24112-run-implementer-3726176774"}, 22:07–22:15Z:The anchor's
span_idis exactly theimplementer.runspan that parents theImplementerOrphanedSubagentspan.Fallback pod,
pod="mctl-agents-implement-dae24112-run-implementer-1588491580", 22:13–22:16Z:Worker side,
{namespace=~"argo-workflows|admins"} |= "431486061c652efb376a860d9d656f25":Execution evidence carrying the same trace (mctl-api
execution_evidence.trace_id):ev-ac179ebd1ff4d73a,ev-78de6bcaf3fcde7d,ev-5cf567cbf8c92bab.A second organic instance has the same shape: incident
argo-mctl-agents-implement-af43e7b8-1791747930→ trace008ad8979d34c0509e74d8062b7f92ca(ImplementerOrphanedSubagent, then fallbackoauth_org_not_allowed).Other checks
mctl-agent:2.5.0with threeOTEL_*env vars since 2026-10-11T21:03:11Z. Two organic tickets since then, both traced, bothescalated(no error span):1ac833c4-5ed7-4c10-9471-6c2aa0a28af5→ac6c3b7f212ec9ac443529ddacc45078(3 spans);6ebe8c19-7b63-40ad-ace4-1a8bfc0b56f8→3b54b8b36a8a3334173dc4cad2458e83(4 spans,diagnosecpu_throttle).trace_id/span_idas JSON fields, andtickets.trace_idreads back from the store for both.ev-68a4a54f06903df7: the columntrace_idand the envelopeexecution.trace_idare both164ac97d8d7264326c406240d263dcc1(runtimeex-681b48cc77279413).AC status
trace_id/span_iddocs/observability/correlation.md), live abovetrace_idmctl_get_incidenton the incident above returns notrace_id, so the documented investigator pathmctl_get_incident → trace_iddoes not work yet. Follow-up to be filed.mctl_get_workflow_status)Remaining before close: the
mctl_get_incidenttrace_idfollow-up.mashkovd commentedon Oct 12, 2026
Follow-up for the remaining AC (incident metadata carries
trace_id): mctlhq/mctl-api#585. Once it is live andmctl_get_incident argo-mctl-agents-implement-dae24112-1791756910returns431486061c652efb376a860d9d656f25, this issue has no open acceptance gap.mashkovd commentedon Oct 13, 2026
Closing on the owner's decision.
mctl-agents-implement-dae24112. The evidence is in comment 6130090541: incident, then ERROR spans, then the Loki anchor.mctl_get_incidentreturning the trace id, was fixed by mctl-api#585, released in mctl-api 4.82.0. It was re-verified live on 4.82.2:mctl_get_incident argo-mctl-agents-implement-dae24112-1791756910returnstrace_id: 431486061c652efb376a860d9d656f25withtrace_source: workflow_audit.The Tempo evaluation (gitops#1280) is tracked separately and stays open until 2026-10-23.