Go quickstart
Target: first trace in your tenant in about five minutes. Go's OTel ecosystem is less auto-instrumenting than Node's — you'll wire one handler wrapper manually. That's the only sharp edge.
1. Sign up and grab your tenant key
Create a tenant and copy your tenant ingest key. Export it to your environment:
export GREENSLOPE_INGEST_KEY="gs_ing_live_…"2. Install the OTel modules
go get \
go.opentelemetry.io/otel \
go.opentelemetry.io/otel/sdk \
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp \
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp \
go.opentelemetry.io/otel/semconv/v1.26.03. Initialise the tracer provider
// telemetry.go
package main
import (
"context"
"os"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
)
func initTracing(ctx context.Context, serviceName, version, releaseID string) (func(context.Context) error, error) {
exp, err := otlptracehttp.New(ctx,
otlptracehttp.WithEndpoint("ingest.greenslope.io"),
otlptracehttp.WithURLPath("/v1/otel/v1/traces"),
otlptracehttp.WithHeaders(map[string]string{
"x-greenslope-key": os.Getenv("GREENSLOPE_INGEST_KEY"),
}),
)
if err != nil {
return nil, err
}
res, err := resource.New(ctx,
resource.WithAttributes(
semconv.ServiceName(serviceName),
semconv.ServiceVersion(version),
attribute.String("greenslope.release.id", releaseID),
),
)
if err != nil {
return nil, err
}
tp := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(exp),
sdktrace.WithResource(res),
)
otel.SetTracerProvider(tp)
return tp.Shutdown, nil
}4. Wrap your HTTP handler
Unlike Node, Go doesn't auto-patch net/http — you opt-in per handler.
Wrap your mux with otelhttp.NewHandler:
// main.go
package main
import (
"context"
"log"
"net/http"
"os"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
func main() {
ctx := context.Background()
shutdown, err := initTracing(ctx, "api", "0.0.0",
os.Getenv("GIT_SHA"))
if err != nil {
log.Fatal(err)
}
defer shutdown(ctx)
mux := http.NewServeMux()
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})
log.Fatal(http.ListenAndServe(":3000",
otelhttp.NewHandler(mux, "server")))
}5. Run and hit the endpoint
go run .
# in another terminal
curl http://localhost:3000/healthVerify
Open Live traces at app.greenslope.io.
Look for a span with http.route=/health and your three resource
attributes set.
Blank? Check Troubleshooting.
Related