From d12243b8497d1f8f6f8d072d4a1c49523e029ad0 Mon Sep 17 00:00:00 2001 From: blakeromano-il Date: Tue, 21 Jun 2022 17:39:21 -0400 Subject: [PATCH 1/4] Add Ability to Override Service Names Signed-off-by: blakeromano-il --- pkg/instrumentation/sdk.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/instrumentation/sdk.go b/pkg/instrumentation/sdk.go index cbaaa7ac91..e45d76191b 100644 --- a/pkg/instrumentation/sdk.go +++ b/pkg/instrumentation/sdk.go @@ -208,6 +208,9 @@ func (i *sdkInjector) injectCommonSDKConfig(ctx context.Context, otelinst v1alph } func chooseServiceName(pod corev1.Pod, resources map[string]string, index int) string { + if name := strings.Split(pod.Annotations["instrumentation.opentelemetry.io/service-name"], ",")[index]; name != "" { + return name + } if name := resources[string(semconv.K8SDeploymentNameKey)]; name != "" { return name } From 0553d518593c0c67b95eef1eb903a7c3154f4d85 Mon Sep 17 00:00:00 2001 From: blakeromano-il Date: Wed, 22 Jun 2022 07:36:31 -0400 Subject: [PATCH 2/4] add information in readme Signed-off-by: blakeromano-il --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 354864a999..042918ccec 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,18 @@ spec: In the above case, `myapp` and `myapp2` containers will be instrumented, `myapp3` will not. +#### Override Service Name + +The service name for containers goes in the following priority list + +* The `instrumentation.opentelemetry.io/service-name` pod annotation (can be `,` seperated list for multiple container services) +* The Deployment Name +* The Statefulset Name +* The Cronjob Name +* The Job Name +* The Pod Name +* The Container Name + #### Use customized or vendor instrumentation By default, the operator uses upstream auto-instrumentation libraries. Custom auto-instrumentation can be configured by From 625869a338be4fccd02243bb658bff47b1e55883 Mon Sep 17 00:00:00 2001 From: blakeromano-il Date: Fri, 24 Jun 2022 20:26:36 -0400 Subject: [PATCH 3/4] add unit test, fix documentation and pr comments --- README.md | 16 +++--- pkg/instrumentation/sdk.go | 3 +- pkg/instrumentation/sdk_test.go | 98 +++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 042918ccec..a89e8f87b6 100644 --- a/README.md +++ b/README.md @@ -256,15 +256,13 @@ In the above case, `myapp` and `myapp2` containers will be instrumented, `myapp3 #### Override Service Name -The service name for containers goes in the following priority list - -* The `instrumentation.opentelemetry.io/service-name` pod annotation (can be `,` seperated list for multiple container services) -* The Deployment Name -* The Statefulset Name -* The Cronjob Name -* The Job Name -* The Pod Name -* The Container Name +The operator automatically determines the most suitable service name from the Kubernetes object names. However the service name can be overridden by the `instrumentation.opentelemetry.io/service-name` annotation in the pod specification. Follows the precedence order for determining the service name: + +1. The `instrumentation.opentelemetry.io/service-name` pod annotation (can be `,` seperated list for multiple container services) +2. The Deployment Name +3. The Statefulset/Cronjob/Job Name +4. The Pod Name +5. The Container Name #### Use customized or vendor instrumentation diff --git a/pkg/instrumentation/sdk.go b/pkg/instrumentation/sdk.go index e45d76191b..c89371e722 100644 --- a/pkg/instrumentation/sdk.go +++ b/pkg/instrumentation/sdk.go @@ -208,7 +208,8 @@ func (i *sdkInjector) injectCommonSDKConfig(ctx context.Context, otelinst v1alph } func chooseServiceName(pod corev1.Pod, resources map[string]string, index int) string { - if name := strings.Split(pod.Annotations["instrumentation.opentelemetry.io/service-name"], ",")[index]; name != "" { + serviceNames := strings.Split(pod.Annotations["instrumentation.opentelemetry.io/service-name"], ",") + if name := serviceNames[index]; name != "" { return name } if name := resources[string(semconv.K8SDeploymentNameKey)]; name != "" { diff --git a/pkg/instrumentation/sdk_test.go b/pkg/instrumentation/sdk_test.go index 304d0d93ad..2a3f64658a 100644 --- a/pkg/instrumentation/sdk_test.go +++ b/pkg/instrumentation/sdk_test.go @@ -357,6 +357,104 @@ func TestSDKInjection(t *testing.T) { }, }, }, + { + name: "Service Name Annotation Added", + inst: v1alpha1.Instrumentation{ + Spec: v1alpha1.InstrumentationSpec{ + Exporter: v1alpha1.Exporter{ + Endpoint: "https://collector:4317", + }, + Resource: v1alpha1.Resource{ + Attributes: map[string]string{ + "fromcr": "val", + }, + }, + Propagators: []v1alpha1.Propagator{"jaeger"}, + Sampler: v1alpha1.Sampler{ + Type: "parentbased_traceidratio", + Argument: "0.25", + }, + }, + }, + pod: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "project1", + Name: "app", + Annotations: map[string]string{ + "instrumentation.opentelemetry.io/service-name": "my-app", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Env: []corev1.EnvVar{ + { + Name: "OTEL_EXPORTER_OTLP_ENDPOINT", + Value: "explicitly_set", + }, + { + Name: "OTEL_PROPAGATORS", + Value: "b3", + }, + { + Name: "OTEL_TRACES_SAMPLER", + Value: "always_on", + }, + { + Name: "OTEL_RESOURCE_ATTRIBUTES", + Value: "foo=bar,k8s.container.name=other,", + }, + }, + }, + }, + }, + }, + expected: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "project1", + Name: "app", + Annotations: map[string]string{ + "instrumentation.opentelemetry.io/service-name": "my-app", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Env: []corev1.EnvVar{ + { + Name: "OTEL_EXPORTER_OTLP_ENDPOINT", + Value: "explicitly_set", + }, + { + Name: "OTEL_PROPAGATORS", + Value: "b3", + }, + { + Name: "OTEL_TRACES_SAMPLER", + Value: "always_on", + }, + { + Name: "OTEL_SERVICE_NAME", + Value: "my-app", + }, + { + Name: "OTEL_RESOURCE_ATTRIBUTES_NODE_NAME", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "spec.nodeName", + }, + }, + }, + { + Name: "OTEL_RESOURCE_ATTRIBUTES", + Value: "foo=bar,k8s.container.name=other,fromcr=val,k8s.namespace.name=project1,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=app", + }, + }, + }, + }, + }, + }, + }, } for _, test := range tests { From 70a4b7781a369c75cc665ee90d26902dc8347307 Mon Sep 17 00:00:00 2001 From: blakeromano-il Date: Mon, 27 Jun 2022 10:25:18 -0400 Subject: [PATCH 4/4] fix readme, sdk.go and add e2e tests --- README.md | 7 ++-- pkg/instrumentation/sdk.go | 3 +- .../00-install-collector.yaml | 23 +++++++++++ .../00-install-instrumentation.yaml | 34 +++++++++++++++ .../01-assert.yaml | 41 +++++++++++++++++++ .../01-install-app.yaml | 21 ++++++++++ 6 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 tests/e2e/instrumentation-service-name-annotation/00-install-collector.yaml create mode 100644 tests/e2e/instrumentation-service-name-annotation/00-install-instrumentation.yaml create mode 100644 tests/e2e/instrumentation-service-name-annotation/01-assert.yaml create mode 100644 tests/e2e/instrumentation-service-name-annotation/01-install-app.yaml diff --git a/README.md b/README.md index a89e8f87b6..a8159e5ce0 100644 --- a/README.md +++ b/README.md @@ -259,10 +259,9 @@ In the above case, `myapp` and `myapp2` containers will be instrumented, `myapp3 The operator automatically determines the most suitable service name from the Kubernetes object names. However the service name can be overridden by the `instrumentation.opentelemetry.io/service-name` annotation in the pod specification. Follows the precedence order for determining the service name: 1. The `instrumentation.opentelemetry.io/service-name` pod annotation (can be `,` seperated list for multiple container services) -2. The Deployment Name -3. The Statefulset/Cronjob/Job Name -4. The Pod Name -5. The Container Name +2. The Deployment/Statefulset/Cronjob/Job Name +3. The Pod Name +4. The Container Name #### Use customized or vendor instrumentation diff --git a/pkg/instrumentation/sdk.go b/pkg/instrumentation/sdk.go index c89371e722..e5e37a1d8b 100644 --- a/pkg/instrumentation/sdk.go +++ b/pkg/instrumentation/sdk.go @@ -37,6 +37,7 @@ import ( const ( volumeName = "opentelemetry-auto-instrumentation" initContainerName = "opentelemetry-auto-instrumentation" + svcNameAnnotation = "instrumentation.opentelemetry.io/service-name" ) // inject a new sidecar container to the given pod, based on the given OpenTelemetryCollector. @@ -208,7 +209,7 @@ func (i *sdkInjector) injectCommonSDKConfig(ctx context.Context, otelinst v1alph } func chooseServiceName(pod corev1.Pod, resources map[string]string, index int) string { - serviceNames := strings.Split(pod.Annotations["instrumentation.opentelemetry.io/service-name"], ",") + serviceNames := strings.Split(pod.Annotations[svcNameAnnotation], ",") if name := serviceNames[index]; name != "" { return name } diff --git a/tests/e2e/instrumentation-service-name-annotation/00-install-collector.yaml b/tests/e2e/instrumentation-service-name-annotation/00-install-collector.yaml new file mode 100644 index 0000000000..f8e1e98e07 --- /dev/null +++ b/tests/e2e/instrumentation-service-name-annotation/00-install-collector.yaml @@ -0,0 +1,23 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: sidecar +spec: + mode: sidecar + config: | + receivers: + otlp: + protocols: + grpc: + http: + processors: + + exporters: + logging: + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [logging] diff --git a/tests/e2e/instrumentation-service-name-annotation/00-install-instrumentation.yaml b/tests/e2e/instrumentation-service-name-annotation/00-install-instrumentation.yaml new file mode 100644 index 0000000000..f77a3f835f --- /dev/null +++ b/tests/e2e/instrumentation-service-name-annotation/00-install-instrumentation.yaml @@ -0,0 +1,34 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: Instrumentation +metadata: + name: java +spec: + env: + - name: OTEL_TRACES_EXPORTER + value: otlp + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://localhost:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: "20" + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: "0.85" + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: "true" + exporter: + endpoint: http://localhost:4317 + propagators: + - jaeger + - b3 + sampler: + type: parentbased_traceidratio + argument: "0.25" + java: + env: + - name: OTEL_JAVAAGENT_DEBUG + value: "true" + - name: OTEL_INSTRUMENTATION_JDBC_ENABLED + value: "false" + - name: SPLUNK_PROFILER_ENABLED + value: "false" diff --git a/tests/e2e/instrumentation-service-name-annotation/01-assert.yaml b/tests/e2e/instrumentation-service-name-annotation/01-assert.yaml new file mode 100644 index 0000000000..83319f9188 --- /dev/null +++ b/tests/e2e/instrumentation-service-name-annotation/01-assert.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + sidecar.opentelemetry.io/inject: "true" + instrumentation.opentelemetry.io/inject-python: "true" + instrumentation.opentelemetry.io/service-name: "ServiceName" + labels: + app: my-pod +spec: + containers: + - name: myapp + env: + - name: PYTHONPATH + value: /otel-auto-instrumentation/opentelemetry/instrumentation/auto_instrumentation:/otel-auto-instrumentation + - name: OTEL_TRACES_EXPORTER + value: otlp_proto_http + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://localhost:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: "20" + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: "0.85" + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: "true" + - name: OTEL_SERVICE_NAME + value: ServiceName + - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME + - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME + - name: OTEL_PROPAGATORS + value: jaeger,b3 + - name: OTEL_RESOURCE_ATTRIBUTES + volumeMounts: + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + - mountPath: /otel-auto-instrumentation + name: opentelemetry-auto-instrumentation + - name: otc-container +status: + phase: Running \ No newline at end of file diff --git a/tests/e2e/instrumentation-service-name-annotation/01-install-app.yaml b/tests/e2e/instrumentation-service-name-annotation/01-install-app.yaml new file mode 100644 index 0000000000..51860d76be --- /dev/null +++ b/tests/e2e/instrumentation-service-name-annotation/01-install-app.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-deployment +spec: + selector: + matchLabels: + app: my-pod + replicas: 1 + template: + metadata: + labels: + app: my-pod + annotations: + sidecar.opentelemetry.io/inject: "true" + instrumentation.opentelemetry.io/inject-python: "true" + instrumentation.opentelemetry.io/service-name: "ServiceName" + spec: + containers: + - name: myapp + image: ghcr.io/anuraaga/flask-hello-world:latest