OpenTelemetry Go implementation providing APIs for distributed tracing, metrics, and logging to instrument applications and send telemetry data to observability platforms
Context propagation enables passing trace context and baggage across service boundaries using standardized formats.
import (
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/baggage"
)OpenTelemetry Go supports:
import (
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/propagation"
)
func main() {
// Setup composite propagator
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{},
propagation.Baggage{},
))
}
// Inject context into HTTP headers
func makeRequest(ctx context.Context) {
req, _ := http.NewRequest("GET", "https://api.example.com", nil)
otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
// Send request
}
// Extract context from HTTP headers
func handleRequest(w http.ResponseWriter, r *http.Request) {
ctx := otel.GetTextMapPropagator().Extract(r.Context(),
propagation.HeaderCarrier(r.Header))
// Use context
}type TextMapPropagator interface {
// Inject set cross-cutting concerns from the Context into the carrier.
Inject(ctx context.Context, carrier TextMapCarrier)
// Extract reads cross-cutting concerns from the carrier into a Context.
Extract(ctx context.Context, carrier TextMapCarrier) context.Context
// Fields returns the keys who's values are set with Inject.
Fields() []string
}// W3C Trace Context propagator
type TraceContext struct{}
// W3C Baggage propagator
type Baggage struct{}
// Composite propagator (combines multiple)
func NewCompositeTextMapPropagator(propagators ...TextMapPropagator) TextMapPropagatortype TextMapCarrier interface {
// Get returns the value associated with the passed key.
Get(key string) string
// Set stores the key-value pair.
Set(key, value string)
// Keys lists the keys stored in this carrier.
Keys() []string
}type HeaderCarrier http.Header
func (hc HeaderCarrier) Get(key string) string
func (hc HeaderCarrier) Set(key, value string)
func (hc HeaderCarrier) Keys() []string
func (hc HeaderCarrier) Values(key string) []stringtype MapCarrier map[string]string
func (c MapCarrier) Get(key string) string
func (c MapCarrier) Set(key, value string)
func (c MapCarrier) Keys() []stringtype Baggage struct {
// Has unexported fields.
}
// Create baggage
func New(members ...Member) (Baggage, error)
// Parse from string
func Parse(bStr string) (Baggage, error)
// Get from context
func FromContext(ctx context.Context) Baggage
// Methods
func (b Baggage) Member(key string) Member
func (b Baggage) Members() []Member
func (b Baggage) SetMember(member Member) (Baggage, error)
func (b Baggage) DeleteMember(key string) Baggage
func (b Baggage) Len() int
func (b Baggage) String() stringtype Member struct {
// Has unexported fields.
}
// Create member
func NewMember(key, value string, props ...Property) (Member, error)
func NewMemberRaw(key, value string, props ...Property) (Member, error)
// Methods
func (m Member) Key() string
func (m Member) Value() string
func (m Member) Properties() []Property
func (m Member) String() stringtype Property struct {
// Has unexported fields.
}
// Create property
func NewKeyProperty(key string) (Property, error)
func NewKeyValueProperty(key, value string) (Property, error)
func NewKeyValuePropertyRaw(key, value string) (Property, error)
// Methods
func (p Property) Key() string
func (p Property) Value() (string, bool)
func (p Property) String() string// Store baggage in context
func ContextWithBaggage(parent context.Context, b Baggage) context.Context
// Remove baggage from context
func ContextWithoutBaggage(parent context.Context) context.Contextfunc makeHTTPRequest(ctx context.Context, url string) error {
// Create request
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return err
}
// Inject trace context and baggage
otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
// Make request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
return nil
}func handleRequest(w http.ResponseWriter, r *http.Request) {
// Extract trace context and baggage
ctx := otel.GetTextMapPropagator().Extract(
r.Context(),
propagation.HeaderCarrier(r.Header),
)
// Use extracted context
tracer := otel.Tracer("server")
ctx, span := tracer.Start(ctx, "handle-request")
defer span.End()
// Access baggage
bag := baggage.FromContext(ctx)
userID := bag.Member("user.id").Value()
// Process request...
}// Create baggage members
member1, _ := baggage.NewMemberRaw("user.id", "12345")
member2, _ := baggage.NewMemberRaw("session.id", "abc-123")
// Create baggage
bag, _ := baggage.New(member1, member2)
// Store in context
ctx := baggage.ContextWithBaggage(context.Background(), bag)
// Add to existing baggage
bag = baggage.FromContext(ctx)
member3, _ := baggage.NewMemberRaw("request.id", "xyz-789")
bag, _ = bag.SetMember(member3)
ctx = baggage.ContextWithBaggage(ctx, bag)
// Read from baggage
userID := bag.Member("user.id").Value()
sessionID := bag.Member("session.id").Value()
// Delete member
bag = bag.DeleteMember("session.id")Install with Tessl CLI
npx tessl i tessl/golang-go-opentelemetry-io--otel