diff --git a/api/v1alpha1/tracing_types.go b/api/v1alpha1/tracing_types.go index 8b0c256fec6..6917275dd06 100644 --- a/api/v1alpha1/tracing_types.go +++ b/api/v1alpha1/tracing_types.go @@ -15,7 +15,7 @@ type ProxyTracing struct { // Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. // // Only one of SamplingRate or SamplingFraction may be specified. - // If neither field is specified, 1% of requests will be sampled. + // If neither field is specified, all requests will be sampled. // // +kubebuilder:validation:Minimum=0 // +kubebuilder:validation:Maximum=100 @@ -26,9 +26,8 @@ type ProxyTracing struct { // selected for tracing if no prior sampling decision has been made. // // Only one of SamplingRate or SamplingFraction may be specified. - // If neither field is specified, 1% of requests will be sampled. + // If neither field is specified, all requests will be sampled. // - // +notImplementedHide // +optional SamplingFraction *gwapiv1.Fraction `json:"samplingFraction,omitempty"` // CustomTags defines the custom tags to add to each span. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml index 1bbb323766a..d6dcc22d9c5 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -14443,7 +14443,7 @@ spec: selected for tracing if no prior sampling decision has been made. Only one of SamplingRate or SamplingFraction may be specified. - If neither field is specified, 1% of requests will be sampled. + If neither field is specified, all requests will be sampled. properties: denominator: default: 100 @@ -14468,7 +14468,7 @@ spec: Defaults to 100, valid values [0-100]. 100 indicates 100% sampling. Only one of SamplingRate or SamplingFraction may be specified. - If neither field is specified, 1% of requests will be sampled. + If neither field is specified, all requests will be sampled. format: int32 maximum: 100 minimum: 0 diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index fb18c9efb02..c7efd9eb47f 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -8,6 +8,7 @@ package gatewayapi import ( "errors" "fmt" + "math" "github.com/google/cel-go/cel" corev1 "k8s.io/api/core/v1" @@ -459,11 +460,6 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo authority = host } - samplingRate := 100.0 - if tracing.SamplingRate != nil { - samplingRate = float64(*tracing.SamplingRate) - } - serviceName := naming.ServiceName(utils.NamespacedName(gw)) if mergeGateways { serviceName = string(gw.Spec.GatewayClassName) @@ -472,7 +468,7 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo return &ir.Tracing{ Authority: authority, ServiceName: serviceName, - SamplingRate: samplingRate, + SamplingRate: proxySamplingRate(tracing), CustomTags: tracing.CustomTags, Destination: ir.RouteDestination{ // TODO: rename this, so that we can share backend with accesslog? @@ -484,6 +480,25 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo }, nil } +func proxySamplingRate(tracing *egv1a1.ProxyTracing) float64 { + rate := 100.0 + if tracing.SamplingRate != nil { + rate = float64(*tracing.SamplingRate) + } else if tracing.SamplingFraction != nil { + numerator := float64(tracing.SamplingFraction.Numerator) + denominator := float64(100) + if tracing.SamplingFraction.Denominator != nil { + denominator = float64(*tracing.SamplingFraction.Denominator) + } + + rate = numerator / denominator + // Identifies a percentage, in the range [0.0, 100.0] + rate = math.Max(0, rate) + rate = math.Min(100, rate) + } + return rate +} + func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy, resources *resource.Resources) (*ir.Metrics, error) { if envoyproxy == nil || envoyproxy.Spec.Telemetry == nil || diff --git a/internal/gatewayapi/listener_test.go b/internal/gatewayapi/listener_test.go new file mode 100644 index 00000000000..97e5d73aa48 --- /dev/null +++ b/internal/gatewayapi/listener_test.go @@ -0,0 +1,84 @@ +// 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 gatewayapi + +import ( + "testing" + + "k8s.io/utils/ptr" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" +) + +func TestProxySamplingRate(t *testing.T) { + cases := []struct { + name string + tracing *egv1a1.ProxyTracing + expected float64 + }{ + { + name: "default", + tracing: &egv1a1.ProxyTracing{}, + expected: 100.0, + }, + { + name: "rate", + tracing: &egv1a1.ProxyTracing{ + SamplingRate: ptr.To[uint32](10), + }, + expected: 10.0, + }, + { + name: "fraction numerator only", + tracing: &egv1a1.ProxyTracing{ + SamplingFraction: &gwapiv1.Fraction{ + Numerator: 100, + }, + }, + expected: 1.0, + }, + { + name: "fraction", + tracing: &egv1a1.ProxyTracing{ + SamplingFraction: &gwapiv1.Fraction{ + Numerator: 1, + Denominator: ptr.To[int32](10), + }, + }, + expected: 0.1, + }, + { + name: "less than zero", + tracing: &egv1a1.ProxyTracing{ + SamplingFraction: &gwapiv1.Fraction{ + Numerator: 1, + Denominator: ptr.To[int32](-1), + }, + }, + expected: 0, + }, + { + name: "greater than 100", + tracing: &egv1a1.ProxyTracing{ + SamplingFraction: &gwapiv1.Fraction{ + Numerator: 101, + Denominator: ptr.To[int32](1), + }, + }, + expected: 100, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + actual := proxySamplingRate(tc.tracing) + if actual != tc.expected { + t.Errorf("expected %v, got %v", tc.expected, actual) + } + }) + } +} diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 7fc3929250b..67daed8d070 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -31,6 +31,7 @@ new features: | Added support for GEP-1731 (HTTPRoute Retries) Added support for routing to Backend resources in the GRPCRoute, TCPRoute and UDPRoute APIs Added support for configuring Max GRPC message size for the Extension Manager in EnvoyGateway config + Added support for configuring tracing sampling rate with Fraction. bug fixes: | Fixed the ability to overwrite control plane certs with the certgen command by using a new command arg (-o) diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 9584b896530..71fedaf1d1b 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -3427,7 +3427,8 @@ _Appears in:_ | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | -| `samplingRate` | _integer_ | false | 100 | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling.

Only one of SamplingRate or SamplingFraction may be specified.
If neither field is specified, 1% of requests will be sampled. | +| `samplingRate` | _integer_ | false | 100 | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling.

Only one of SamplingRate or SamplingFraction may be specified.
If neither field is specified, all requests will be sampled. | +| `samplingFraction` | _[Fraction](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Fraction)_ | false | | SamplingFraction represents the fraction of requests that should be
selected for tracing if no prior sampling decision has been made.

Only one of SamplingRate or SamplingFraction may be specified.
If neither field is specified, all requests will be sampled. | | `customTags` | _object (keys:string, values:[CustomTag](#customtag))_ | true | | CustomTags defines the custom tags to add to each span.
If provider is kubernetes, pod name and namespace are added by default. | | `provider` | _[TracingProvider](#tracingprovider)_ | true | | Provider defines the tracing provider. | diff --git a/site/content/zh/latest/api/extension_types.md b/site/content/zh/latest/api/extension_types.md index 9584b896530..71fedaf1d1b 100644 --- a/site/content/zh/latest/api/extension_types.md +++ b/site/content/zh/latest/api/extension_types.md @@ -3427,7 +3427,8 @@ _Appears in:_ | Field | Type | Required | Default | Description | | --- | --- | --- | --- | --- | -| `samplingRate` | _integer_ | false | 100 | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling.

Only one of SamplingRate or SamplingFraction may be specified.
If neither field is specified, 1% of requests will be sampled. | +| `samplingRate` | _integer_ | false | 100 | SamplingRate controls the rate at which traffic will be
selected for tracing if no prior sampling decision has been made.
Defaults to 100, valid values [0-100]. 100 indicates 100% sampling.

Only one of SamplingRate or SamplingFraction may be specified.
If neither field is specified, all requests will be sampled. | +| `samplingFraction` | _[Fraction](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Fraction)_ | false | | SamplingFraction represents the fraction of requests that should be
selected for tracing if no prior sampling decision has been made.

Only one of SamplingRate or SamplingFraction may be specified.
If neither field is specified, all requests will be sampled. | | `customTags` | _object (keys:string, values:[CustomTag](#customtag))_ | true | | CustomTags defines the custom tags to add to each span.
If provider is kubernetes, pod name and namespace are added by default. | | `provider` | _[TracingProvider](#tracingprovider)_ | true | | Provider defines the tracing provider. | diff --git a/tools/crd-ref-docs/config.yaml b/tools/crd-ref-docs/config.yaml index c29ec42ff40..6d568dca85f 100644 --- a/tools/crd-ref-docs/config.yaml +++ b/tools/crd-ref-docs/config.yaml @@ -31,3 +31,6 @@ render: - name: PolicyStatus package: sigs.k8s.io/gateway-api/apis/v1alpha2 link: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.PolicyStatus + - name: Fraction + package: sigs.k8s.io/gateway-api/apis/v1 + link: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Fraction diff --git a/tools/make/docs.mk b/tools/make/docs.mk index d6fcfe8832c..314d47f8729 100644 --- a/tools/make/docs.mk +++ b/tools/make/docs.mk @@ -4,7 +4,7 @@ RELEASE_VERSIONS ?= $(foreach v,$(wildcard ${ROOT_DIR}/docs/*),$(notdir ${v})) # find a way to remove github.com from ignore list # TODO: example.com is not a valid domain, we should remove it from ignore list # TODO: https://www.gnu.org/software/make became unstable, we should remove it from ignore list later -LINKINATOR_IGNORE := "github.com githubusercontent.com example.com github.io gnu.org _print" +LINKINATOR_IGNORE := "github.com jwt.io githubusercontent.com example.com github.io gnu.org _print" CLEAN_NODE_MODULES ?= true ##@ Docs