.NET Auto-Instrumentation

Want to use OpenTelemetry instead? Read these docs to get started!

If your app is written in .NET, you can get started quickly with Cloud Observability. Download the Auto-Installer, then configure it to communicate with your Cloud Observability Microsatellites. When you deploy your app, all supported libraries will begin sending trace data to Cloud Observability.

These Auto-Installers are forked from Datadog’s contribution of their tracers to the OpenTelemetry project. You can find the original Datadog docs here.

Supported .NET Versions

The .NET Tracer supports automatic instrumentation on the following runtimes:

  • .NET Framework >=4.5 on Windows
  • .NET Core >=2.1 on Windows, Linux

There is an issue in .NET Core versions 2.1.0, 2.1.1, and 2.1.2 that can prevent profilers from working correctly. This issue is fixed in .NET Core 2.1.3. See this GitHub issue for more details.

The .NET Tracer works on .NET Core 2.0, 2.2, and 3.0, but these versions reached their end of life and are no longer supported by Microsoft. See Microsoft’s support policy for more details. We recommend using the latest patch version of .NET Core 2.1 or 3.1.

Install the Auto-Installer

Installation procedures depend on the host operating system: .NET Framework on Windows, .NET Core on Windows or .NET Core on Linux. Each environment uses these installation components:

  • Native COM library that implements the Profiling API (a .dll file on Windows or .so on Linux) to intercept method calls
  • Managed library (Datadog.Trace.dll) that interact with your application to measure method execution time and extract data from method arguments
  • Several environment variables that enable the Profiling API and configure the .NET Auto-Installer

.NET Framework on Windows

  1. Install the .NET Tracer on the host using the MSI installer for Windows. Choose the platform that matches the OS architecture. The native library is deployed into Program Files by default and registered as a COM library in the Windows Registry by the MSI installer. Managed libraries are deployed into the Global Assembly Cache (GAC) by the MSI installer, where any .NET Framework application can access them.

  2. Set these two environment variables before starting your application to enable automatic instrumentation (not necessary if running IIS)

    The .NET runtime tries to load a profiler into any .NET process that is started while these environment variables are set. You should limit profiling only to the applications that need to be traced. Do not set these environment variables globally as this causes all .NET processes on the host to load the profiler.

    1
    2
    
     COR_ENABLE_PROFILING=1
     COR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
    

    To set environment variables for a Windows Service, use the multi-string key HKLM\System\CurrentControlSet\Services\{service name}\Environment in the Windows Registry.

.NET Core on Windows

  1. Install the .NET Tracer on the host using the MSI installer for Windows. Choose the platform that matches the OS architecture. The native library is deployed into Program Files by default and registered as a COM library in the Windows Registry by the MSI installer. Managed libraries are deployed into the Global Assembly Cache (GAC) by the MSI installer, where any .NET Framework application can access them.

  2. Set these two environment variables before starting your application to enable automatic instrumentation (not necessary if running IIS)

    The .NET runtime tries to load a profiler into any .NET process that is started while these environment variables are set. You should limit profiling only to the applications that need to be traced. Do not set these environment variables globally as this causes all .NET processes on the host to load the profiler.

    1
    2
    
     CORECLR_ENABLE_PROFILING=1
     CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
    

    To set environment variables for a Windows Service, use the multi-string key HKLM\System\CurrentControlSet\Services\{service name}\Environment in the Windows Registry.

.NET Core on Linux

  1. Install the .NET Auto-Instrumentation on the host using the using one of the packages available from the ls-trace-dotnet releases page.

Start tabs

Debian or Ubuntu

1
2
curl -LO https://github.com/LightStep/ls-trace-dotnet/releases/download/v<TRACER_VERSION>/lightstep-dotnet-apm_<TRACER_VERSION>_amd64.deb
sudo dpkg -i ./lightstep-dotnet-apm_<TRACER_VERSION>_amd64.deb

CentOS or Fedora

1
2
curl -LO https://github.com/LightStep/ls-trace-dotnet/releases/download/v<TRACER_VERSION>/lightstep-dotnet-apm-<TRACER_VERSION>-1.x86_64.rpm
sudo rpm -Uvh lightstep-dotnet-apm-<TRACER_VERSION>-1.x86_64.rpm

Alpine

1
2
3
sudo mkdir -p /opt/datadog
curl -L https://github.com/DataDog/dd-trace-dotnet/releases/download/v<TRACER_VERSION>/datadog-dotnet-apm-<TRACER_VERSION>-musl.tar.gz \
| sudo tar xzf - -C /opt/datadog

Other Distributions

1
2
3
sudo mkdir -p /opt/datadog
curl -L https://github.com/lightstep/ls-trace-dotnet/releases/download/v<TRACER_VERSION>/lightstep-dotnet-apm-<TRACER_VERSION>.tar.gz \
| sudo tar xzf - -C /opt/datadog

End code tabs

The native and managed libraries are deployed into /opt/datadog/ by default, or manually if using the tar package.

  1. Set environment variables.

    The .NET runtime tries to load a profiler into any .NET process that is started while these environment variables are set. You should limit profiling only to the applications that need to be traced. Do not set these environment variables globally as this causes all .NET processes on the host to load the profiler.

    1
    2
    3
    4
    5
    
     CORECLR_ENABLE_PROFILING=1
     CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
     CORECLR_PROFILER_PATH=/opt/datadog/Datadog.Trace.ClrProfiler.Native.so
     DD_INTEGRATIONS=/opt/datadog/integrations.json
     DD_DOTNET_TRACER_HOME=/opt/datadog
    

    For example, to set them from a bash file before starting your application:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
     # Set environment variables
     export CORECLR_ENABLE_PROFILING=1
     export CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
     export CORECLR_PROFILER_PATH=/opt/datadog/Datadog.Trace.ClrProfiler.Native.so
     export DD_INTEGRATIONS=/opt/datadog/integrations.json
     export DD_DOTNET_TRACER_HOME=/opt/datadog
    
     # Start your application
     dotnet example.dll
    

    To set the environment variables for a systemd service, use Environment=:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
     [Unit]
     Description=example
    
     [Service]
     ExecStart=/usr/bin/dotnet /app/example.dll
     Restart=always
     Environment=CORECLR_ENABLE_PROFILING=1
     Environment=CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
     Environment=CORECLR_PROFILER_PATH=/opt/datadog/Datadog.Trace.ClrProfiler.Native.so
     Environment=DD_INTEGRATIONS=/opt/datadog/integrations.json
     Environment=DD_DOTNET_TRACER_HOME=/opt/datadog
    
     [Install]
     WantedBy=multi-user.target
    

    To set the environment variables on a Linux container in Docker, use ENV:

    1
    2
    3
    4
    5
    
     ENV CORECLR_ENABLE_PROFILING=1
     ENV CORECLR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}
     ENV CORECLR_PROFILER_PATH=/opt/datadog/Datadog.Trace.ClrProfiler.Native.so
     ENV DD_INTEGRATIONS=/opt/datadog/integrations.json
     ENV DD_DOTNET_TRACER_HOME=/opt/datadog
    

Configure the Auto-Installer to Send Data to Cloud Observability

To send data from your system to Cloud Observability, you need to configure the Auto-Installer to:

  • Point to your Microsatellites
  • Send global tags required by Cloud Observability to ingest and display the data to you.

To configure the Auto-Installer:

  1. Configure the Auto-Installer to point to the Cloud Observability Microsatellites by setting these environment variables. Use the right values, depending on if you are using on-premise or Cloud Observability public Microsatellites, or Developer Mode Satellites.

    Start tabs

    On-Premise Microsatellites

    1
    2
    
     DD_TRACE_AGENT_URL=http[s]://<Satellite host>:<Satellite port>
     DD_SERVICE_NAME=<SERVICE_NAME>
    

    Public Microsatellites

    1
    2
    
     DD_TRACE_AGENT_URL=http[s]://ingest.lightstep.com:443
     DD_SERVICE_NAME=<SERVICE_NAME>
    

    Developer Mode

    1
    2
    
     DD_TRACE_AGENT_URL=http://localhost:8360
     DD_SERVICE_NAME=<SERVICE_NAME>
    

    End code tabs

    The host and port values for on-premise is your pool address, found in your configuration file.

  2. Set these global tags on all spans using environment variables:

    • lightstep.service_name: The name of the service from which spans originate. This tag allows Cloud Observability to accurately report on your services, with features such as the Service diagram and the Service Directory
    • lightstep.access_token: The access token for the project the tracers report to. Cloud Observability Microsatellites need this token to accept and store span data from the tracer. Reports from clients with invalid or deactivated access tokens will be rejected on ingress.

      1
      
        DD_TRACE_GLOBAL_TAGS=lightstep.service_name:<SERVICE_NAME>,lightstep.access_token:<ACCESS_TOKEN>
      

Troubleshooting

Following are issues you may have after instrumentation, and how to resolve them.

Operation Names Aren’t Human Readable

Symptom
Operation names in Cloud Observability are not clear or are very long and unhelpful.

This feature requires a Satellite upgrade to the June 2020 release.

This can happen because the auto-installer is getting the name from a parameter in Datadog that might not be appropriate for your language. You can set that parameter to different values to see if that results in better operation names.

You can use either the resource or the name parameter, or both.

Which to use (or if using the both, the order to use) depends on the language of the installer. Refer to the Datadog docs for more info.

To configure how the operation name is set, add the following parameter to your Microsatellite configuration:

1
2
3
4
5
receivers:
  datadog:
	operation_name_extractors:
  	  - resource
  	  - name

If you set both, the order of the values matters. Cloud Observability tries to extract a name from the first variable value. If one isn’t found, it looks for the second value and uses that.

What’s Auto-Instrumented

Framework or libraryNuGet package namePackage versionsIntegration Name
ASP.NET Core1Microsoft.AspNetCore and Microsoft.AspNetCore.App2.0+ and 3.0+AspNetCore
ADO.NET 2System.Data.Common and System.Data.SqlClient4.0+AdoNet
WebClient / WebRequestSystem.Net.Requests4.0+WebRequest
HttpClient / HttpClientHandlerSystem.Net.Http4.0+HttpMessageHandler
Redis (StackExchange client)StackExchange.Redis1.0.187+StackExchangeRedis
Redis (ServiceStack client)ServiceStack.Redis4.0.48+ServiceStackRedis
ElasticsearchNEST / Elasticsearch.Net5.3.0+ElasticsearchNet
MongoDBMongoDB.Driver.Core2.1.0+MongoDb
PostgreSQLNpgsql4.0+AdoNet

Notes:

1: The AspNetCore integration adds instrumentation to any ASP.NET application based on System.Web.HttpApplication, which can include applications developed with Web Forms, MVC, Web API, and other web frameworks.

2: The AdoNet integration tries to instrument all ADO.NET providers. Datadog tested SQL Server (System.Data.SqlClient) and PostgreSQL (Npgsql). Other providers (MySQL, SQLite, Oracle) are untested but should work.

See also

Measure your instrumentation quality

Updated Mar 3, 2020