Skip to main content

Observability and resilience

Mecatl exposes metrics, traces, structured logs, and tool audit records. Its model-provider wrapper also handles transient failures and stalled streams.

ChannelPurpose
Prometheus metricsMeasure runs, turns, tools, tokens, and failures.
OpenTelemetry tracesFollow run, turn, and tool spans.
Structured diagnosticsReport lifecycle and degraded-mode conditions.
Tool audit recordsRecord each tool call and its timing.

Embedders choose and inject the sinks. The engine does not use a global logger.

Prometheus metrics​

In mecated, the admin listener serves /metrics at 127.0.0.1:9090 by default. The endpoint is unauthenticated, so keep it on a loopback address. mecak8s disables it by default. Embedders must provide their own recorder and exporter.

Run metrics use a bounded role label: main, subagent, member, parallel, usermodel, or child. Session IDs and model names do not appear in labels.

SeriesTypeLabelsMeasures
mecatl_runs_totalCounterstop, roleCompleted runs by stop reason
mecatl_turns_totalCounterroleCompleted model turns
mecatl_turn_empty_totalCounterroleNo-progress events
mecatl_events_totalCountertype, roleEmitted session events
mecatl_tool_calls_totalCountertool, error, roleTool calls
mecatl_tool_duration_secondsHistogramtool, roleTool latency
mecatl_tokens_totalCounterkind, roleInput, output, and cache tokens
mecatl_cache_hit_ratioGaugeroleCache-read tokens divided by input tokens
mecatl_active_runsGaugeroleActive runs
mecatl_permission_asks_totalCounterrolePermission requests
mecatl_session_load_failures_totalCounterclassConcealed store or snapshot load failures

The admin listener also serves:

PathContent
/debug/pprof/*Go CPU, heap, goroutine, allocation, mutex, and block profiles
/debug/varsSelected runtime/metrics values
/debug/flightrecorderThe in-memory execution trace ring

The flight recorder is enabled by default with an 8 MiB, five-second window. Mutex and block profiling require explicit flags because they add overhead.

mecatui performance endpoints​

mecatui --perf exposes the same endpoints through an owner-private UNIX socket by default. --perf-addr selects a loopback TCP address. Raw admin data remains outside model context and the session debugger.

--perf-mcp adds a read-only MCP server at /mcp. It summarizes runtime data for agent analysis and exposes raw profiles only as user-audience resource links. Mecatl refuses this option when the admin listener is not loopback.

OpenTelemetry traces​

Set --otlp-endpoint to enable run, turn, and tool spans. An empty endpoint disables tracing without affecting Prometheus metrics.

FlagDefaultPurpose
--otlp-endpointEmptySet the OTLP collector and enable tracing.
--otlp-protocolgrpcUse grpc or http.
--otlp-insecurefalseDisable TLS for a local collector.

Concurrent runs that share one sink also share its root span. Mecatl does not yet provide independent root correlation for those runs.

EventSink.Emit receives the run context so an embedder can parent telemetry to the originating request. Read trace data during the call, but do not retain the context or use its cancellation state to drop events.

Model-call resilience​

Mecatl can retry a transient provider failure while a model step remains precommit. It buffers reasoning, whitespace, tool assembly, usage, and other provider metadata until meaningful assistant text becomes visible or the step completes cleanly. A failure after that semantic boundary is terminal and is never replayed. Raw stream activity still resets the idle watchdog, so a precommit idle timeout can recover while a visible-stream idle timeout ends the step.

The server-owned recovery window and attempt cap apply to each model step. See Choose models and providers for defaults, cost implications, manual retry, and deployment links.

Prompt caching​

Provider-side prompt caching is enabled for Anthropic, OpenAI Responses, and OpenRouter. The current OpenAI Chat Completions route uses no cache dialect.

FlagDefaultPurpose
--no-prompt-cachefalseDisable provider caching.
--anthropic-cache-ttl1h on anthropic, openrouter-anthropic and toolhive-anthropic; API default (5m) elsewhereSet Anthropic cache breakpoints to 5m or 1h.

Use mecatl_tokens_total and mecatl_cache_hit_ratio to confirm cache use.

Failure diagnostics​

Retry decisions and breaker transitions go to structured diagnostics without raw errors or request content. The event log also receives sanitized network.attempt records. InspectSession {"view":"network"} returns bounded retry and terminal decisions without prompts, credentials, or response bodies. Each attempt also carries a bounded structural summary — whether the provider's protocol terminal was actually observed, and a closed outcome (complete, incomplete, stream error, or cancelled) — covering successful and cancelled streams as well as failures, so a session that finished without error but produced unexpected output can still be distinguished from one whose stream was cut off or errored in transport.

Structured diagnostics​

mecated writes diagnostics to stderr or journald. An embedded mecatui server writes to $XDG_STATE_HOME/mecatl/mecatui.log; a remote client discards local server diagnostics.

Session facts belong in the event stream. Diagnostics cover operational conditions that have no matching event, such as persistence failures, policy denials, instruction-fragment assembly failures, and degraded integrations.

When caller ownership is enforced, session-load failures look like NotFound to the caller. Operators receive only class=store|snapshot|unknown; logs and metrics omit the requested session, owner, storage key, path, raw error, and snapshot contents.

ClassOperator response
storeCheck backend health, credentials, TLS, connectivity, and timeouts.
snapshotCheck storage-integrity alerts and follow the backend's repair process.
unknownCheck the custom adapter's bounded diagnostics and add public failure classification.

OpenRouter's downstream provider.route is an event-stream fact, not a log entry. It can be absent on cache hits.

Tool call audit​

port.ToolCallRecorder receives one record per tool execution, including queue and execution time. With --store-dir, jsonlstore writes .tools.jsonl sidecars and feeds the tool count and duration metrics. See the session store extension point for record ownership and naming.

Anonymous product metrics​

Mecatl separately reports aggregate adoption metrics to Stacklok by default. These metrics include version, OS and architecture, a random installation ID, enabled feature families, provider family, binary name, and coarse counts and durations. Tool names are limited to built-ins or the category mcp.

The report excludes prompts, file paths, MCP server and tool names, session and run IDs, model IDs, and other free text. A one-time stderr notice appears before the first report.

Disable product metrics with any of these controls:

  • --product-metrics=false
  • MECATL_PRODUCT_METRICS=false
  • A truthy DO_NOT_TRACK value
  • telemetry.productMetrics.enabled: false in user-global settings

MECATL_PRODUCT_METRICS=true overrides DO_NOT_TRACK. Project settings cannot change the operator's choice. Use --product-metrics-dry-run to print the observations instead of sending them.

The Helm chart stores mecak8s's random installation ID in a ConfigMap and passes it as MECATL_PRODUCT_METRICS_INSTALL_ID, so it survives pod restarts without a persistent volume. Delete the ConfigMap to reset the ID, or disable reporting with one of the controls above.

What's next​