Repository navigation
[go-fan] Go Module Review: go.opentelemetry.io/otel #6841
Description
🐹 Go Fan Report: OpenTelemetry Go SDK
Module Overview
go.opentelemetry.io/otel is the official OpenTelemetry SDK for Go — a vendor-neutral observability framework providing distributed tracing, metrics, and logging APIs. This project uses the tracing subsystem to instrument MCP gateway requests with OTLP/HTTP export to any compatible backend (Jaeger, Tempo, Honeycomb, etc.).
The project imports four OTel modules as direct dependencies:
go.opentelemetry.io/otel— core API (tracer, propagator, global)go.opentelemetry.io/otel/trace— trace types (Span, TraceID, etc.)go.opentelemetry.io/otel/sdk— SDK TracerProvider, samplers, BatchSpanProcessorgo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp— OTLP/HTTP exporter
Current Usage in gh-aw
The tracing integration is well-structured and lives entirely in internal/tracing/.
- Files: 24 Go files reference OTel (9 source + tests)
- Import Count: 10+ distinct OTel sub-package imports
- Key APIs Used:
sdktrace.NewTracerProviderwithWithBatcher(correct for production)otlptracehttp.NewwithWithEndpointURL+WithTimeout+WithHeadersresource.NewwithWithTelemetrySDK,WithContainer,WithHost,WithProcessPIDpropagation.NewCompositeTextMapPropagator(TraceContext + Baggage — W3C compliant)otel.SetTracerProvider/otel.SetTextMapPropagator(global registration)sdktrace.TraceIDRatioBasedsampler with configurable ratetrace.ContextWithRemoteSpanContextfor parent context injectionsemconv/v1.34.0andsemconv/v1.27.0for semantic conventions- GenAI semconv attributes (
gen_ai.tool.name,gen_ai.agent.id,gen_ai.conversation.id) tracetest.NewInMemoryExporterfor unit tests
Research Findings
Recent Updates
The project uses v1.43.0; the latest available release is v1.44.0. The OTel Go project is very actively maintained with regular releases. At v1.43 → v1.44 the changes are typically:
- Updated semantic convention versions (semconv sub-package bumps)
- Stability promotions in the metrics/log APIs
- Minor bug fixes in the SDK
Best Practices (from OTel Go maintainers)
- Single semconv version across a package: OTel strongly recommends pinning to one semconv version throughout your instrumentation to avoid mixed schema URLs in traces.
error.typeattribute on errored spans: The OTel spec recommends settingsemconv.ErrorTypeKeywhen recording an error span to enable better error categorization in backends.gen_ai.systemattribute: GenAI semconv calls forgen_ai.system(e.g.,"mcp") on GenAI-related spans so backends can filter by AI system type.BatchSpanProcessorin production: ✅ Already used correctly.- Noop provider for disabled tracing: ✅ Already used correctly.
- W3C propagator registration: ✅ Already done correctly.
Improvement Opportunities
🏃 Quick Wins
1. Unify semconv versions — span_helpers.go still imports v1.27.0
span_helpers.go (and its test) imports semconv/v1.27.0 while all other tracing files use semconv/v1.34.0. Both define URLPathKey identically (url.path), so this is a zero-risk change that eliminates a mixed schema URL inconsistency in exported traces.
// span_helpers.go — change this:
semconv "go.opentelemetry.io/otel/semconv/v1.27.0"
// to:
semconv "go.opentelemetry.io/otel/semconv/v1.34.0"Same fix in span_helpers_test.go. The v1.27.0 import becomes unused and can be removed from the module graph entirely with go mod tidy.
2. Bump to v1.44.0
A minor patch bump to v1.44.0 (go get go.opentelemetry.io/otel@v1.44.0 and friends) keeps the dependency current with the latest bug fixes and semconv updates.
✨ Feature Opportunities
3. Add error.type attribute to RecordSpanError
The OTel HTTP and GenAI semantic conventions recommend setting semconv.ErrorTypeKey when a span enters error status. This enables backends (Grafana Tempo, Honeycomb, Datadog) to facet and alert on specific error types. Current code:
func RecordSpanError(span oteltrace.Span, err error, msg string) {
span.RecordError(err, oteltrace.WithStackTrace(true))
span.SetStatus(codes.Error, msg)
// Missing: span.SetAttributes(semconv.ErrorType(reflect.TypeOf(err).String()))
}Adding semconv.ErrorType(fmt.Sprintf("%T", err)) (using semconv/v1.34.0) provides structured error categorization without breaking existing behavior.
4. Add gen_ai.system attribute to MCP tool call spans
The GenAI semconv (which the project already uses for gen_ai.tool.name, gen_ai.agent.id, etc.) also defines gen_ai.system to identify the AI framework. For MCP:
// In StartToolCallSpan:
oteltrace.WithAttributes(
GenAISystem.String("mcp"), // add this
GenAIAgentID.String(serverID),
// ...
)This aligns the project with GenAI semconv completeness and helps trace backends that filter by gen_ai.system.
5. Export genai_attrs.go constant for gen_ai.system
The file already exports GenAIToolName, GenAIAgentID, etc. Adding GenAISystem = semconv.GenAISystemKey would round out the exported constants and make it easier to set the system attribute consistently.
📐 Best Practice Alignment
6. Consider otelhttp.NewHandler from go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
The custom WrapHTTPHandler in http.go re-implements what otelhttp.NewHandler provides. The contrib library handles: automatic span naming, method/route/status attributes, request size attributes, and response write interception. Adopting it would reduce custom code while gaining community-maintained edge-case handling. This is a larger refactor but worth considering as the tracing integration matures.
7. resource.WithContainer() in non-container environments
resource.WithContainer() attempts to read /.dockerenv and cgroup files. In non-container CI/dev environments, this is a no-op but it does perform filesystem I/O on every startup. Wrapping it in a conditional (if isRunningInContainer()) or removing it when RUNNING_IN_CONTAINER is not set could save a few milliseconds at cold start. Low priority given the project already has container detection logic in internal/sys/.
🔧 General Improvements
8. http.url.full on server spans
The WrapHTTPHandler sets url.path and http.route but not url.full (the full URL including query string). For gateway debugging, url.full can be helpful. The OTel HTTP semconv marks it as "opt-in" for servers (due to PII concerns with query params), but since the gateway already processes auth headers it's worth considering for internal observability.
Module Summary
| Field | Value |
|---|---|
| Module | go.opentelemetry.io/otel |
| Version | v1.43.0 (also: otel/trace, otel/sdk, otel/exporters/otlp/otlptrace/otlptracehttp) |
| Repository | https://github.com/open-telemetry/opentelemetry-go |
| Latest Release | v1.44.0 |
| Last Reviewed | 2026-06-01 |
Key Features Used
- Distributed tracing with OTLP/HTTP export
- W3C TraceContext + Baggage propagation
- Configurable sampling (ratio, always, never)
- Resource detection (service, version, host, PID, container)
- Noop provider for zero-overhead when tracing disabled
- GenAI semantic conventions (
gen_ai.*attributes) - In-memory exporter for unit tests (
tracetest)
References
- Documentation: (opentelemetry.io/redacted)
- API Reference: https://pkg.go.dev/go.opentelemetry.io/otel
- Changelog: https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md
- GenAI Semconv: (opentelemetry.io/redacted)
Recommendations
Prioritized by impact and effort:
- 🔴 [Quick Win] Unify semconv to
v1.34.0inspan_helpers.go— eliminates mixed schema URL inconsistency in traces; safe, zero-risk change. - 🟡 [Quick Win] Bump all four OTel modules to v1.44.0 — stays current with latest bugfixes.
- 🟡 [Feature] Add
error.typeattribute inRecordSpanError— improves error observability in APM backends. - 🟢 [Feature] Add
gen_ai.system = "mcp"to tool call spans — rounds out GenAI semconv compliance. - 🟢 [Feature] Export
GenAISystemconstant ingenai_attrs.goalongside existing GenAI constants. - ⚪ [Future] Evaluate
otelhttp.NewHandlerfrom the contrib library as a replacement for customWrapHTTPHandler.
Next Steps
- Fix semconv version in
span_helpers.go(and its test) tov1.34.0, rungo mod tidy -
go get go.opentelemetry.io/otel@v1.44.0(and the three companion modules) +go mod tidy - Add
semconv.ErrorType(fmt.Sprintf("%T", err))toRecordSpanErrorinspan_helpers.go - Add
GenAISystemconstant and use it onStartToolCallSpan
Generated by Go Fan 🐹 — Run §26745080144
Note
🔒 Integrity filter blocked 96 items
The following items were blocked because they don't meet the GitHub integrity level.
- https://github.com/modelcontextprotocol/go-sdk
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/ktr0731/go-mcp
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/SetiabudiResearch/mcp-go-sdk
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/modelcontextprotocol-ce/go-sdk
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/leefowlercu/go-mcp-registry
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/jeanlucthumm/modelcontextprotocol-go-sdk
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/x86ed/modelcontextprotocol-go-sdk
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/curioswitch/mcp-go-sdk-otel
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/kwasek404/warehouse-mcp
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/frsfahd/go-weather-mcp-server
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/ganawaj/mcp-transport-nats
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/step-chen/atlassian-dc-mcp-go
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/kakkky/mcp-sdk-go
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/thediveo/enumflag
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/deepin-community/golang-github-spf13-pflag
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/vanhtuan0409/copperhead
search_repositories: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - ... and 80 more items
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | noneGenerated by Go Fan · sonnet46 1.3M · ◷
- expires on Jun 8, 2026, 8:59 AM UTC
Activity
refactor(tracing): unify semconv import to v1.34.0 in span_helpers
github-actions commentedon Jun 1, 2026
🤖 This is an automated response from Repo Assist.
Great analysis! I've picked up recommendation #1 (unify semconv to v1.34.0 in
span_helpers) and created a PR for it — see #aw_6841c.A few notes on the other recommendations:
#2 Bump to v1.44.0 — This requires network access to
proxy.golang.orgwhich is blocked in the Repo Assist CI environment. A maintainer can rungo get go.opentelemetry.io/otel@v1.44.0 go.opentelemetry.io/otel/trace@v1.44.0 go.opentelemetry.io/otel/sdk@v1.44.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp@v1.44.0 && go mod tidyto apply this. The change is low-risk since v1.43.0→v1.44.0 is a minor bump.#3 Add
error.typeattribute toRecordSpanError— Worth doing. The call would bespan.SetAttributes(semconv.ErrorType(fmt.Sprintf("%T", err)))after updating the import (once the semconv PR merges). This improves error categorization in APM backends without any behavioral change.#4/#5
gen_ai.systemattribute and constant — Straightforward additions that round out GenAI semconv compliance. Would fit well alongside #3 in a single "tracing semconv improvements" PR.#6
otelhttp.NewHandler— I'd flag this as a future consideration rather than an immediate action. The customWrapHTTPHandleris intentionally minimal for the gateway's use case, and adopting the contrib library adds a new dependency. Worth a discussion issue if the tracing integration grows more complex.Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
proxy.golang.orgSee Network Configuration for more information.
Add this agentic workflows to your repo
To install this agentic workflow, run
[Repo Assist] refactor(tracing): unify semconv import to v1.34.0 in s…