otelprofiling

package module
v0.0.0-...-9a8a47a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 5, 2024 License: Apache-2.0 Imports: 4 Imported by: 0

README

otel-profiling-go

This package provides an integration between distributed tracing via OpenTelemetry with Profiling data collected via eBPF by Parca Agent. The best thing about this is that it isn't actually a deep integration with Parca Agent, it just puts the trace ID into a place that Parca Agent will know how to find.

Note: Currently Parca Agent only supports reading the trace ID in Go 1.22.

More specifically it provides three ways to do so:

  • An OpenTelemetry Tracer implementation
  • A gRPC middleware
  • An HTTP middleware

What these provide are ways to automatically set Go's goroutine labels. Goroutine labels are then accessible to Parca Agent via eBPF, as they are stored in thread-local-store, which the Go runtime manages, which has a well-known layout, so it is easy for the Parca Agent to know how to read them.

Using the Tracer

The tracer is the simplest way to get started, as it can be used as a drop-in replacement for your existing tracer, and you're all set! The tracer is also the least efficient, as it causes allocations with every new span that's created.

import (
	otelprof "github.com/polarsignals/otel-profiling-go"
)

main() {
	tp := initTracer()
	otel.SetTracerProvider(otelprof.NewTracerProvider(tp))

	// your application...
}

See a full example in ./tracer-example.

Middleware

Our recommendation is to use a middleware approach, where the trace ID is set once per request, causing only constant allocations, instead of allocations per span.

HTTP

For HTTP use the handler wrapper. Make sure it is called after an initial trace ID has been set on the context.

import (
	"github.com/polarsignals/otel-profiling-go/otelhttpprofiling"
	"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)

func main() {
	handler := otelhttp.NewHandler(otelhttpprofiling.Handler(http.HandlerFunc(fibHandler)), "fibHandler")

	// ... actually serve handler
}

See a full example in ./http-example.

gRPC

For gRPC use the gRPC middleware. Same as the HTTP middleware, ensure that it is after the otel interceptors to ensure a trace ID is already set on the context.

import (
	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
)

main() {
	otel.SetTracerProvider(initTracer())

	grpcotelprof := otelgrpcprofiling.NewMiddleware()
	server := grpc.NewServer(
		grpc_middleware.WithUnaryServerChain(
			otelgrpc.UnaryServerInterceptor(),
			grpcotelprof.GrpcUnaryInterceptor,
		),
		grpc_middleware.WithStreamServerChain(
			otelgrpc.StreamServerInterceptor(),
			grpcotelprof.GrpcStreamInterceptor,
		),
	)

	// ... register gRPC services, serve it, etc.
}

See a full example in ./grpc-example.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewTracerProvider

func NewTracerProvider(tp trace.TracerProvider, options ...Option) trace.TracerProvider

NewTracerProvider creates a new tracer provider that annotates pprof samples with span_id label. This allows to establish a relationship between pprof profiles and reported tracing spans.

Types

type Option

type Option func(*tracerProvider)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL