diff --git a/README.md b/README.md index 66b71ed837..441f57f9f8 100644 --- a/README.md +++ b/README.md @@ -184,6 +184,9 @@ spec: - tracecontext - baggage - b3 + sampler: + type: parentbased_traceidratio + argument: "0.25" java: image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest # <1> EOF diff --git a/apis/instrumentation/v1alpha1/instrumentation_types.go b/apis/instrumentation/v1alpha1/instrumentation_types.go index 405c09112a..48b29748fd 100644 --- a/apis/instrumentation/v1alpha1/instrumentation_types.go +++ b/apis/instrumentation/v1alpha1/instrumentation_types.go @@ -33,6 +33,11 @@ type InstrumentationSpec struct { // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true Propagators []Propagator `json:"propagators,omitempty"` + // Sampler defines sampling configuration. + // +optional + // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true + Sampler `json:"sampler,omitempty"` + // Java defines configuration for java auto-instrumentation. // +optional // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true @@ -55,6 +60,22 @@ type Exporter struct { Endpoint string `json:"endpoint,omitempty"` } +// Sampler defines sampling configuration. +type Sampler struct { + // Type defines sampler type. + // The value can be for instance parentbased_always_on, parentbased_always_off, parentbased_traceidratio... + // +optional + // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true + Type SamplerType `json:"type,omitempty"` + + // Argument defines sampler argument. + // The value depends on the sampler type. + // For instance for parentbased_traceidratio sampler type it is a number in range [0..1] e.g. 0.25. + // +optional + // +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true + Argument string `json:"argument,omitempty"` +} + // InstrumentationStatus defines status of the instrumentation. type InstrumentationStatus struct { } diff --git a/apis/instrumentation/v1alpha1/propagation.go b/apis/instrumentation/v1alpha1/propagators.go similarity index 100% rename from apis/instrumentation/v1alpha1/propagation.go rename to apis/instrumentation/v1alpha1/propagators.go diff --git a/apis/instrumentation/v1alpha1/samplers.go b/apis/instrumentation/v1alpha1/samplers.go new file mode 100644 index 0000000000..beb01b7cee --- /dev/null +++ b/apis/instrumentation/v1alpha1/samplers.go @@ -0,0 +1,40 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1alpha1 + +type ( + // SamplerType represents sampler type. + // +kubebuilder:validation:Enum=always_on;always_off;traceidratio;parentbased_always_on;parentbased_always_off;parentbased_traceidratio;jaeger_remote;xray + SamplerType string +) + +const ( + // AlwaysOn represents AlwaysOnSampler. + AlwaysOn SamplerType = "always_on" + // AlwaysOff represents AlwaysOffSampler. + AlwaysOff SamplerType = "always_off" + // TraceIDRatio represents TraceIdRatioBased. + TraceIDRatio SamplerType = "traceidratio" + // ParentBasedAlwaysOn represents ParentBased(root=AlwaysOnSampler). + ParentBasedAlwaysOn SamplerType = "parentbased_always_on" + // ParentBasedAlwaysOff represents ParentBased(root=AlwaysOffSampler). + ParentBasedAlwaysOff SamplerType = "parentbased_always_off" + // ParentBasedTraceIDRatio represents ParentBased(root=TraceIdRatioBased). + ParentBasedTraceIDRatio SamplerType = "parentbased_traceidratio" + // JaegerRemote represents JaegerRemoteSampler. + JaegerRemote SamplerType = "jaeger_remote" + // XRay represents AWS X-Ray Centralized Sampling. + XRaySampler SamplerType = "xray" +) diff --git a/apis/instrumentation/v1alpha1/zz_generated.deepcopy.go b/apis/instrumentation/v1alpha1/zz_generated.deepcopy.go index e57ababe44..ff2ec25734 100644 --- a/apis/instrumentation/v1alpha1/zz_generated.deepcopy.go +++ b/apis/instrumentation/v1alpha1/zz_generated.deepcopy.go @@ -113,6 +113,7 @@ func (in *InstrumentationSpec) DeepCopyInto(out *InstrumentationSpec) { *out = make([]Propagator, len(*in)) copy(*out, *in) } + out.Sampler = in.Sampler out.Java = in.Java } @@ -155,3 +156,18 @@ func (in *JavaSpec) DeepCopy() *JavaSpec { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Sampler) DeepCopyInto(out *Sampler) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sampler. +func (in *Sampler) DeepCopy() *Sampler { + if in == nil { + return nil + } + out := new(Sampler) + in.DeepCopyInto(out) + return out +} diff --git a/bundle/manifests/opentelemetry.io_instrumentations.yaml b/bundle/manifests/opentelemetry.io_instrumentations.yaml index cc75190693..94072224a2 100644 --- a/bundle/manifests/opentelemetry.io_instrumentations.yaml +++ b/bundle/manifests/opentelemetry.io_instrumentations.yaml @@ -79,6 +79,28 @@ spec: description: ResourceAttributes defines attributes that are added to resource. type: object + sampler: + description: Sampler defines sampling configuration. + properties: + argument: + description: Argument defines sampler argument. The value depends + on the sampler type. For instance for parentbased_traceidratio + sampler type it is a number in range [0..1] e.g. 0.25. + type: string + type: + description: Type defines sampler type. The value can be for instance + parentbased_always_on, parentbased_always_off, parentbased_traceidratio... + enum: + - always_on + - always_off + - traceidratio + - parentbased_always_on + - parentbased_always_off + - parentbased_traceidratio + - jaeger_remote + - xray + type: string + type: object type: object status: description: InstrumentationStatus defines status of the instrumentation. diff --git a/config/crd/bases/opentelemetry.io_instrumentations.yaml b/config/crd/bases/opentelemetry.io_instrumentations.yaml index 0eef557165..bcd0cc196f 100644 --- a/config/crd/bases/opentelemetry.io_instrumentations.yaml +++ b/config/crd/bases/opentelemetry.io_instrumentations.yaml @@ -81,6 +81,28 @@ spec: description: ResourceAttributes defines attributes that are added to resource. type: object + sampler: + description: Sampler defines sampling configuration. + properties: + argument: + description: Argument defines sampler argument. The value depends + on the sampler type. For instance for parentbased_traceidratio + sampler type it is a number in range [0..1] e.g. 0.25. + type: string + type: + description: Type defines sampler type. The value can be for instance + parentbased_always_on, parentbased_always_off, parentbased_traceidratio... + enum: + - always_on + - always_off + - traceidratio + - parentbased_always_on + - parentbased_always_off + - parentbased_traceidratio + - jaeger_remote + - xray + type: string + type: object type: object status: description: InstrumentationStatus defines status of the instrumentation. diff --git a/pkg/instrumentation/sdk.go b/pkg/instrumentation/sdk.go index 54971731ab..bf32506ca3 100644 --- a/pkg/instrumentation/sdk.go +++ b/pkg/instrumentation/sdk.go @@ -34,6 +34,8 @@ const ( envOTELExporterOTLPEndpoint = "OTEL_EXPORTER_OTLP_ENDPOINT" envOTELResourceAttrs = "OTEL_RESOURCE_ATTRIBUTES" envOTELPropagators = "OTEL_PROPAGATORS" + envOTELTracesSampler = "OTEL_TRACES_SAMPLER" + envOTELTracesSamplerArg = "OTEL_TRACES_SAMPLER_ARG" ) // inject a new sidecar container to the given pod, based on the given OpenTelemetryCollector. @@ -90,6 +92,24 @@ func injectCommonSDKConfig(otelinst v1alpha1.Instrumentation, ns corev1.Namespac }) } + idx = getIndexOfEnv(container.Env, envOTELTracesSampler) + // configure sampler only if it is configured in the CR + if idx == -1 && otelinst.Spec.Sampler.Type != "" { + idxSamplerArg := getIndexOfEnv(container.Env, envOTELTracesSamplerArg) + if idxSamplerArg == -1 { + container.Env = append(container.Env, corev1.EnvVar{ + Name: envOTELTracesSampler, + Value: string(otelinst.Spec.Sampler.Type), + }) + if otelinst.Spec.Sampler.Argument != "" { + container.Env = append(container.Env, corev1.EnvVar{ + Name: envOTELTracesSamplerArg, + Value: otelinst.Spec.Sampler.Argument, + }) + } + } + } + return pod } diff --git a/pkg/instrumentation/sdk_test.go b/pkg/instrumentation/sdk_test.go index e736605067..f421f69c0a 100644 --- a/pkg/instrumentation/sdk_test.go +++ b/pkg/instrumentation/sdk_test.go @@ -40,6 +40,10 @@ func TestSDKInjection(t *testing.T) { Endpoint: "https://collector:4317", }, Propagators: []v1alpha1.Propagator{"b3", "jaeger"}, + Sampler: v1alpha1.Sampler{ + Type: "parentbased_traceidratio", + Argument: "0.25", + }, }, }, pod: corev1.Pod{ @@ -81,6 +85,14 @@ func TestSDKInjection(t *testing.T) { Name: "OTEL_PROPAGATORS", Value: "b3,jaeger", }, + { + Name: "OTEL_TRACES_SAMPLER", + Value: "parentbased_traceidratio", + }, + { + Name: "OTEL_TRACES_SAMPLER_ARG", + Value: "0.25", + }, }, }, }, @@ -98,6 +110,10 @@ func TestSDKInjection(t *testing.T) { "fromcr": "val", }, Propagators: []v1alpha1.Propagator{"jaeger"}, + Sampler: v1alpha1.Sampler{ + Type: "parentbased_traceidratio", + Argument: "0.25", + }, }, }, pod: corev1.Pod{ @@ -125,6 +141,10 @@ func TestSDKInjection(t *testing.T) { Name: "OTEL_PROPAGATORS", Value: "b3", }, + { + Name: "OTEL_TRACES_SAMPLER", + Value: "always_on", + }, }, }, }, @@ -155,6 +175,10 @@ func TestSDKInjection(t *testing.T) { Name: "OTEL_PROPAGATORS", Value: "b3", }, + { + Name: "OTEL_TRACES_SAMPLER", + Value: "always_on", + }, }, }, }, diff --git a/tests/e2e/instrumentation-java/00-install-instrumentation.yaml b/tests/e2e/instrumentation-java/00-install-instrumentation.yaml index 48091c25ed..1a87e317ef 100644 --- a/tests/e2e/instrumentation-java/00-install-instrumentation.yaml +++ b/tests/e2e/instrumentation-java/00-install-instrumentation.yaml @@ -8,5 +8,9 @@ spec: propagators: - jaeger - b3 + endpoint: http://localhost:4318 + sampler: + type: parentbased_traceidratio + argument: "0.25" java: image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest diff --git a/tests/e2e/instrumentation-java/01-assert.yaml b/tests/e2e/instrumentation-java/01-assert.yaml index 7049893072..a6da38d36c 100644 --- a/tests/e2e/instrumentation-java/01-assert.yaml +++ b/tests/e2e/instrumentation-java/01-assert.yaml @@ -17,6 +17,10 @@ spec: - name: OTEL_RESOURCE_ATTRIBUTES - name: OTEL_PROPAGATORS value: jaeger,b3 + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: "0.25" - name: JAVA_TOOL_OPTIONS value: " -javaagent:/otel-auto-instrumentation/javaagent.jar" volumeMounts: