Configure zero-code instrumentation manually
The installer scripts set the environment variables that enable profiler-based zero-code instrumentation for you. If you can't use them, for example when you build container images, configure Windows services or IIS, or deploy with the OpenTelemetry Operator, you must set those variables yourself.
EDOT .NET is a plugin that runs inside the upstream OpenTelemetry .NET automatic instrumentation. If you set up only the upstream variables, the upstream instrumentation runs but the EDOT plugin doesn't load.
You must set OTEL_DOTNET_AUTO_PLUGINS for every manual setup. Without it you get upstream OpenTelemetry .NET automatic instrumentation without the Elastic defaults.
OTEL_DOTNET_AUTO_PLUGINS
Loads the EDOT .NET plugin. Set it to exactly:
Elastic.OpenTelemetry.AutoInstrumentationPlugin, Elastic.OpenTelemetry.AutoInstrumentation
OTEL_DOTNET_AUTO_HOME
The directory where the EDOT .NET distribution is installed, for example $HOME/.otel-dotnet-auto.
DOTNET_STARTUP_HOOKS
Path to net/OpenTelemetry.AutoInstrumentation.StartupHook.dll under OTEL_DOTNET_AUTO_HOME. If the variable already has a value, add the path to the existing list.
Set the variables for your platform in addition to the required variables. <HOME> is the value of OTEL_DOTNET_AUTO_HOME.
| Variable | Value |
|---|---|
CORECLR_ENABLE_PROFILING |
1 |
CORECLR_PROFILER |
{918728DD-259F-4A6A-AC2B-B85E1B658318} |
CORECLR_PROFILER_PATH |
<HOME>/<RID>/OpenTelemetry.AutoInstrumentation.Native.so on Linux, or .dylib on macOS |
Use one of these runtime identifiers (RID) in CORECLR_PROFILER_PATH:
| Platform | RID |
|---|---|
| Linux (glibc) | linux-x64, linux-arm64 |
| Linux (musl, for example Alpine) | linux-musl-x64, linux-musl-arm64 |
| macOS | osx-x64, osx-arm64 |
| Variable | Value | Applies to |
|---|---|---|
CORECLR_ENABLE_PROFILING |
1 |
.NET |
CORECLR_PROFILER |
{918728DD-259F-4A6A-AC2B-B85E1B658318} |
.NET |
CORECLR_PROFILER_PATH_64 |
<HOME>\win-x64\OpenTelemetry.AutoInstrumentation.Native.dll |
.NET |
CORECLR_PROFILER_PATH_32 |
<HOME>\win-x86\OpenTelemetry.AutoInstrumentation.Native.dll |
.NET |
COR_ENABLE_PROFILING |
1 |
.NET Framework |
COR_PROFILER |
{918728DD-259F-4A6A-AC2B-B85E1B658318} |
.NET Framework |
COR_PROFILER_PATH_64 |
<HOME>\win-x64\OpenTelemetry.AutoInstrumentation.Native.dll |
.NET Framework |
COR_PROFILER_PATH_32 |
<HOME>\win-x86\OpenTelemetry.AutoInstrumentation.Native.dll |
.NET Framework |
ASPNETCORE_HOSTINGSTARTUPASSEMBLIES |
OpenTelemetry.AutoInstrumentation.AspNetCoreBootstrapper |
ASP.NET Core |
The COR_ prefix configures .NET Framework and the CORECLR_ prefix configures .NET. The PowerShell module sets these, together with OTEL_DOTNET_AUTO_HOME, DOTNET_STARTUP_HOOKS, and OTEL_DOTNET_AUTO_PLUGINS, for the current session or for a Windows service.
The OpenTelemetry Operator injects the upstream variables into the application container. It sets CORECLR_ENABLE_PROFILING, CORECLR_PROFILER, CORECLR_PROFILER_PATH, DOTNET_STARTUP_HOOKS, DOTNET_ADDITIONAL_DEPS, DOTNET_SHARED_STORE, and OTEL_DOTNET_AUTO_HOME. It doesn't set OTEL_DOTNET_AUTO_PLUGINS.
Add it to the dotnet section of your Instrumentation resource, next to the EDOT .NET image:
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: elastic-instrumentation
spec:
dotnet:
image: docker.elastic.co/observability/elastic-otel-dotnet:<VERSION>
env:
- name: OTEL_DOTNET_AUTO_PLUGINS
value: "Elastic.OpenTelemetry.AutoInstrumentationPlugin, Elastic.OpenTelemetry.AutoInstrumentation"
Replace <VERSION> with the EDOT .NET release you want to use. If you deploy with the kube-stack Helm chart, set the same env under instrumentation.dotnet in your values file.
The operator injects environment variables when it creates a pod, so restart existing workloads after you change the Instrumentation resource.
For the full Kubernetes workflow, including annotations and troubleshooting, refer to Instrument applications on Kubernetes.
Check the resource attributes of the exported telemetry:
| Attribute | EDOT .NET plugin loaded | Plugin not loaded |
|---|---|---|
telemetry.distro.name |
elastic |
opentelemetry-dotnet-instrumentation |
telemetry.distro.version |
The EDOT .NET version | The upstream instrumentation version |
If you see opentelemetry-dotnet-instrumentation, check that OTEL_DOTNET_AUTO_PLUGINS is set in the application's environment. In Kubernetes, run kubectl describe pod and look at the container environment.