# .NET zero-code instrumentation

> Send traces and metrics from .NET applications and services.

---

Site [llms.txt](/ro/llms.txt)

---

Use the OpenTelemetry .NET Automatic Instrumentation to send traces and metrics
from .NET applications and services to observability backends without having to
modify their source code.

To learn how to instrument your service or application code, read
[Manual instrumentation](/docs/languages/dotnet/instrumentation).

## Compatibility

OpenTelemetry .NET Automatic Instrumentation should work with all officially
supported operating systems and versions of
[.NET](https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core).

The minimal supported version of
[.NET Framework](https://dotnet.microsoft.com/download/dotnet-framework) is
`4.6.2`.

Supported processor architectures are:

- x86
- AMD64 (x86-64)
- ARM64 ([Experimental](/docs/specs/otel/versioning-and-stability))

> [!NOTE]
>
> ARM64 build does not support CentOS based images.

CI tests run against the following operating systems:

- [Alpine x64](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/main/docker/alpine.dockerfile)
- [Alpine ARM64](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/main/docker/alpine.dockerfile)
- [Debian x64](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/main/docker/debian.dockerfile)
- [Debian ARM64](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/main/docker/debian-arm64.dockerfile)
- [CentOS Stream 9 x64](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/blob/main/docker/centos-stream9.dockerfile)
- [macOS Sonoma 14 ARM64](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md)
- [Microsoft Windows Server 2022 x64](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md)
- [Microsoft Windows Server 2025 x64](https://github.com/actions/runner-images/blob/main/images/windows/Windows2025-Readme.md)
- [Ubuntu 22.04 LTS x64](https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md)
- [Ubuntu 22.04 LTS ARM64](https://github.com/actions/partner-runner-images/blob/main/images/arm-ubuntu-22-image.md)

## Setup

To instrument a .NET application automatically, download and run the installer
script for your operating system.

### Linux and macOS

Download, verify, and run the `.sh` script:

> [!NOTE]
>
> On macOS [`coreutils`](https://formulae.brew.sh/formula/coreutils) is
> required.
>
> The downloaded installer should be verified before it is executed because a
> script cannot establish trust in its own code. By default, the installer also
> requires the [GitHub CLI](https://cli.github.com/) and verifies both the
> immutable release and artifact attestation for the downloaded ZIP archive. To
> explicitly opt out of archive verification, set
> `SKIP_RELEASE_VERIFICATION=true`. Skipping verification is not recommended.

```shell
# Download the installer into a private directory
version="v1.17.0"
repository="open-telemetry/opentelemetry-dotnet-instrumentation"
release_workflow="$repository/.github/workflows/release.yml"
download_dir="$(mktemp -d "${TMPDIR:-/tmp}/otel-dotnet-auto-installer.XXXXXX")"
installer="$download_dir/otel-dotnet-auto-install.sh"
trap 'rm -rf "$download_dir"' 0

# Download, verify, and run the installer as a single conditional chain so a
# failed download or verification prevents the installer from running
curl -sSfL "https://github.com/$repository/releases/download/$version/otel-dotnet-auto-install.sh" -o "$installer" &&
  gh release verify-asset "$version" "$installer" --repo "$repository" &&
  gh attestation verify "$installer" \
    --repo "$repository" \
    --signer-workflow "$release_workflow" \
    --source-ref "refs/tags/$version" &&
  VERSION="$version" sh "$installer"

# Enable execution for the instrumentation script
chmod +x $HOME/.otel-dotnet-auto/instrument.sh

# Setup the instrumentation for the current shell session
. $HOME/.otel-dotnet-auto/instrument.sh

# Run your application with instrumentation
OTEL_SERVICE_NAME=myapp OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=staging,service.version=1.0.0 ./MyNetApp
```

For air-gapped environments, verify the archive before transferring it and
explicitly skip the installer's online verification. You can provide the archive
directly with:

```shell
SKIP_RELEASE_VERIFICATION=true LOCAL_PATH=<PATH_TO_ARCHIVE> sh ./otel-dotnet-auto-install.sh
```

Alternatively, provide the folder with the files, and the install script
determines the correct file to use:

```shell
SKIP_RELEASE_VERIFICATION=true DOWNLOAD_DIR=<PATH_TO_FOLDER_WITH_FILES> sh ./otel-dotnet-auto-install.sh
```

> [!IMPORTANT]
>
> If you have [Homebrew](https://brew.sh/) installed on macOS, you can install
> `coreutils` by running:
>
> ```shell
> brew install coreutils
> ```

### Windows (PowerShell)

On Windows, use the PowerShell module as an Administrator.

> [!NOTE] Requirements
>
> Windows
> [PowerShell Desktop](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_windows_powershell_5.1#powershell-editions)
> (v5.1) is required. Other
> [versions](https://learn.microsoft.com/previous-versions/powershell/scripting/overview),
> including PowerShell Core (v6.0+) are not supported at this time.
>
> The downloaded module should be verified before it is imported because a
> module cannot establish trust in its own code. By default, installation
> requires the [GitHub CLI](https://cli.github.com/) and verifies both the
> immutable release and artifact attestation. To explicitly opt out, set
> `$skip_release_verification` to `$true`; this also passes
> `-SkipReleaseVerification` to `Install-OpenTelemetryCore` for the Windows
> archive. Skipping verification is not recommended.

```powershell
# PowerShell 5.1 is required
#Requires -PSEdition Desktop

$version = "v1.17.0"
$repository = "open-telemetry/opentelemetry-dotnet-instrumentation"
$release_workflow = "$repository/.github/workflows/release.yml"
$skip_release_verification = $false

# Use a unique directory protected by the Program Files access controls.
$program_files = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::ProgramFiles)
$download_dir = Join-Path $program_files "OpenTelemetry .NET AutoInstrumentation Download $([System.Guid]::NewGuid().ToString("N"))"
$download_path = Join-Path $download_dir "OpenTelemetry.DotNet.Auto.psm1"
$module_url = "https://github.com/$repository/releases/download/$version/OpenTelemetry.DotNet.Auto.psm1"

New-Item -ItemType Directory -Path $download_dir -ErrorAction Stop | Out-Null

try {
    Invoke-WebRequest -Uri $module_url -OutFile $download_path -UseBasicParsing

    if ($skip_release_verification) {
        Write-Warning "Release verification is skipped. Downloaded PowerShell code and binaries will not be verified."
    }
    else {
        $github_cli = Get-Command gh.exe -CommandType Application -ErrorAction SilentlyContinue | Select-Object -First 1
        if (-not $github_cli) {
            throw "The GitHub CLI ('gh') is required. Install it from https://cli.github.com/ or explicitly set `$skip_release_verification to `$true."
        }

        & $github_cli.Source release verify-asset $version $download_path --repo $repository
        if ($LASTEXITCODE -ne 0) {
            throw "GitHub release verification failed for the PowerShell module."
        }

        & $github_cli.Source attestation verify $download_path `
            --repo $repository `
            --signer-workflow $release_workflow `
            --source-ref "refs/tags/$version"
        if ($LASTEXITCODE -ne 0) {
            throw "GitHub artifact attestation verification failed for the PowerShell module."
        }
    }

    # Import the module only after successful verification.
    Import-Module $download_path

    # To install from a previously downloaded Windows archive, add:
    # -LocalPath "C:\Path\To\OpenTelemetry.zip"
    Install-OpenTelemetryCore -SkipReleaseVerification:$skip_release_verification -ErrorAction Stop

    # Cache the verified module for updates and uninstallation.
    Copy-Item -LiteralPath $download_path -Destination (Get-OpenTelemetryInstallDirectory) -Force
}
finally {
    if (Test-Path -LiteralPath $download_dir) {
        Remove-Item -LiteralPath $download_dir -Force -Recurse
    }
}

# Set up the instrumentation for the current PowerShell session
Register-OpenTelemetryForCurrentSession -OTelServiceName "MyServiceDisplayName"

# Run your application with instrumentation
.\MyNetApp.exe

# You can get usage information by calling the following commands

# List all available commands
Get-Command -Module OpenTelemetry.DotNet.Auto

# Get command's usage information
Get-Help Install-OpenTelemetryCore -Detailed
```

## Instrument a Windows Service running a .NET application

Use the `OpenTelemetry.DotNet.Auto.psm1` PowerShell module to set up automatic
instrumentation for a Windows Service:

```powershell
# Import the module
Import-Module "OpenTelemetry.DotNet.Auto.psm1"

# Install core files
Install-OpenTelemetryCore

# Set up your Windows Service instrumentation
Register-OpenTelemetryForWindowsService -WindowsServiceName "WindowsServiceName" -OTelServiceName "MyServiceDisplayName"
```

> [!CAUTION]
>
> `Register-OpenTelemetryForWindowsService` performs a service restart.

### Configuration for Windows Service

> [!IMPORTANT]
>
> Remember to restart the Windows Service after making configuration changes.
> You can do it by running `Restart-Service -Name $WindowsServiceName -Force` in
> PowerShell.

For .NET Framework applications you can configure
[the most common `OTEL_` settings](/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration)
(like `OTEL_RESOURCE_ATTRIBUTES`) via `appSettings` in `App.config`.

The alternative is to set environment variables for the Windows Service in the
Windows Registry.

The registry key of a given Windows Service (named `$svcName`) is located under:

```powershell
HKLM\SYSTEM\CurrentControlSet\Services\$svcName
```

The environment variables are defined in a `REG_MULTI_SZ` (multiline registry
value) called `Environment` in the following format:

```env
Var1=Value1
Var2=Value2
```

## Instrument an ASP.NET application deployed on IIS

> [!NOTE]
>
> The following instructions apply to .NET Framework applications.

Use the `OpenTelemetry.DotNet.Auto.psm1` PowerShell module to set up automatic
instrumentation for IIS:

```powershell
# Import the module
Import-Module "OpenTelemetry.DotNet.Auto.psm1"

# Install core files
Install-OpenTelemetryCore

# Setup IIS instrumentation
Register-OpenTelemetryForIIS
```

> [!CAUTION]
>
> `Register-OpenTelemetryForIIS` performs an IIS restart.

### Configuration for ASP.NET applications

> [!NOTE]
>
> The following instructions apply to .NET Framework applications.

For ASP.NET applications you can configure
[the most common `OTEL_` settings](/docs/specs/otel/configuration/sdk-environment-variables/#general-sdk-configuration)
(like `OTEL_SERVICE_NAME`) via `appSettings` in `Web.config`.

If a service name is not explicitly configured, one will be generated for you.
If the application is hosted on IIS in .NET Framework this will use
`SiteName\VirtualDirectoryPath` ex: `MySite\MyApp`

For ASP.NET Core application you can use the
[`<environmentVariable>`](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/web-config#set-environment-variables)
elements inside the `<aspNetCore>` block of your `Web.config` file to set
configuration via environment variables.

> [!IMPORTANT]
>
> Remember to restart IIS after making configuration changes. You can do it by
> executing `iisreset.exe`.

### Advanced configuration

You can add the
[`<environmentVariables>`](https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/applicationpools/add/environmentvariables/)
in `applicationHost.config` to set environment variables for given application
pools.

Consider setting common environment variables, for all applications deployed to
IIS by setting the environment variables for `W3SVC` and `WAS` Windows Services.

> [!TIP]
>
> For IIS versions older than 10.0, you can consider creating a distinct user,
> set its environment variables and use it as the application pool user.

## NuGet package

You can instrument
[`self-contained`](https://learn.microsoft.com/en-us/dotnet/core/deploying/#publish-as-self-contained)
applications using the NuGet packages. See [NuGet packages](./nuget-packages)
for more information.

## Instrument a container

For an example of Docker container instrumentation, see
[the example](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/tree/main/examples/demo)
on GitHub.

You can also use the
[OpenTelemetry Operator for Kubernetes](/docs/platforms/kubernetes/operator/).

## Configuring the agent

To see the full range of configuration options, see
[Configuration and settings](./configuration).

## Log to trace correlation

> [!NOTE]
>
> Automatic log to trace correlation provided by OpenTelemetry .NET Automatic
> Instrumentation currently works only for .NET applications using
> `Microsoft.Extensions.Logging`. For more details, see [#2310][].

[#2310]:
  https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/issues/2310

OpenTelemetry .NET SDK automatically correlates logs to trace data. When logs
are emitted in the context of an active trace, trace context
[fields](/docs/specs/otel/logs/data-model#trace-context-fields) `TraceId`,
`SpanId`, `TraceState` are automatically populated.

The following are logs produced by the sample console application:

```json
"logRecords": [
    {
        "timeUnixNano": "1679392614538226700",
        "severityNumber": 9,
        "severityText": "Information",
        "body": {
            "stringValue": "Success! Today is: {Date:MMMM dd, yyyy}"
        },
        "flags": 1,
        "traceId": "21df288eada1ce4ace6c40f39a6d7ce1",
        "spanId": "a80119e5a05fed5a"
    }
]
```

For more information, see:

- [OpenTelemetry .NET SDK](https://github.com/open-telemetry/opentelemetry-dotnet/tree/main/docs/logs/correlation)
- [OpenTelemetry Specification](/docs/specs/otel/logs/data-model#trace-context-fields)

## Supported libraries and frameworks

The OpenTelemetry .NET Automatic Instrumentation supports a wide variety of
libraries. For a complete list, see [Instrumentations](./instrumentations).

## Troubleshooting

To see the telemetry from your application directly on the standard output, add
`console` to the following environment variables value before launching your
application:

- `OTEL_TRACES_EXPORTER`
- `OTEL_METRICS_EXPORTER`
- `OTEL_LOGS_EXPORTER`

For general troubleshooting steps and solutions to specific issues, see
[Troubleshooting](./troubleshooting).

## Next steps

After you have automatic instrumentation configured for your app or service, you
might want to [send custom traces and metrics](./custom) or add
[manual instrumentation](/docs/languages/dotnet/instrumentation) to collect
custom telemetry data.

## Uninstall

### Linux and macOS {#uninstall-unix}

On Linux and macOS, the installation steps only affect the current shell session
so no explicit uninstallation is required.

### Windows (PowerShell) {#uninstall-windows}

On Windows, use the PowerShell module as an Administrator.

> [!IMPORTANT] Version note
>
> Windows [PowerShell Desktop][] (v5.1) is required. Other [versions][],
> including PowerShell Core (v6.0+) are not supported at this time.

[PowerShell Desktop]:
  https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_windows_powershell_5.1#powershell-editions
[versions]:
  https://learn.microsoft.com/previous-versions/powershell/scripting/overview

```powershell
# PowerShell 5.1 is required
#Requires -PSEdition Desktop

# Import the previously installed module
Import-Module "OpenTelemetry.DotNet.Auto.psm1"

# If IIS was previously registered, unregister it
Unregister-OpenTelemetryForIIS

# If Windows services were previously registered, unregister them
Unregister-OpenTelemetryForWindowsService -WindowsServiceName "WindowsServiceName"

# Finally, uninstall OpenTelemetry instrumentation
Uninstall-OpenTelemetryCore
```

---

Section pages:

- [Getting Started](/ro/docs/zero-code/dotnet/getting-started/): Get telemetry for your app in less than 5 minutes!
- [Available instrumentations](/ro/docs/zero-code/dotnet/instrumentations/): OpenTelemetry .NET Automatic Instrumentation supported libraries.
- [Configuration and settings](/ro/docs/zero-code/dotnet/configuration/)
- [Create custom traces and metrics](/ro/docs/zero-code/dotnet/custom/): Custom traces and metrics using .NET automatic instrumentation.
- [Using the OpenTelemetry.AutoInstrumentation NuGet packages](/ro/docs/zero-code/dotnet/nuget-packages/)
- [Troubleshooting .NET automatic instrumentation issues](/ro/docs/zero-code/dotnet/troubleshooting/)
