Go SDK
Full observability for Go services — HTTP, databases, gRPC, and logging captured automatically via OpenTelemetry
Built on OpenTelemetry
The Go SDK is a thin wrapper that configures OpenTelemetry with the Obtrace ingest endpoint. It uses OTel contrib packages (otelhttp, otelsql, otelgrpc) to instrument your application. You get automatic spans for HTTP, database, and gRPC operations out of the box.
Installation
Minimum Setup
Set OBTRACE_API_KEY in your environment. ServiceName should be a stable, lowercase identifier that matches what your team calls the service (e.g., checkout-api, billing-worker).
What's Captured Automatically
After ob.NewClient(), the SDK configures OpenTelemetry and instruments Go's standard library and common packages. You don't need to write any extra code for this:
| What | How | Needs code? |
|---|---|---|
| All stdlib log output | log.Println(), log.Printf(), log.Fatalf() etc. are intercepted and sent as structured logs | No |
| Outbound HTTP calls | http.DefaultTransport is wrapped via otelhttp to emit spans with method, URL, status, and duration, and inject traceparent headers | No |
| Inbound HTTP | Use otelhttp.NewHandler() or framework-specific contrib middleware (gin, echo, chi, mux, fiber) | Wrap handler |
| database/sql | Use otelsql to wrap your database driver for automatic query spans | Wrap driver |
| gRPC | Use otelgrpc interceptors for automatic client and server spans | Add interceptor |
Every http.Get(), http.Post(), or request made through http.DefaultClient is automatically traced. Trace context is propagated to downstream services via the traceparent header.
OTel contrib packages for Go require explicit wiring (unlike dynamic languages), but the SDK pre-configures the OTel exporter and resource so you only need to add the middleware or wrapper.
Opting Out of Auto HTTP Instrumentation
Optional: Custom Telemetry
The automatic log and HTTP capture covers basic observability. For business-specific events, use the SDK methods directly.
Logging
Use client.Log(level, message, ctx) to record events you need to search for later. Good candidates:
- Errors and panics recovered in middleware
- Business events (order placed, payment failed, user signed up)
- Audit trail entries (permission changed, config updated)
- State transitions (circuit breaker opened, cache flushed)
The level parameter accepts standard syslog levels: DEBUG, INFO, WARN, ERROR, FATAL. Messages are truncated at 32KB.
The ctx parameter is optional. When provided, it attaches structured attributes to the log entry. Use Attrs for custom key-value pairs, and the built-in fields (TraceID, SpanID, Method, Endpoint, StatusCode) to correlate logs with traces.
Metrics
Use client.Metric(name, value, unit, ctx) to record measurements you want to graph or alert on. Good candidates:
- Latency measurements (how long did this take?)
- Counters (how many orders per minute?)
- Gauges (current queue depth, active connections)
- Business KPIs (revenue per checkout, items per cart)
The unit parameter follows OTLP conventions: "ms" for milliseconds, "By" for bytes, "1" for dimensionless values (counts, ratios), or a currency code.
Tracing / Spans
Use client.Span(...) to track a unit of work and its duration. Returns (traceID, spanID) so you can propagate context to downstream services. Good candidates:
- HTTP handler execution (request in, response out)
- Database queries
- External API calls
- Background job processing
- Any operation where you need to see where time was spent
Pass an empty string for traceID and spanID to auto-generate them. Pass an existing traceID to group spans into the same trace. The statusCode uses OTLP conventions: 0 = unset, 1 = OK, 2 = error.
Propagating Trace Context
Trace context is injected automatically on outbound HTTP calls made through http.DefaultTransport. For custom transports or non-HTTP protocols, inject manually:
Framework Integration
net/http Middleware
The SDK includes middleware for net/http that uses otelhttp under the hood to create a span and log entry for each inbound request:
The middleware emits one span (http.server METHOD) and one log (http request done) per request, with method, route, status code, and duration attached.
Gin, Echo, Chi, Gorilla Mux, and Fiber middleware are also available under middleware/gin, middleware/echo, middleware/chi, middleware/mux, and middleware/fiber. These use the corresponding OTel contrib packages internally.
Configuration Reference
| Field | Type | Default | Description |
|---|---|---|---|
APIKey | string | "" | Required. Your Obtrace API key. |
ServiceName | string | "" | Required. Stable name for this service. |
ServiceVersion | string | "" | Deployment version (git SHA, semver, date). |
TenantID | string | "" | Scoped ingest identity. |
ProjectID | string | "" | Scoped ingest identity. |
AppID | string | "" | Scoped ingest identity. |
Env | string | "" | Environment name (prod, staging, dev). |
DisableAutoHTTP | bool | false | Disable automatic http.DefaultTransport instrumentation. |
RequestTimeoutMS | int | 5000 | HTTP timeout per OTLP request in milliseconds. |
MaxQueueSize | int | 1000 | Max queued telemetry items before oldest are dropped. |
ValidateSemanticMetrics | bool | false | When true + Debug, warns on non-canonical metric names. |
Debug | bool | false | Enables SDK diagnostic output to stdout. |
DefaultHeaders | map[string]string | nil | Extra headers sent with every OTLP request. |
TraceHeaderName | string | "" | Custom trace propagation header name. |
SessionHeaderName | string | "" | Custom session propagation header name. |
Validation Checklist
After integrating the SDK, verify these before shipping to production:
-
ServiceName,Env, andServiceVersionare set and survive restarts and deploys - At least one request path emits both a log and a span
-
client.Flush()orclient.Shutdown()is called before process exit (usedefer) - No
401or403errors appear in logs during OTLP submission (check withDebug: true) - Metrics use correct units (
ms,By,1) not free-form strings - Outbound HTTP calls via
http.DefaultTransportshow auto-generated spans (powered byotelhttp) - Custom HTTP clients with non-default transports use
InjectPropagationmanually - Database queries via
database/sqlshow spans when usingotelsqldriver wrapper - gRPC calls show spans when using
otelgrpcinterceptors
See also: Semantic Metrics