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 ab00e8c commit 434c366
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 3 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,19 @@ DotNet:
instrumentation.opentelemetry.io/inject-dotnet: "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.
* `"my-other-namespace/my-instrumentation"` - name and namespace of `Instrumentation` CR instance in another namespace.
* `"false"` - do not inject


>**Note:** For `DotNet` auto-instrumentation, by default, operator sets the `OTEL_DOTNET_AUTO_TRACES_ENABLED_INSTRUMENTATIONS` environment variable which specifies the list of traces source instrumentations you want to enable. The value that is set by default by the operator is all available instrumentations supported by the `openTelemery-dotnet-instrumentation` release consumed in the image, i.e. `AspNet,HttpClient,SqlClient`. This value can be overriden by configuring the environment variable explicitely.
>**Note:** For `DotNet` auto-instrumentation, by default, operator sets the `OTEL_DOTNET_AUTO_TRACES_ENABLED_INSTRUMENTATIONS` environment variable which specifies the list of traces source instrumentations you want to enable. The value that is set by default by the operator is all available instrumentations supported by the `openTelemery-dotnet-instrumentation` release consumed in the image, i.e. `AspNet,HttpClient,SqlClient`. This value can be overriden by configuring the environment variable explicitely.
#### Multi-container pods

Expand Down Expand Up @@ -283,9 +288,17 @@ spec:
image: your-customized-auto-instrumentation-image:dotnet
```

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 @@ -27,6 +27,7 @@ const (
annotationInjectNodeJS = "instrumentation.opentelemetry.io/inject-nodejs"
annotationInjectPython = "instrumentation.opentelemetry.io/inject-python"
annotationInjectDotNet = "instrumentation.opentelemetry.io/inject-dotnet"
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 @@ -44,6 +44,7 @@ type languageInstrumentations struct {
NodeJS *v1alpha1.Instrumentation
Python *v1alpha1.Instrumentation
DotNet *v1alpha1.Instrumentation
Sdk *v1alpha1.Instrumentation
}

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

if insts.Java == nil && insts.NodeJS == nil && insts.Python == nil && insts.DotNet == 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.DotNet == nil && insts.Sdk == nil {
logger.V(1).Info("annotation not present in deployment, skipping instrumentation injection")
return pod, nil
}
Expand Down
7 changes: 7 additions & 0 deletions pkg/instrumentation/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ 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 @@ -776,3 +776,70 @@ func TestInjectDotNet(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 434c366

Please sign in to comment.