Skip to content
Last9
Book demo

goose

Send goose (the aaif open-source AI coding agent) telemetry — traces, metrics, and logs — to Last9 via OpenTelemetry.

goose is an aaif open-source AI coding agent. It emits structured OpenTelemetry data for every session: agent reply spans, model provider calls, tool dispatches, session token counts, and duration. Routing this to Last9 lets you measure adoption, model latency, cost, and tool reliability — within your existing observability stack.

goose exports all three OpenTelemetry signal types:

  • Traces — spans covering reply, reply_stream, complete, stream_response_from_provider, dispatch_tool_call, plus events like WAITING_LLM_STREAM_START/END
  • Metrics — derived from monotonic_counter.* attributes on log events; instrumented via tracing-opentelemetry
  • Logs — session events with token counts, duration, exit type, message count

Default temporality is cumulative, so metrics ingest cleanly into Last9 without conversion.

What gets exported

Spans

SpanWhen
replyTop-level session reply (carries user_message, trace_input, session.id)
reply_streamStreaming response loop
stream_response_from_providerSingle LLM streaming call (events: WAITING_LLM_STREAM_START, WAITING_LLM_STREAM_END)
completeProvider completion call (carries gen_ai.request.model)
dispatch_tool_callSingle tool invocation (carries input, output, session.id)

Session counters (emitted as log attributes)

AttributeDescription
monotonic_counter.goose.session_tokensTotal tokens consumed in the session
monotonic_counter.goose.session_duration_msTotal session wall time
monotonic_counter.goose.session_completionsNumber of completed sessions

These counters propagate as native OTel metrics when tracing-opentelemetry’s MetricsLayer is active.

Prerequisites

  1. Last9 account — Sign up at app.last9.io
  2. goose installedbrew install block-goose-cli or follow install docs
  3. OTLP credentials — Get your endpoint and auth header from Integrations → OpenTelemetry

Setup

goose honors the standard OpenTelemetry SDK environment variables — no custom prefix.

  1. Get your Last9 OTLP credentials

    Navigate to Integrations → OpenTelemetry in your Last9 dashboard. Copy:

    • OTLP Endpoint (e.g., https://otlp.last9.io or https://otlp-aps1.last9.io:443)
    • Authorization header value (e.g., Basic <base64-token>)
  2. Add environment variables to your shell profile

    Append the following to ~/.zshrc, ~/.bashrc, or equivalent:

    export OTEL_EXPORTER_OTLP_ENDPOINT="https://<your-last9-otlp-endpoint>"
    export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic <your-last9-auth-token>"
    export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
    export OTEL_SERVICE_NAME=goose
    export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=local"
  3. Reload your shell

    source ~/.zshrc
  4. Run goose

    goose session

    Or non-interactively:

    goose run -t "explain this file"
  5. Verify data is arriving

    • Traces — open Traces in Last9, filter by service.name = goose. Look for reply, complete, stream_response_from_provider span names
    • Metrics — open Metrics, search for goose_session_tokens or goose_session_duration_ms
    • Logs — open Logs, filter by service.name = goose. Session events include total_tokens, duration_ms, exit_type

Configuration reference

Core

VariableDescription
OTEL_EXPORTER_OTLP_ENDPOINTBase OTLP endpoint (SDK appends /v1/traces, etc.)
OTEL_EXPORTER_OTLP_HEADERSkey=value comma-separated auth headers
OTEL_EXPORTER_OTLP_PROTOCOLgrpc, http/protobuf, or http/json
OTEL_SERVICE_NAMEService name override (defaults to goose)
OTEL_RESOURCE_ATTRIBUTESComma-separated key=value resource tags
OTEL_SDK_DISABLEDSet true to disable all OTel export

Per-signal control

VariableDescription
OTEL_TRACES_EXPORTERotlp, console, none
OTEL_METRICS_EXPORTERotlp, console, none
OTEL_LOGS_EXPORTERotlp, console, none
OTEL_EXPORTER_OTLP_TRACES_ENDPOINTTraces-only endpoint override
OTEL_EXPORTER_OTLP_METRICS_ENDPOINTMetrics-only endpoint override
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTLogs-only endpoint override

Sampling and tuning

VariableDescription
OTEL_TRACES_SAMPLERparentbased_traceidratio, always_on, etc.
OTEL_TRACES_SAMPLER_ARGSampling ratio (e.g. 0.1 for 10%)
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCEcumulative (default), delta, or lowmemory
OTEL_EXPORTER_OTLP_TIMEOUTExport timeout in milliseconds

Anonymous usage data (separate from OTel)

VariableDescription
GOOSE_TELEMETRY_ENABLEDEnable/disable goose’s anonymous usage data collection (separate from the OpenTelemetry export above)

Configuration via goose config file

Alternatively, configure via ~/.config/goose/config.yaml:

otel_exporter_otlp_endpoint: "https://<your-last9-otlp-endpoint>"
otel_exporter_otlp_timeout: 30

Environment variables take precedence over config file values.

What you can do in Last9

Model latency tracking (traces)

stream_response_from_provider span duration is end-to-end LLM call latency. Filter by gen_ai.request.model to compare providers/models. p95/p99 over time catches degradation:

histogram_quantile(0.95,
sum by (le, gen_ai_request_model) (rate(traces_span_metrics_duration_milliseconds_bucket{ServiceName="goose",SpanName="stream_response_from_provider"}[5m]))
)

Token consumption (logs / metrics)

Per-session token counters are emitted as log attributes (monotonic_counter.goose.session_tokens). Aggregate via Last9 logs panel or convert to a metric. Sum over a time window for daily/weekly totals.

Session duration distribution (logs / metrics)

monotonic_counter.goose.session_duration_ms plus the structured log fields (exit_type, message_count, total_tokens) let you find long-running sessions or sessions that exited abnormally.

Tool reliability (traces)

dispatch_tool_call spans carry input, output, and session.id. Filter for failed spans (StatusCode=ERROR) to spot tool errors. Group by tool name from span attributes.

Session replay via session.id (traces + logs)

Every span and log carries session.id. Filter by it to reconstruct a single goose session — agent loop, model calls, tool dispatches — in trace order.

Sampling tip

For high-volume environments, sample 10% of traces to reduce volume:

export OTEL_TRACES_SAMPLER="parentbased_traceidratio"
export OTEL_TRACES_SAMPLER_ARG="0.1"

Counters and logs continue at full rate; only trace volume reduces.


Troubleshooting

  • No data in Last9

    • Confirm echo $OTEL_EXPORTER_OTLP_ENDPOINT in the same shell where you run goose. Restart the shell after editing ~/.zshrc.
    • Verify OTEL_SDK_DISABLED is not set to true.
  • 401 / authentication errors

    • Header format must be Authorization=Basic <token> (key=value, not HTTP colon syntax)
    • Regenerate the token from Integrations → OpenTelemetry if it has expired
  • Service name appears as unknown_service

    • Set OTEL_SERVICE_NAME=goose explicitly. goose’s resource builder defaults to goose but env vars take precedence.
  • High trace volume

    • Set OTEL_TRACES_SAMPLER=parentbased_traceidratio and OTEL_TRACES_SAMPLER_ARG=0.1 to sample 10% of traces
  • goose anonymous telemetry vs OpenTelemetry export

    • These are separate. GOOSE_TELEMETRY_ENABLED controls goose’s built-in anonymous usage data collection. The OTEL_* vars control the OpenTelemetry export to your collector. You can run both, neither, or just one.

Please get in touch with us on Discord or Email if you have any questions.