Go Instrumentation
Instrument any Go HTTP server or service using the OpenTelemetry Go SDK. Go requires a small init function — there's no equivalent of NODE_OPTIONS — but the setup is under 20 lines and only needed once.
1. Install
bash
go get go.opentelemetry.io/otel \
go.opentelemetry.io/otel/sdk \
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp2. Set environment variables
.env
LA_DSN=la_live_YOUR_TOKEN_HERE
OTEL_SERVICE_NAME=my-go-service
ENVIRONMENT=production3. Add the init function
Create otel.go in your project root:
otel.go
package main
import (
"context"
"os"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.21.0"
"go.opentelemetry.io/otel/sdk/resource"
)
func initTracer(ctx context.Context) func() {
exp, _ := otlptracehttp.New(ctx,
otlptracehttp.WithEndpoint("la-ingest-gateway.lightarch.workers.dev"),
otlptracehttp.WithHeaders(map[string]string{"x-la-dsn": os.Getenv("LA_DSN")}),
)
res, _ := resource.New(ctx, resource.WithAttributes(
semconv.ServiceName(os.Getenv("OTEL_SERVICE_NAME")),
semconv.DeploymentEnvironment(os.Getenv("ENVIRONMENT")),
))
tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exp), sdktrace.WithResource(res))
otel.SetTracerProvider(tp)
return func() { tp.Shutdown(ctx) }
}4. Call it from main
main.go
func main() {
ctx := context.Background()
defer initTracer(ctx)()
// ... rest of your app
}defer initTracer(ctx)() initialises OTel and registers a shutdown hook in one line. The double () is intentional — it calls the cleanup function returned by initTracer.Screenshot needed
Traces page showing Go service spans with service='my-go-service', waterfall with multiple Go spans.
Custom spans
go
func processPayment(ctx context.Context, orderID string) error {
tracer := otel.Tracer("my-go-service")
ctx, span := tracer.Start(ctx, "payment.process")
defer span.End()
span.SetAttributes(attribute.String("order.id", orderID))
if err := chargeCard(ctx, orderID); err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
return err
}
return nil
}