Documentation Index Fetch the complete documentation index at: https://docs.tracelit.io/llms.txt
Use this file to discover all available pages before exploring further.
Installation
go get github.com/tracelit-ai/tracelit-go
Quick start
Initialise the SDK
package main
import (
" context "
" log "
" github.com/tracelit-ai/tracelit-go "
)
func main () {
sdk , err := tracelit . New (
tracelit . WithAPIKey ( os . Getenv ( "TRACELIT_API_KEY" )),
tracelit . WithServiceName ( "payments-api" ),
tracelit . WithEnvironment ( "production" ),
)
if err != nil {
log . Fatal ( err )
}
defer sdk . Shutdown ( context . Background ())
// Your application code here
}
Or use environment variables (zero code changes)
export TRACELIT_API_KEY = your-api-key
export TRACELIT_SERVICE_NAME = payments-api
export TRACELIT_ENVIRONMENT = production
if err := tracelit . Configure (); err != nil {
log . Fatal ( err )
}
defer tracelit . Shutdown ( context . Background ())
Configuration reference
Option Env variable Default Description WithAPIKey(key)TRACELIT_API_KEY— Required. Your Tracelit API keyWithServiceName(name)TRACELIT_SERVICE_NAME— Required. Service name shown in TracelitWithEnvironment(env)TRACELIT_ENVIRONMENTproductionDeployment environment tag WithEndpoint(url)TRACELIT_ENDPOINThttps://ingest.tracelit.appOverride only when self-hosting WithSampleRate(rate)TRACELIT_SAMPLE_RATE1.0Head-based sampling ratio 0.0–1.0 WithEnabled(bool)TRACELIT_ENABLEDtrueSet false to disable all telemetry WithResourceAttributes(map)— — Extra resource attributes on every signal
Custom resource attributes
sdk , err := tracelit . New (
tracelit . WithAPIKey ( os . Getenv ( "TRACELIT_API_KEY" )),
tracelit . WithServiceName ( "orders-api" ),
tracelit . WithResourceAttributes ( map [ string ] string {
"deployment.region" : "us-east-1" ,
"team" : "platform" ,
}),
)
Tracing
Automatic instrumentation
Once tracelit.New (or tracelit.Configure) is called, the global OTel TracerProvider is set. Any library that uses the OTel API (otelhttp, otelgrpc, otelsql, etc.) will automatically send spans to Tracelit without further configuration.
Manual spans
import " github.com/tracelit-ai/tracelit-go "
func processOrder ( ctx context . Context , order Order ) error {
ctx , span := tracelit . StartSpan ( ctx , "process-order" ,
tracelit . WithSpanAttributes ( map [ string ] any {
"order.id" : order . ID ,
"order.currency" : order . Currency ,
}),
)
defer span . End ()
if err := validateOrder ( ctx , order ); err != nil {
span . RecordError ( err ) // sets codes.Error + attaches exception.stacktrace
return err
}
// Child span — automatically a child of the span above
ctx , paySpan := tracelit . StartClientSpan ( ctx , "charge-payment-provider" )
defer paySpan . End ()
if err := chargeCard ( ctx , order ); err != nil {
paySpan . RecordError ( err ,
tracelit . WithErrorAttributes ( map [ string ] any {
"payment.gateway" : "stripe" ,
"payment.amount" : order . TotalCents ,
}),
)
return err
}
span . AddEvent ( "payment-captured" , map [ string ] any { "amount" : order . TotalCents })
return nil
}
Span kinds
// SpanKindInternal (default) — internal operation
ctx , span := tracelit . StartSpan ( ctx , "validate-input" )
// SpanKindServer — inbound request handler
ctx , span := tracelit . StartServerSpan ( ctx , "POST /orders" )
// SpanKindClient — outbound call (HTTP, gRPC, DB)
ctx , span := tracelit . StartClientSpan ( ctx , "stripe.charge" )
// SpanKindProducer / Consumer — message queues
ctx , span := tracelit . StartProducerSpan ( ctx , "orders.created publish" )
ctx , span := tracelit . StartConsumerSpan ( ctx , "orders.created consume" )
Stack traces on errors
RecordError captures a full goroutine stack trace automatically:
ctx , span := tracelit . StartSpan ( ctx , "risky-op" )
defer span . End ()
if err := riskyOperation (); err != nil {
span . RecordError ( err ) // sets codes.Error + attaches exception.stacktrace
return err
}
Panic recovery
ctx , span := tracelit . StartSpan ( ctx , "risky-op" )
defer func () {
if r := recover (); r != nil {
span . RecordPanic ( r ) // records panic + re-panics by default
// span.RecordPanic(r, tracelit.WithSwallowPanic()) // absorb the panic
}
span . End ()
}()
Trace and span IDs (for log correlation)
traceID := tracelit . TraceID ( ctx ) // "4bf92f3577b34da6a3ce929d0e0e4736"
spanID := tracelit . SpanID ( ctx ) // "00f067aa0ba902b7"
Passing spans across goroutines
ctx , span := tracelit . StartSpan ( ctx , "fan-out" )
defer span . End ()
for _ , item := range items {
go func ( item Item ) {
childCtx , child := tracelit . StartSpan ( ctx , "process-item" )
defer child . End ()
processItem ( childCtx , item )
}( item )
}
HTTP and gRPC instrumentation
HTTP server and client
import (
" github.com/tracelit-ai/tracelit-go/middleware "
" net/http "
)
// Server — wrap entire mux or individual handlers
mux := http . NewServeMux ()
mux . HandleFunc ( "/api/orders" , handleOrders )
http . ListenAndServe ( ":8080" , middleware . NewHTTPHandler ( mux ))
// Client — wrap transport for outgoing requests
client := & http . Client {
Transport : middleware . NewHTTPTransport ( nil ),
}
resp , err := client . Get ( "https://api.stripe.com/v1/charges" )
gRPC
import " github.com/tracelit-ai/tracelit-go/middleware "
// Server
grpcServer := grpc . NewServer (
grpc . StatsHandler ( middleware . NewGRPCServerHandler ()),
)
// Client
conn , err := grpc . NewClient ( "localhost:50051" ,
grpc . WithStatsHandler ( middleware . NewGRPCClientHandler ()),
)
Metrics
import (
" go.opentelemetry.io/otel/metric "
" go.opentelemetry.io/otel/attribute "
)
// Counter
requests , err := tracelit . Counter ( "http.server.requests" ,
metric . WithDescription ( "Total HTTP requests" ),
metric . WithUnit ( "{request}" ),
)
requests . Add ( ctx , 1 , metric . WithAttributes (
attribute . String ( "method" , r . Method ),
attribute . Int ( "status" , code ),
))
// Histogram
latency , err := tracelit . Histogram ( "http.server.duration" ,
metric . WithUnit ( "ms" ),
)
latency . Record ( ctx , durationMs )
Runtime and process metrics (goroutines, GC, memory) are exported automatically every 60 seconds — no extra code required.
Logger bridges
All bridges route log records to the Tracelit log pipeline and automatically inject trace_id and span_id from the context.
import (
" log/slog "
" github.com/tracelit-ai/tracelit-go/bridge "
)
// Replace the default global slog logger
slog . SetDefault ( slog . New ( bridge . NewSlogHandler ()))
// Logs are correlated with the active span when ctx is passed
slog . InfoContext ( ctx , "order created" , "order_id" , order . ID )
import (
" github.com/tracelit-ai/tracelit-go/bridge "
" go.uber.org/zap "
" go.uber.org/zap/zapcore "
)
// Option 1: OTel-only logger
logger := bridge . NewZapLogger ( "payments-api" )
// Option 2: tee to both stdout and OTel
stdoutLogger , _ := zap . NewProduction ()
logger := zap . New ( zapcore . NewTee (
stdoutLogger . Core (),
bridge . NewZapCore ( "payments-api" ),
), zap . AddCaller ())
logger . Info ( "order created" , zap . String ( "order_id" , order . ID ))
import (
" github.com/sirupsen/logrus "
" github.com/tracelit-ai/tracelit-go/bridge "
)
logrus . AddHook ( bridge . NewLogrusHook ())
// Pass ctx to get trace correlation
logrus . WithContext ( ctx ). WithField ( "order_id" , order . ID ). Info ( "order created" )
import (
" os "
" github.com/rs/zerolog "
" github.com/rs/zerolog/log "
" github.com/tracelit-ai/tracelit-go/bridge "
)
// Replace the global zerolog logger
log . Logger = zerolog . New ( bridge . NewZerologWriter ( os . Stderr )).
With (). Timestamp (). Logger ()
// Use log.Ctx(ctx) to attach trace correlation
log . Ctx ( ctx ). Info (). Str ( "order_id" , order . ID ). Msg ( "order created" )
Sampling and error guarantee
sdk , err := tracelit . New (
tracelit . WithAPIKey ( os . Getenv ( "TRACELIT_API_KEY" )),
tracelit . WithServiceName ( "high-traffic-api" ),
tracelit . WithSampleRate ( 0.1 ), // keep 10% of traces
)
Error spans are always exported , even when the parent trace falls outside the sample ratio. The SDK uses a custom ErrorAlwaysOnSampler + ErrorSpanProcessor pair — no configuration required.
Disabling in tests
sdk , err := tracelit . New (
tracelit . WithAPIKey ( os . Getenv ( "TRACELIT_API_KEY" )),
tracelit . WithServiceName ( "my-service" ),
tracelit . WithEnabled ( false ), // or TRACELIT_ENABLED=false
)
Complete example
package main
import (
" context "
" log/slog "
" net/http "
" os "
" os/signal "
" syscall "
" github.com/tracelit-ai/tracelit-go "
" github.com/tracelit-ai/tracelit-go/bridge "
" github.com/tracelit-ai/tracelit-go/middleware "
)
func main () {
sdk , err := tracelit . New (
tracelit . WithAPIKey ( os . Getenv ( "TRACELIT_API_KEY" )),
tracelit . WithServiceName ( "my-api" ),
tracelit . WithEnvironment ( "production" ),
tracelit . WithSampleRate ( 0.2 ),
)
if err != nil {
slog . Error ( "tracelit init failed" , "error" , err )
os . Exit ( 1 )
}
defer sdk . Shutdown ( context . Background ())
// Route all slog output through Tracelit
slog . SetDefault ( slog . New ( bridge . NewSlogHandler ()))
mux := http . NewServeMux ()
mux . HandleFunc ( "POST /orders" , func ( w http . ResponseWriter , r * http . Request ) {
ctx , span := tracelit . StartServerSpan ( r . Context (), "create-order" )
defer span . End ()
slog . InfoContext ( ctx , "creating order" )
if err := processOrder ( ctx ); err != nil {
span . RecordError ( err )
http . Error ( w , "internal error" , http . StatusInternalServerError )
return
}
w . WriteHeader ( http . StatusCreated )
})
srv := & http . Server {
Addr : ":8080" ,
Handler : middleware . NewHTTPHandler ( mux ),
}
quit := make ( chan os . Signal , 1 )
signal . Notify ( quit , syscall . SIGTERM , syscall . SIGINT )
go func () { _ = srv . ListenAndServe () }()
<- quit
_ = srv . Shutdown ( context . Background ())
}
GitHub
Source code and issue tracker: github.com/Tracelit-AI/tracelit-go