Repository navigation
[go-fan] Go Module Review: go.opentelemetry.io/otelΒ #4845
Description
πΉ Go Fan Report: OpenTelemetry Go SDK
Module Overview
go.opentelemetry.io/otel is the official OpenTelemetry SDK for Go β distributed tracing, context propagation, OTLP export, and semantic conventions. The project uses it at v1.43.0 (latest stable) across four sub-modules: core API, SDK, trace, and OTLP/HTTP exporter.
Current Usage in gh-aw-mcpg
The gateway has a well-structured tracing layer under internal/tracing/ with good noop/live toggle and W3C propagation support.
- Files: 5 files (
tracing/provider.go,tracing/http.go,server/unified.go,server/http_helpers.go,proxy/handler.go) - Key APIs Used:
sdktrace.NewTracerProvider,otlptracehttp.New,noop.NewTracerProvider,span.RecordError,span.SetStatus,resource.New,propagation.NewCompositeTextMapPropagator - Sampler logic: AlwaysSample / NeverSample / TraceIDRatioBased based on config
- Semantic conventions:
semconv/v1.26.0used across all files
Research Findings
Recent Updates (v1.43.0)
- v1.43.0 is the current stable release β the project is fully up-to-date
- semconv
v1.27.0is available within the same module (project usesv1.26.0) - No breaking changes between 1.26.0 and 1.27.0 semconv β safe upgrade
Best Practices
- Always use a
ResponseWriterwrapper to capture HTTP response status and set it on the span - Set
codes.Erroron spans returning 5xx responses; setsemconv.HTTPResponseStatusCodeKey - Use
span.AddEventfor lifecycle milestones (not just errors) - Avoid putting raw
err.Error()inSetStatusdescription β OTel backends may log these publicly; prefer fixed messages and useRecordError(err)for the full error
Improvement Opportunities
π Quick Wins
1. WrapHTTPHandler missing HTTP response status recording
tracing/http.go WrapHTTPHandler wraps next.ServeHTTP(w, r.WithContext(ctx)) but never captures the response status code. Per OTel HTTP semantic conventions, http.response.status_code SHOULD be set, and spans with 4xx/5xx should have codes.Error set.
// Add a responseWriter wrapper:
type statusResponseWriter struct {
http.ResponseWriter
statusCode int
}
func (rw *statusResponseWriter) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}
// In WrapHTTPHandler, after next.ServeHTTP:
srw := &statusResponseWriter{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(srw, r.WithContext(ctx))
span.SetAttributes(semconv.HTTPResponseStatusCodeKey.Int(srw.statusCode))
if srw.statusCode >= 500 {
span.SetStatus(codes.Error, http.StatusText(srw.statusCode))
}2. Bump semconv from v1.26.0 β v1.27.0
The module ships both. v1.27.0 adds network.* attributes and clarifies http.* naming. A one-line import change in 4 files.
β¨ Feature Opportunities
3. Propagate session.id in W3C Baggage
The W3C Baggage propagator is already registered but never written to. Injecting session.id into baggage would allow downstream services (e.g., OTLP collectors, backend MCP servers) to correlate requests without needing OTel instrumentation themselves.
ctx = baggage.ContextWithBaggage(ctx, /* baggage with session.id */)4. Span events for lifecycle milestones
span.AddEvent("tools/list.resolved", oteltrace.WithAttributes(...)) would enrich traces without adding new spans. Good candidates: session creation, tool list resolution, circuit breaker state changes.
5. mTLS support for OTLP export
The gateway supports mTLS for inbound connections. For consistency, otlptracehttp.WithTLSClientConfig could be exposed via config for OTLP endpoints requiring mutual TLS.
π Best Practice Alignment
6. Raw error in SetStatus description
unified.go:556: execSpan.SetStatus(codes.Error, err.Error()) puts the raw error string in the span status description. This can leak internal details to trace backends. Prefer:
execSpan.RecordError(err) // already called on line 555
execSpan.SetStatus(codes.Error, "tool execution failed") // fixed message7. Missing codes.Ok for explicit success
OTel recommends setting codes.Ok on spans that represent explicitly successful operations (e.g., after a tool call completes with a valid response). Currently the status is left as Unset on success.
π§ General Improvements
8. resource.WithHost() in provider
Already used β
. But resource.WithOSDescription() and resource.WithContainerID() (via resource.WithDetectors) could enrich the resource for containerized deployments β the gateway explicitly supports Docker.
Recommendations
| Priority | Item | Effort |
|---|---|---|
| High | Fix WrapHTTPHandler to capture response status (#1) |
Small |
| Medium | Sanitize SetStatus error descriptions (#6) |
Trivial |
| Medium | Bump semconv to v1.27.0 (#2) | Trivial |
| Low | Baggage propagation for session.id (#3) | Small |
| Low | Span events for lifecycle milestones (#4) | Small |
Next Steps
- Add
statusResponseWriterwrapper totracing/http.go - Replace
execSpan.SetStatus(codes.Error, err.Error())with fixed message - Update semconv import to
v1.27.0
Generated by Go Fan πΉ
Module summary saved to: specs/mods/opentelemetry-otel.md
Run: Β§25153854887
Note
π Integrity filter blocked 14 items
The following items were blocked because they don't meet the GitHub integrity level.
- BurntSushi/toml@b66ba2a
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - santhosh-tekuri/jsonschema@d3bf053
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - spf13/pflag@3d32e71
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - open-telemetry/opentelemetry-go@d4d6c45
get_commit: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/BurntSushi/toml/releases/tag/v1.6.0
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/spf13/pflag/releases/tag/v1.0.10
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/santhosh-tekuri/jsonschema/releases/tag/v6.0.2
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.43.0
get_latest_release: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.43.0
list_releases: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.42.0
list_releases: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.41.0
list_releases: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.40.0
list_releases: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.39.0
list_releases: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved". - get_file_contents
get_file_contents: has lower integrity than agent requires. The agent cannot read data with integrity below "unapproved".
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | noneGenerated by Go Fan Β· β 1.8M Β· β·
- expires on May 7, 2026, 7:57 AM UTC
Activity