Skip to content

Commit

Permalink
[feature] Enable injecting only core SDK config
Browse files Browse the repository at this point in the history
Closes #990.

Adds support for injecting SDK environment variables only,
without injecting language-specific libraries or config.

Usage:

```bash
instrumentation.opentelemetry.io/inject-sdk: "true"
```
  • Loading branch information
bilbof committed Jul 26, 2022
1 parent 5ef2c0f commit cb37cb9
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 2 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ Python:
instrumentation.opentelemetry.io/inject-python: "true"
```

OpenTelemetry SDK environment variables only:
```bash
instrumentation.opentelemetry.io/inject-sdk: "true"
```

The possible values for the annotation can be
* `"true"` - inject and `Instrumentation` resource from the namespace.
* `"my-instrumentation"` - name of `Instrumentation` CR instance in the current namespace.
Expand Down Expand Up @@ -273,9 +278,17 @@ spec:
image: your-customized-auto-instrumentation-image:python
```

The Dockerfiles for auto-instrumentation can be found in [autoinstrumentation directory](./autoinstrumentation).
The Dockerfiles for auto-instrumentation can be found in [autoinstrumentation directory](./autoinstrumentation).
Follow the instructions in the Dockerfiles on how to build a custom container image.

#### Inject OpenTelemetry SDK environment variables only

You can configure the OpenTelemetry SDK for applications which can't currently be autoinstrumented by using `inject-sdk` in place of (e.g.) `inject-python` or `inject-java`. This will inject environment variables like `OTEL_RESOURCE_ATTRIBUTES`, `OTEL_TRACES_SAMPLER`, and `OTEL_EXPORTER_OTLP_ENDPOINT`, that you can configure in the `Instrumentation`, but will not actually provide the SDK.

```bash
instrumentation.opentelemetry.io/inject-sdk: "true"
```

## Compatibility matrix

### OpenTelemetry Operator vs. OpenTelemetry Collector
Expand Down
1 change: 1 addition & 0 deletions pkg/instrumentation/annotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
annotationInjectJava = "instrumentation.opentelemetry.io/inject-java"
annotationInjectNodeJS = "instrumentation.opentelemetry.io/inject-nodejs"
annotationInjectPython = "instrumentation.opentelemetry.io/inject-python"
annotationInjectSdk = "instrumentation.opentelemetry.io/inject-sdk"
annotationInjectContainerName = "instrumentation.opentelemetry.io/container-names"
)

Expand Down
10 changes: 9 additions & 1 deletion pkg/instrumentation/podmutator.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type languageInstrumentations struct {
Java *v1alpha1.Instrumentation
NodeJS *v1alpha1.Instrumentation
Python *v1alpha1.Instrumentation
Sdk *v1alpha1.Instrumentation
}

var _ webhookhandler.PodMutator = (*instPodMutator)(nil)
Expand Down Expand Up @@ -95,7 +96,14 @@ func (pm *instPodMutator) Mutate(ctx context.Context, ns corev1.Namespace, pod c
}
insts.Python = inst

if insts.Java == nil && insts.NodeJS == nil && insts.Python == nil {
if inst, err = pm.getInstrumentationInstance(ctx, ns, pod, annotationInjectSdk); err != nil {
// we still allow the pod to be created, but we log a message to the operator's logs
logger.Error(err, "failed to select an OpenTelemetry Instrumentation instance for this pod")
return pod, err
}
insts.Sdk = inst

if insts.Java == nil && insts.NodeJS == nil && insts.Python == nil && insts.Sdk == nil {
logger.V(1).Info("annotation not present in deployment, skipping instrumentation injection")
return pod, nil
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/instrumentation/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ func (i *sdkInjector) inject(ctx context.Context, insts languageInstrumentations
pod = i.injectCommonEnvVar(otelinst, pod, index)
pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index)
}
if insts.Sdk != nil {
otelinst := *insts.Sdk
i.logger.V(1).Info("injecting sdk-only instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name)
pod = i.injectCommonEnvVar(otelinst, pod, index)
pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index)
}
return pod
}

Expand Down
67 changes: 67 additions & 0 deletions pkg/instrumentation/sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -670,3 +670,70 @@ func TestInjectPython(t *testing.T) {
},
}, pod)
}

func TestInjectSdkOnly(t *testing.T) {
inst := v1alpha1.Instrumentation{
Spec: v1alpha1.InstrumentationSpec{
Exporter: v1alpha1.Exporter{
Endpoint: "https://collector:4318",
},
},
}
insts := languageInstrumentations{
Sdk: &inst,
}

inj := sdkInjector{
logger: logr.Discard(),
}
pod := inj.inject(context.Background(), insts,
corev1.Namespace{},
corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "app",
},
},
},
}, "")
assert.Equal(t, corev1.Pod{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "app",
Env: []corev1.EnvVar{
{
Name: "OTEL_SERVICE_NAME",
Value: "app",
},
{
Name: "OTEL_EXPORTER_OTLP_ENDPOINT",
Value: "https://collector:4318",
},
{
Name: "OTEL_RESOURCE_ATTRIBUTES_POD_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "metadata.name",
},
},
},
{
Name: "OTEL_RESOURCE_ATTRIBUTES_NODE_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "spec.nodeName",
},
},
},
{
Name: "OTEL_RESOURCE_ATTRIBUTES",
Value: "k8s.container.name=app,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=$(OTEL_RESOURCE_ATTRIBUTES_POD_NAME)",
},
},
},
},
},
}, pod)
}
23 changes: 23 additions & 0 deletions tests/e2e/instrumentation-sdk/00-install-collector.yaml
Original file line number Diff line number Diff line change
@@ -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]
24 changes: 24 additions & 0 deletions tests/e2e/instrumentation-sdk/00-install-instrumentation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: sdk-only
spec:
env:
- name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED
value: "true"
exporter:
endpoint: http://localhost:4317
propagators:
- jaeger
- b3
sampler:
type: parentbased_traceidratio
argument: "0.25"
nodejs:
env:
- name: OTEL_NODEJS_DEBUG
value: "true"
python:
env:
- name: OTEL_ENV_VAR
value: "true"
27 changes: 27 additions & 0 deletions tests/e2e/instrumentation-sdk/01-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
sidecar.opentelemetry.io/inject: "true"
instrumentation.opentelemetry.io/inject-sdk: "true"
labels:
app: my-pod-with-sidecar
spec:
containers:
- name: myapp
env:
- name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED
value: "true"
- name: OTEL_SERVICE_NAME
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://localhost:4317
- name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME
- name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME
- name: OTEL_PROPAGATORS
value: jaeger,b3
- name: OTEL_TRACES_SAMPLER
- name: OTEL_TRACES_SAMPLER_ARG
- name: OTEL_RESOURCE_ATTRIBUTES
- name: otc-container
status:
phase: Running
24 changes: 24 additions & 0 deletions tests/e2e/instrumentation-sdk/01-install-app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment-with-sidecar
spec:
selector:
matchLabels:
app: my-pod-with-sidecar
replicas: 1
template:
metadata:
labels:
app: my-pod-with-sidecar
annotations:
sidecar.opentelemetry.io/inject: "true"
instrumentation.opentelemetry.io/inject-sdk: "true"
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: myapp
image: ghcr.io/anuraaga/express-hello-world:latest

0 comments on commit cb37cb9

Please sign in to comment.