Skip to content

feat(otel): respect standard OTel env vars for exporter selection#7144

Merged
codefromthecrypt merged 7 commits intomainfrom
adrian/otel-env
Feb 14, 2026
Merged

feat(otel): respect standard OTel env vars for exporter selection#7144
codefromthecrypt merged 7 commits intomainfrom
adrian/otel-env

Conversation

@codefromthecrypt
Copy link
Collaborator

@codefromthecrypt codefromthecrypt commented Feb 11, 2026

Summary

Respect standard OpenTelemetry environment variables for per-signal exporter selection (OTEL_TRACES_EXPORTER, OTEL_METRICS_EXPORTER, OTEL_LOGS_EXPORTER, OTEL_SDK_DISABLED) and signal-specific endpoints (OTEL_EXPORTER_OTLP_{SIGNAL}_ENDPOINT). Supports otlp, console, and none exporter types.

  • New otel module (crates/goose/src/otel/) — OTel code moves out of tracing/ since it covers traces, metrics, and logs
  • otel::otlp exposes signal_exporter(signal) that checks env vars in priority order: SDK disabled → per-signal exporter → signal-specific endpoint → generic endpoint
  • init_otlp_layers(&Config) replaces duplicated setup in CLI and server — creates all signal layers, promotes config to env, and sets propagation in one call
  • promote_config_to_env takes &Config instead of reading Config::global(), making it testable with temp config files
  • Server now calls shutdown_otlp() on graceful shutdown (CLI already did)
  • Propagation (TraceContextPropagator) only set when at least one OTLP layer initializes
  • Documentation updated with per-signal pattern and examples

Type of Change

  • Feature
  • Refactor / Code quality
  • Tests

AI Assistance

  • This PR was created or reviewed with AI assistance

Testing

Build the release binary once (used for all tests below):

just release-binary

Console exporter

All three signals (logs, traces, metrics) show the overridden service.name=mygoose and deployment.environment=staging:

$ OTEL_TRACES_EXPORTER=console OTEL_METRICS_EXPORTER=console OTEL_LOGS_EXPORTER=console \
  OTEL_RESOURCE_ATTRIBUTES="service.name=mygoose,deployment.environment=staging" \
  ./target/release/goose run -t "hello"
Logs
Resource
	 ->  service.version=String(Static("1.23.0"))
	 ->  service.namespace=String(Static("goose"))
	 ->  service.name=String(Owned("mygoose"))
	 ->  telemetry.sdk.language=String(Static("rust"))
	 ->  telemetry.sdk.version=String(Static("0.31.0"))
	 ->  deployment.environment=String(Owned("staging"))
	 ->  telemetry.sdk.name=String(Static("opentelemetry"))
Log #0
	 Instrumentation Scope: InstrumentationScope { name: "", version: None, schema_url: None, attributes: [] }
	 EventName: "event crates/goose-cli/src/cli.rs:1439"
	 Target (Scope): "goose_cli::cli"
	 Observed Timestamp: 2026-02-12 00:19:50.218406
	 SeverityText: "INFO"
	 SeverityNumber: Info
	 Body: String(Owned("CLI command executed"))
	 Attributes:
		 ->  counter.goose.cli_commands: Int(1)
		 ->  command: String(Owned("run"))
starting session | provider: openai model: gpt-5-nano
...
Spans
Resource
	 ->  deployment.environment=String(Owned("staging"))
	 ->  service.version=String(Static("1.23.0"))
	 ->  telemetry.sdk.name=String(Static("opentelemetry"))
	 ->  telemetry.sdk.language=String(Static("rust"))
	 ->  telemetry.sdk.version=String(Static("0.31.0"))
	 ->  service.name=String(Owned("mygoose"))
	 ->  service.namespace=String(Static("goose"))
Span #0
	Instrumentation Scope
		Name         : "goose"

	Name         : reply
	TraceId      : 901566482c18f071c8e4f8ce03cdc03e
	SpanId       : 536d84d47658d3c6
	TraceFlags   : TraceFlags(1)
	ParentSpanId : None (root span)
	Kind         : Internal
	Attributes:
		 ->  user_message: String(Owned("hello"))
		 ->  trace_input: String(Owned("hello"))
...
Metrics
Resource
	 ->  service.name=String(Owned("mygoose"))
	 ->  service.version=String(Static("1.23.0"))
	 ->  telemetry.sdk.language=String(Static("rust"))
	 ->  service.namespace=String(Static("goose"))
	 ->  telemetry.sdk.version=String(Static("0.31.0"))
	 ->  deployment.environment=String(Owned("staging"))
	 ->  telemetry.sdk.name=String(Static("opentelemetry"))
	Instrumentation Scope #0
		Name         : tracing/tracing-opentelemetry
		Version  : "0.32.1"
Metric #0
		Name         : goose.cli_commands
		Description  :
		Unit         :
		Type         : Sum
		Sum DataPoints
		Monotonic    : false
		Temporality  : Cumulative
		DataPoint #0
			Value        : 1
			Attributes   :
				 ->  message: CLI command executed
				 ->  command: run
Metric #1
		Name         : goose.session_completions
		Description  :
		Unit         :
		Type         : Sum
		Sum DataPoints
		Monotonic    : false
		Temporality  : Cumulative
		DataPoint #0
			Value        : 1
			Attributes   :
				 ->  duration_ms: 10543
				 ->  exit_type: normal
				 ->  message: Session completed
				 ->  message_count: 2
				 ->  session_type: run
				 ->  total_tokens: 6018

SDK disabled

$ OTEL_SDK_DISABLED=true ./target/release/goose run -t "hello"
starting session | provider: openai model: gpt-5-nano
    session id: 20260212_2
    working directory: /Users/codefromthecrypt/oss/goose-2
# No OTel output — traces, metrics, and logs all suppressed

OTLP exporter with otel-tui

In one terminal, start otel-tui (listens on localhost:4317 gRPC and localhost:4318 HTTP by default):

otel-tui

In another terminal, run goose with the OTLP endpoint:

OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 ./target/release/goose run -t "hello"

Example screenshots, note the lack of root span is something to fix in another PR and was the case in main:

Screenshot 2026-02-12 at 8 21 35 AM Screenshot 2026-02-12 at 8 21 29 AM Screenshot 2026-02-12 at 8 21 23 AM

Related Issues

Extracted from #5151

Copilot AI review requested due to automatic review settings February 11, 2026 09:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates goose’s OpenTelemetry integration to respect standard OTel environment variables for per-signal exporter selection (traces/metrics/logs) with config-file fallback, adds a console exporter for local debugging, and improves provider shutdown behavior.

Changes:

  • Added otel_config module to detect OTel signal/exporter configuration via env vars with config fallback.
  • Reworked OTLP layer initialization to create traces/metrics/logs pipelines independently and support otlp|console|none.
  • Updated CLI/server logging to wire the new propagation init + per-signal layer setup and improved shutdown behavior.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
crates/goose/src/tracing/otlp_layer.rs Refactors OTel layer creation, resource construction, provider lifecycle/shutdown, and adds tests.
crates/goose/src/tracing/otel_config.rs New env/config detection logic for per-signal exporter selection.
crates/goose/src/tracing/mod.rs Wires in otel_config and updates re-exports for new tracing APIs.
crates/goose/Cargo.toml Adds opentelemetry-stdout dependency for console exporting.
crates/goose-server/src/logging.rs Switches to independent per-signal OTel layer setup + propagation init.
crates/goose-cli/src/main.rs Uses is_otlp_initialized() to decide whether to shutdown providers on exit.
crates/goose-cli/src/logging.rs Switches to independent per-signal OTel layer setup + propagation init.
Cargo.lock Locks the new opentelemetry-stdout dependency and transitive deps.

Copilot AI review requested due to automatic review settings February 11, 2026 11:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.

@codefromthecrypt codefromthecrypt marked this pull request as draft February 11, 2026 12:00
@codefromthecrypt
Copy link
Collaborator Author

updating to latest otel and the copilot feedback broke http export which is different recently. will pull out of draft when I figure it out.

Copy link
Collaborator

@alexhancock alexhancock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTel seems the way to go to me, and this looks like a great simple start

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.

@codefromthecrypt
Copy link
Collaborator Author

re-ran all the tests and manual tests and updated screenshots and console output

@codefromthecrypt codefromthecrypt marked this pull request as ready for review February 12, 2026 00:22
@codefromthecrypt codefromthecrypt requested a review from a team as a code owner February 12, 2026 00:22
@block block deleted a comment from github-actions bot Feb 12, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Comment on lines 443 to 445
Configure goose to export traces, metrics, and logs to any
[OpenTelemetry](https://opentelemetry.io/docs/) compatible platform.
When configured, goose exports telemetry asynchronously and flushes on exit.
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR updates public documentation alongside feature code; if these docs are intended for a future release, they should be separated or otherwise marked so unreleased behavior isn’t documented in published guides.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this PR contains already released features/functionality?

Support OTEL_TRACES_EXPORTER, OTEL_METRICS_EXPORTER, OTEL_LOGS_EXPORTER
and OTEL_SDK_DISABLED environment variables. Add console exporter for
local debugging alongside the existing OTLP exporter.

Each signal (traces, metrics, logs) now initializes independently so
one failing doesn't block the others. Shutdown properly flushes all
three providers instead of sleeping.

Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
Signed-off-by: Adrian Cole <adrian@tetrate.io>
@github-actions
Copy link
Contributor

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://block.github.io/goose/pr-preview/pr-7144/

Built to branch gh-pages at 2026-02-12 01:35 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Copy link
Collaborator

@michaelneale michaelneale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems ok and cross checked it with internal deployment that uses it

@codefromthecrypt
Copy link
Collaborator Author

@blackgirlbytes since this updates docs, this needs an approve to merge. mind giving a look?

@blackgirlbytes
Copy link
Contributor

@codefromthecrypt I gave this a comment a few days ago but think it got missed. My team prefers you remove the docs, and we will add it back later. Just because the functionality wont be immediately available to everyone! thanks

Signed-off-by: Adrian Cole <adrian@tetrate.io>
@codefromthecrypt
Copy link
Collaborator Author

moved here! #7221

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated no new comments.

@codefromthecrypt codefromthecrypt added this pull request to the merge queue Feb 14, 2026
Merged via the queue into main with commit ab54075 Feb 14, 2026
26 checks passed
@codefromthecrypt codefromthecrypt deleted the adrian/otel-env branch February 14, 2026 01:08
@codefromthecrypt
Copy link
Collaborator Author

Note: I removed the hard-coded 10pct sampling in this change. As @michaelneale noticed it might not be obvious which otel ENV do the same. I updated #7221 with an example to set 10pct, and the same style can apply any rate

michaelneale added a commit that referenced this pull request Feb 16, 2026
* origin/main: (42 commits)
  fix: use dynamic port for Tetrate auth callback server (#7228)
  docs: removing LLM Usage admonitions (#7227)
  feat(otel): respect standard OTel env vars for exporter selection (#7144)
  fix: fork session (#7219)
  Bump version numbers for 1.24.0 release (#7214)
  Move platform extensions into their own folder (#7210)
  fix: ignore deprecated skills extension (#7139)
  Add a goosed over HTTP integration test, and test the developer tool PATH (#7178)
  feat: add onFallbackRequest handler to McpAppRenderer (#7208)
  feat: add streaming support for Claude Code CLI provider (#6833)
  fix: The detected filetype is PLAIN_TEXT, but the provided filetype was HTML (#6885)
  Add prompts (#7212)
  Add testing instructions for speech to text (#7185)
  Diagnostic files copying (#7209)
  fix: allow concurrent tool execution within the same MCP extension (#7202)
  fix: handle missing arguments in MCP tool calls to prevent GUI crash (#7143)
  Filter Apps page to only show standalone Goose Apps (#6811)
  opt: use static for Regex (#7205)
  nit: show dir in title, and less... jank (#7138)
  feat(gemini-cli): use stream-json output and re-use session (#7118)
  ...
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.

4 participants