diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 0d19a0c869..0c0e066abb 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -196,8 +196,9 @@ var ( utils.RPCTxSyncDefaultTimeoutFlag, utils.RPCTxSyncMaxTimeoutFlag, utils.RPCGlobalRangeLimitFlag, - utils.RPCTracingFlag, - utils.RPCTracingEndpointFlag, + utils.RPCTelemetryFlag, + utils.RPCTelemetryEndpointFlag, + utils.RPCTelemetrySampleRatioFlag, } metricsFlags = []cli.Flag{ diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index fe240a15c1..8a252c53c3 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1043,16 +1043,23 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server. Category: flags.MetricsCategory, } - // RPC Tracing - RPCTracingFlag = &cli.BoolFlag{ - Name: "rpc.tracing", - Usage: "Enable RPC tracing", + // RPC Telemetry + RPCTelemetryFlag = &cli.BoolFlag{ + Name: "rpc.telemetry", + Usage: "Enable RPC telemetry", Category: flags.APICategory, } - RPCTracingEndpointFlag = &cli.StringFlag{ - Name: "rpc.tracing.endpoint", - Usage: "Defines where RPC traces are sent (e.g., http://localhost:4318)", + RPCTelemetryEndpointFlag = &cli.StringFlag{ + Name: "rpc.telemetry.endpoint", + Usage: "Defines where RPC telemetry is sent (e.g., http://localhost:4318)", + Category: flags.APICategory, + } + + RPCTelemetrySampleRatioFlag = &cli.Float64Flag{ + Name: "rpc.telemetry.sample-ratio", + Usage: "Defines the sampling ratio for RPC telemetry (0.0 to 1.0)", + Value: 1.0, Category: flags.APICategory, } ) diff --git a/cmd/utils/telemetry.go b/cmd/utils/telemetry.go index e54168a2ab..2c2cd7a4bb 100644 --- a/cmd/utils/telemetry.go +++ b/cmd/utils/telemetry.go @@ -1,4 +1,4 @@ -// Copyright 2025 The go-ethereum Authors +// Copyright 2026 The go-ethereum Authors // This file is part of go-ethereum. // // go-ethereum is free software: you can redistribute it and/or modify @@ -18,6 +18,7 @@ package utils import ( "context" + "fmt" "time" "github.com/ethereum/go-ethereum/internal/telemetry/config" @@ -26,21 +27,21 @@ import ( "github.com/urfave/cli/v2" ) -// telemetryService wraps the telemetry Provider to implement node.Lifecycle. +// telemetryService wraps the TelemetryProvider to implement node.Lifecycle. type telemetryService struct { - provider *config.Provider + telemetryProvider *config.TelemetryProvider } // Start implements node.Lifecycle. func (t *telemetryService) Start() error { - return nil // Provider is already started during setup + return nil // TelemetryProvider is already started during setup } // Stop implements node.Lifecycle. func (t *telemetryService) Stop() error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - if err := t.provider.Shutdown(ctx); err != nil { + if err := t.telemetryProvider.Shutdown(ctx); err != nil { log.Error("Failed to stop telemetry service", "err", err) return err } @@ -50,13 +51,17 @@ func (t *telemetryService) Stop() error { // SetupTelemetry initializes OpenTelemetry tracing based on CLI flags. func SetupTelemetry(ctx *cli.Context) (*telemetryService, error) { - if !ctx.Bool(RPCTracingFlag.Name) { + if !ctx.Bool(RPCTelemetryFlag.Name) { return nil, nil } - endpoint := ctx.String(RPCTracingEndpointFlag.Name) + endpoint := ctx.String(RPCTelemetryEndpointFlag.Name) if endpoint == "" { return nil, nil } + sampleRatio := ctx.Float64(RPCTelemetrySampleRatioFlag.Name) + if sampleRatio < 0 || sampleRatio > 1 { + return nil, fmt.Errorf("invalid sample ratio: %f", sampleRatio) + } setupCtx := ctx.Context if setupCtx == nil { setupCtx = context.Background() @@ -66,12 +71,13 @@ func SetupTelemetry(ctx *cli.Context) (*telemetryService, error) { handle, err := config.Setup( setupCtx, endpoint, + sampleRatio, ) if err != nil { return nil, err } log.Info("Telemetry enabled", "endpoint", endpoint) - return &telemetryService{provider: handle}, nil + return &telemetryService{telemetryProvider: handle}, nil } // RegisterTelemetryService registers the telemetryService with the node. diff --git a/internal/telemetry/config/config.go b/internal/telemetry/config/config.go index c0d56231bf..5c242e6241 100644 --- a/internal/telemetry/config/config.go +++ b/internal/telemetry/config/config.go @@ -1,4 +1,4 @@ -// Copyright 2025 The go-ethereum Authors +// Copyright 2026 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -31,18 +31,18 @@ import ( semconv "go.opentelemetry.io/otel/semconv/v1.38.0" ) -// Provider wraps a TracerProvider and exposes a Shutdown method. -type Provider struct { +// TelemetryProvider wraps a TracerProvider and exposes the Shutdown method. +type TelemetryProvider struct { tracerProvider *sdktrace.TracerProvider } -// Shutdown shuts down the tracer provider. -func (p *Provider) Shutdown(ctx context.Context) error { - return p.tracerProvider.Shutdown(ctx) +// Shutdown shuts down the TracerProvider. +func (t *TelemetryProvider) Shutdown(ctx context.Context) error { + return t.tracerProvider.Shutdown(ctx) } -// Setup initializes OpenTelemetry tracing with the given parameters. -func Setup(ctx context.Context, endpoint string) (*Provider, error) { +// Setup initializes telemetry with the given parameters. +func Setup(ctx context.Context, endpoint string, sampleRatio float64) (*TelemetryProvider, error) { // Create exporter based on endpoint URL u, err := url.Parse(endpoint) if err != nil { @@ -68,6 +68,10 @@ func Setup(ctx context.Context, endpoint string) (*Provider, error) { return nil, fmt.Errorf("failed to create telemetry exporter: %w", err) } + // If no parent span is available, then sampleRatio of traces are sampled; + // otherwise, inherit the parent's sampling decision. + sampler := sdktrace.ParentBased(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(sampleRatio))) + // Create resource with service and client information res := resource.NewWithAttributes( semconv.SchemaURL, @@ -77,6 +81,7 @@ func Setup(ctx context.Context, endpoint string) (*Provider, error) { // Create TracerProvider tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sampler), sdktrace.WithBatcher(exporter), sdktrace.WithResource(res), ) @@ -91,5 +96,5 @@ func Setup(ctx context.Context, endpoint string) (*Provider, error) { propagation.Baggage{}, )) - return &Provider{tracerProvider: tp}, nil + return &TelemetryProvider{tracerProvider: tp}, nil }