Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions api/v1alpha1/envoygateway_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,23 @@ func (e *EnvoyGateway) DisablePrometheus() bool {
return e.GetEnvoyGatewayTelemetry().Metrics.Prometheus.Disable
}

// DisableTraces returns true if tracing is disabled.
func (e *EnvoyGateway) DisableTraces() bool {
return e.GetEnvoyGatewayTelemetry().Traces.Disable
}

// DefaultEnvoyGatewayTelemetry returns a new EnvoyGatewayTelemetry with default configuration parameters.
func DefaultEnvoyGatewayTelemetry() *EnvoyGatewayTelemetry {
return &EnvoyGatewayTelemetry{
Metrics: DefaultEnvoyGatewayMetrics(),
Traces: DefaultEnvoyGatewayTraces(),
}
}

// DefaultEnvoyGatewayTraces returns a new EnvoyGatewayTraces with default configuration parameters.
func DefaultEnvoyGatewayTraces() *EnvoyGatewayTraces {
return &EnvoyGatewayTraces{
Disable: true,
}
}

Expand Down
75 changes: 75 additions & 0 deletions api/v1alpha1/envoygateway_traces_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

package v1alpha1

import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"

// EnvoyGatewayTraces defines control plane tracing configurations.
type EnvoyGatewayTraces struct {
// Sink defines the trace sink where traces are sent to.
Sink EnvoyGatewayTraceSink `json:"sink,omitempty"`
// Disable disables the traces.
//
// +optional
Disable bool `json:"disable,omitempty"`
// SamplingRate controls the rate at which traces are sampled.
// Defaults to 1.0 (100% sampling). Valid values are between 0.0 and 1.0.
// 0.0 means no sampling, 1.0 means all traces are sampled.
//
// +optional
// +kubebuilder:validation:Minimum=0.0
// +kubebuilder:validation:Maximum=1.0
SamplingRate *float64 `json:"samplingRate,omitempty"`
// BatchSpanProcessorConfig defines the configuration for the batch span processor.
// This processor batches spans before exporting them to the configured sink.
//
// +optional
BatchSpanProcessorConfig *BatchSpanProcessorConfig `json:"batchSpanProcessor,omitempty"`
}

// BatchSpanProcessorConfig defines the configuration for the OpenTelemetry batch span processor.
// The batch span processor batches spans before sending them to the exporter.
type BatchSpanProcessorConfig struct {
// BatchTimeout is the maximum duration for constructing a batch. Spans are
// exported when either the batch is full or this timeout is reached.
//
// +optional
BatchTimeout *gwapiv1.Duration `json:"batchTimeout,omitempty"`
// MaxExportBatchSize is the maximum number of spans to export in a single batch.
// Default is 512.
//
// +optional
// +kubebuilder:validation:Minimum=1
MaxExportBatchSize *int `json:"maxExportBatchSize,omitempty"`
// MaxQueueSize is the maximum queue size to buffer spans for delayed processing.
// If the queue gets full it drops the spans. Default is 2048.
//
// +optional
// +kubebuilder:validation:Minimum=1
MaxQueueSize *int `json:"maxQueueSize,omitempty"`
}

// TraceSinkType specifies the types of trace sinks supported by Envoy Gateway.
// +kubebuilder:validation:Enum=OpenTelemetry
type TraceSinkType string

const (
// TraceSinkTypeOpenTelemetry captures traces for the OpenTelemetry sink.
TraceSinkTypeOpenTelemetry TraceSinkType = "OpenTelemetry"
)

// EnvoyGatewayTraceSink defines control plane
// trace sinks where traces are sent to.
type EnvoyGatewayTraceSink struct {
// Type defines the trace sink type.
// EG control plane currently supports OpenTelemetry.
// +kubebuilder:validation:Enum=OpenTelemetry
// +kubebuilder:default=OpenTelemetry
Type TraceSinkType `json:"type"`
// OpenTelemetry defines the configuration for OpenTelemetry sink.
// It's required if the sink type is OpenTelemetry.
OpenTelemetry *EnvoyGatewayOpenTelemetrySink `json:"openTelemetry,omitempty"`
}
2 changes: 2 additions & 0 deletions api/v1alpha1/envoygateway_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ type LeaderElection struct {
type EnvoyGatewayTelemetry struct {
// Metrics defines metrics configuration for envoy gateway.
Metrics *EnvoyGatewayMetrics `json:"metrics,omitempty"`
// Traces defines traces configuration for envoy gateway.
Traces *EnvoyGatewayTraces `json:"traces,omitempty"`
}

// EnvoyGatewayLogging defines logging for Envoy Gateway.
Expand Down
81 changes: 81 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ require (
go.opentelemetry.io/otel v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0
go.opentelemetry.io/otel/exporters/prometheus v0.61.0
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0
go.opentelemetry.io/otel/metric v1.39.0
Expand Down Expand Up @@ -286,7 +288,6 @@ require (
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
Expand Down
107 changes: 102 additions & 5 deletions internal/traces/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ package traces

import (
"context"
"fmt"
"time"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"

egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
)

Expand All @@ -29,6 +33,16 @@ func New(cfg *config.Server) *Runner {
}

func (r *Runner) Start(ctx context.Context) error {
if r.cfg.EnvoyGateway.DisableTraces() {
return nil
}

tracesConfig := r.cfg.EnvoyGateway.GetEnvoyGatewayTelemetry().Traces
sinkConfig := tracesConfig.Sink
configObj := sinkConfig.OpenTelemetry

endpoint := fmt.Sprintf("%s:%d", sinkConfig.OpenTelemetry.Host, sinkConfig.OpenTelemetry.Port)

// Create resource
res, err := resource.New(ctx,
resource.WithAttributes(
Expand All @@ -39,16 +53,99 @@ func (r *Runner) Start(ctx context.Context) error {
return err
}

tp := trace.NewTracerProvider(
trace.WithResource(res),
)
// Get sampler configuration
sampler := r.getSampler(tracesConfig)

// Get batch span processor options
batchOptions := r.getBatchSpanProcessorOptions(tracesConfig)

if configObj.Protocol == egv1a1.GRPCProtocol {
exporter, err := otlptracegrpc.New(ctx,
otlptracegrpc.WithEndpoint(endpoint),
otlptracegrpc.WithInsecure(),
)
if err != nil {
return err
}

otel.SetTracerProvider(tp)
r.tp = tp
bsp := trace.NewBatchSpanProcessor(exporter, batchOptions...)
tp := trace.NewTracerProvider(
trace.WithSpanProcessor(bsp),
trace.WithResource(res),
trace.WithSampler(sampler),
)

otel.SetTracerProvider(tp)
r.tp = tp

return nil
}

if configObj.Protocol == egv1a1.HTTPProtocol {
// Create OTLP HTTP exporter
exporter, err := otlptracehttp.New(ctx,
otlptracehttp.WithEndpoint(endpoint),
otlptracehttp.WithInsecure(),
)
if err != nil {
return err
}

bsp := trace.NewBatchSpanProcessor(exporter, batchOptions...)
tp := trace.NewTracerProvider(
trace.WithSpanProcessor(bsp),
trace.WithResource(res),
trace.WithSampler(sampler),
)

otel.SetTracerProvider(tp)
r.tp = tp

return nil
}

return nil
}

// getSampler returns the configured sampler or a default sampler
func (r *Runner) getSampler(tracesConfig *egv1a1.EnvoyGatewayTraces) trace.Sampler {
if tracesConfig.SamplingRate != nil {
return trace.TraceIDRatioBased(*tracesConfig.SamplingRate)
}
// Default to always sample (100%)
return trace.AlwaysSample()
}

// getBatchSpanProcessorOptions returns the configured batch span processor options
func (r *Runner) getBatchSpanProcessorOptions(tracesConfig *egv1a1.EnvoyGatewayTraces) []trace.BatchSpanProcessorOption {
var options []trace.BatchSpanProcessorOption

if tracesConfig.BatchSpanProcessorConfig != nil {
cfg := tracesConfig.BatchSpanProcessorConfig

if cfg.BatchTimeout != nil {
timeout, err := time.ParseDuration(string(*cfg.BatchTimeout))
if err == nil && timeout > 0 {
options = append(options, trace.WithBatchTimeout(timeout))
}
}

if cfg.MaxExportBatchSize != nil && *cfg.MaxExportBatchSize > 0 {
options = append(options, trace.WithMaxExportBatchSize(*cfg.MaxExportBatchSize))
}

if cfg.MaxQueueSize != nil && *cfg.MaxQueueSize > 0 {
options = append(options, trace.WithMaxQueueSize(*cfg.MaxQueueSize))
}
}

// If no options were configured, use defaults
// Default BatchTimeout is 5s, MaxExportBatchSize is 512, MaxQueueSize is 2048
// These are the OpenTelemetry SDK defaults

return options
}

func (r *Runner) Name() string {
return "traces"
}
Expand Down
4 changes: 3 additions & 1 deletion internal/traces/register_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ func TestTracesRunner_New(t *testing.T) {
cfg := &config.Server{
EnvoyGateway: &egv1a1.EnvoyGateway{
EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
Telemetry: &egv1a1.EnvoyGatewayTelemetry{},
Telemetry: &egv1a1.EnvoyGatewayTelemetry{
Traces: &egv1a1.EnvoyGatewayTraces{},
},
},
},
}
Expand Down
Loading
Loading