Tracing .NET Framework Applications

Tracing .NET Framework Applications

Compatibility requirements

Supported .NET Framework runtimes

The .NET Tracer supports instrumentation on .NET Framework 4.5 and above.

For a full list of supported libraries and processor architectures, see Compatibility Requirements.

Installation and getting started

Automatic instrumentation

Notes:
  • Datadog automatic instrumentation relies on the .NET CLR Profiling API. This API allows only one subscriber (for example, APM). To ensure maximum visibility, run only one APM solution in your application environment.
  • If you are using both automatic and custom instrumentation, it is important to keep the package versions (for example, MSI and NuGet) in sync.

Follow these instructions to begin tracing .NET applications:

Applications hosted in IIS

To start tracing an application hosted in IIS:

  1. Install and configure the Windows Datadog Agent.

  2. Download the .NET Tracer MSI installer. Select the MSI installer for the architecture that matches the operating system (x64 or x86).

  3. Run the .NET Tracer MSI installer with administrator privileges.

  4. Stop, then start IIS using the following commands as an administrator:

    Note: You must use a stop and start command. This is not the same as a reset or restart command.
    net stop /y was
    net start w3svc
    
  5. Create application load.

  6. Visit APM Live Traces.

Applications not hosted in IIS

To enable automatic instrumentation on Windows applications not in IIS, you must set two environment variables before starting your application:

NameValue
COR_ENABLE_PROFILING1
COR_PROFILER{846F5F1C-F9AE-4B07-969E-05C26BC060D8}
Note: The .NET runtime tries to load a profiler into any .NET process started with these environment variables set. You should limit instrumentation only to the applications that need to be traced. Don't set these environment variables globally because this causes all .NET processes on the host to load the profiler.
Windows services

To automatically instrument a Windows service, set the COR_ENABLE_PROFILING and COR_PROFILER environment variables:

  1. In the Windows Registry Editor, create a multi-string value named Environment in HKLM\System\CurrentControlSet\Services\<SERVICE NAME>

  2. Set the value data to:

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

Alternatively, you can set the environment variables by using the following PowerShell snippet:

add-env-var.ps1

   [String[]] $v = @("COR_ENABLE_PROFILING=1", "COR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}")
   Set-ItemProperty HKLM:SYSTEM\CurrentControlSet\Services\<NAME> -Name Environment -Value $v
   
Console applications

To automatically instrument a console application, set the COR_ENABLE_PROFILING and COR_PROFILER environment variables from a batch file before starting your application:

rem Set environment variables
SET COR_ENABLE_PROFILING=1
SET COR_PROFILER={846F5F1C-F9AE-4B07-969E-05C26BC060D8}

rem Start application
example.exe

Configure the Datadog Agent for APM

Install and configure the Datadog Agent to receive traces from your instrumented application. By default the Datadog Agent is enabled in your datadog.yaml file under apm_config with enabled: true and listens for trace traffic at receiver_port:8126.

config_template.yaml

## @param apm_config - custom object - optional
## Enter specific configurations for your trace collection.
## Uncomment this parameter and the one below to enable them.
## See https://docs.datadoghq.com/agent/apm/
 apm_config:

  ## @param enabled - boolean - optional - default: true
  ## @env DD_APM_CONFIG_ENABLED - boolean - optional - default: true
  ## Set to true to enable the APM Agent.
   enabled: true

  ## @param env - string - optional - default: none
  ## @env DD_APM_CONFIG_ENV - string - optional - default: none
  ## The environment tag that Traces should be tagged with.
  ## If not set the value will be inherited, in order, from the top level
  ## "env" config option if set and then from the 'env:' tag if present in the
  ## 'tags' top level config option.
   env: none

  ## @param receiver_port - integer - optional - default: 8126
  ## @env DD_APM_CONFIG_RECEIVER_PORT - integer - optional - default: 8126
  ## The port that the trace receiver should listen on.
   receiver_port: 8126

  ## @param receiver_socket - string - optional
  ## @env DD_APM_CONFIG_RECEIVER_SOCKET - string - optional
  ## Accept traces through Unix Domain Sockets.
  ## It is off by default. When set, it must point to a valid socket file.
   receiver_socket: <UNIX_SOCKET_PATH>

  ## @param apm_non_local_traffic - boolean - optional - default: false
  ## @env DD_APM_CONFIG_APM_NON_LOCAL_TRAFFIC - boolean - optional - default: false
  ## Set to true so the Trace Agent listens for non local traffic,
  ## i.e if Traces are being sent to this Agent from another host/container
   apm_non_local_traffic: false

  ## @param apm_dd_url - string - optional
  ## @env DD_APM_CONFIG_APM_DD_URL - string - optional
  ## Define the endpoint and port to hit when using a proxy for APM. The traces are forwarded in TCP
  ## therefore the proxy must be able to handle TCP connections.
   apm_dd_url: <ENDPOINT>:<PORT>

  ## @param extra_sample_rate - float - optional - default: 1.0
  ## @env DD_APM_CONFIG_EXTRA_SAMPLE_RATE - float - optional - default: 1.0
  ## Extra global sample rate to apply on all the traces
  ## This sample rate is combined to the sample rate from the sampler logic, still promoting interesting traces.
  ## From 1 (no extra rate) to 0 (don't sample at all)
   extra_sample_rate: 1.0

  ## @param max_traces_per_second - integer - optional - default: 10
  ## @env DD_APM_CONFIG_MAX_TRACES_PER_SECOND - integer - optional - default: 10
  ## Maximum number of traces per second to sample. The limit is applied over an average over
  ## a few minutes ; much bigger spikes are possible. Set to 0 to disable the limit.
   max_traces_per_second: 10

  ## @param max_events_per_second - integer - optional - default: 200
  ## @env DD_APM_CONFIG_MAX_EVENTS_PER_SECOND - integer - optional - default: 200
  ## Maximum number of APM events per second to sample.
   max_events_per_second: 200

  ## @param max_memory - integer - optional - default: 500000000
  ## @env DD_APM_CONFIG_MAX_MEMORY - integer - optional - default: 500000000
  ## This value is what the Agent aims to use in terms of memory. If surpassed, the API
  ## rate limits incoming requests to aim and stay below this value.
  ## Note: The Agent process is killed if it uses more than 150% of `max_memory`.
  ## Set the `max_memory` parameter to `0` to disable the memory limitation.
   max_memory: 500000000

  ## @param max_cpu_percent - integer - optional - default: 50
  ## @env DD_APM_CONFIG_MAX_CPU_PERCENT - integer - optional - default: 50
  ## The CPU percentage that the Agent aims to use. If surpassed, the API rate limits
  ## incoming requests to aim and stay below this value. Examples: 50 = half a core, 200 = two cores.
  ## Set `max_cpu_percent` to `0` to disable rate limiting based on CPU usage.
   max_cpu_percent: 50

  ## @param obfuscation - object - optional
  ## @env DD_APM_CONFIG_OBFUSCATION_* - optional
  ## Defines obfuscation rules for sensitive data. Disabled by default.
  ## See https://docs.datadoghq.com/tracing/setup_overview/configure_data_security/#agent-trace-obfuscation
   obfuscation:
       <OBFUSCATION_CONFIGURATION>

  ## @param filter_tags - object - optional
  ## Defines rules by which to filter traces based on tags.
  ##  * require - list of key or key/value strings - traces must have those tags in order to be sent to Datadog
  ##  * reject - list of key or key/value strings - traces with these tags are dropped by the Agent
  ## Note: Rules take into account the intersection of tags defined.
   filter_tags:
       require: [<LIST_OF_KEY_VALUE_TAGS>]
       reject: [<LIST_OF_KEY_VALUE_TAGS>]

  ## @param replace_tags - list of objects - optional
  ## @env DD_APM_CONFIG_REPLACE_TAGS  - list of objects - optional
  ## Defines a set of rules to replace or remove certain resources, tags containing
  ## potentially sensitive information.
  ## Each rules has to contain:
  ##  * name - string - The tag name to replace, for resources use "resource.name".
  ##  * pattern - string - The pattern to match the desired content to replace
  ##  * repl - string - what to inline if the pattern is matched
  ##
  ## See https://docs.datadoghq.com/tracing/setup_overview/configure_data_security/#replace-rules-for-tag-filtering
  ##
   replace_tags:
     - name: "<TAG_NAME>"
       pattern: "<REGEX_PATTERN>"
       repl: "<PATTERN_TO_INLINE>"

  ## @param ignore_resources - list of strings - optional
  ## @env DD_APM_CONFIG_IGNORE_RESOURCES - space separated list of strings - optional
  ## An exclusion list of regular expressions can be provided to disable certain traces based on their resource name
  ## all entries must be surrounded by double quotes and separated by commas.
   ignore_resources: ["(GET|POST) /healthcheck"]

  ## @param log_file - string - optional
  ## @env DD_APM_CONFIG_LOG_FILE - string - optional
  ## The full path to the file where APM-agent logs are written.
   log_file: <APM_LOG_FILE_PATH>

  ## @param log_throttling - boolean - default: true
  ## @env DD_APM_CONFIG_LOG_THROTTLING - boolean - default: true
  ## Limits the total number of warnings and errors to 10 for every 10 second interval.
   log_throttling: true

  ## @param profiling - custom object - optional
  ## Enter specific configurations for internal profiling.
  ##
  ## Please note that:
  ##   1. This does *not* enable profiling for user applications.
  ##   2. This only enables internal profiling of the agent go runtime.
  ##   3. To enable profiling for user apps please refer to
  ##      https://docs.datadoghq.com/tracing/profiling/
  ##   4. Enabling this feature will incur in billing charges and other
  ##      unexpected side-effects (ie. agent profiles showing with your
  ##      services).
  ##
  ## Uncomment this parameter and the one below to enable profiling.
   internal_profiling:
    ## @param enabled - boolean - optional - default: false
    ## Enable internal profiling for the trace-agent process.
     enabled: false

For containerized environments, follow the in-app Quickstart instructions to enable trace collection within the Datadog Agent.

Ensure you set DD_SITE in the Datadog Agent to so that the Agent sends data to the right Datadog location.

Custom instrumentation

Note: If you are using both automatic and custom instrumentation, it is important to keep the package versions (for example, MSI and NuGet) in sync.

To use custom instrumentation in your .NET application:

  1. Add the Datadog.Trace NuGet package to your application.
  2. In your application code, access the global tracer through the Datadog.Trace.Tracer.Instance property to create new spans.

For additional details on custom instrumentation and custom tagging, see the .NET Custom Instrumentation documentation.

Configuration

The .NET Tracer has configuration settings which you can set by any of these methods:

To configure the tracer using environment variables, set the variables before launching the instrumented application.

For example:

rem Set environment variables
SET DD_TRACE_AGENT_URL=http://localhost:8126
SET DD_ENV=prod
SET DD_SERVICE=MyService
SET DD_VERSION=abc123

rem Launch application
example.exe
Note: To set environment variables for a Windows Service, use the multi-string key HKLM\System\CurrentControlSet\Services\{service name}\Environment in the Windows Registry, as described above.

Because IIS runs all applications under one Windows Service, Datadog recommends you use another configuration option (Code, web.config, or JSON file) for application-specific settings such as DD_SERVICE.

To configure the Tracer in application code, create a TracerSettings instance from the default configuration sources. Set properties on this TracerSettings instance before passing it to a Tracer constructor. For example:

Note: Settings must be set on TracerSettings before creating the Tracer. Changes made to TracerSettings properties after the Tracer is created are ignored.
using Datadog.Trace;
using Datadog.Trace.Configuration;

// read default configuration sources (env vars, web.config, datadog.json)
var settings = TracerSettings.FromDefaultSources();

// change some settings
settings.Environment = "prod";
settings.ServiceName = "MyService";
settings.ServiceVersion = "abc123";
settings.AgentUri = new Uri("http://localhost:8126/");

// create a new Tracer using these settings
var tracer = new Tracer(settings);

// set the global tracer
Tracer.Instance = tracer;

To configure the Tracer using an app.config or web.config file, use the <appSettings> section. For example:

<configuration>
  <appSettings>
    <add key="DD_TRACE_AGENT_URL" value="http://localhost:8126"/>
    <add key="DD_ENV" value="prod"/>
    <add key="DD_SERVICE" value="MyService"/>
    <add key="DD_VERSION" value="abc123"/>
  </appSettings>
</configuration>

To configure the Tracer using a JSON file, create datadog.json in the instrumented application’s directory. The root JSON object must be an object with a key-value pair for each setting. For example:

{
  "DD_TRACE_AGENT_URL": "http://localhost:8126",
  "DD_ENV": "prod",
  "DD_SERVICE": "MyService",
  "DD_VERSION": "abc123",
}

Configuration settings

Using the methods described above, customize your tracing configuration with the following variables. Use the environment variable name (for example, DD_TRACE_AGENT_URL) when setting environment variables or configuration files. Use the TracerSettings property (for example, AgentUri) when changing settings in code.

Unified Service Tagging

To use Unified Service Tagging, configure the following settings for your services:

DD_ENV
TracerSettings property: Environment
If specified, adds the env tag with the specified value to all generated spans. Added in version 1.17.0.
DD_SERVICE
TracerSettings property: ServiceName
If specified, sets the service name. Otherwise, the .NET Tracer tries to determine service name automatically from application name (IIS application name, process entry assembly, or process name). Added in version 1.17.0.
DD_VERSION
TracerSettings property: ServiceVersion
If specified, sets the version of the service. Added in version 1.17.0.

Optional configuration

The following configuration variables are available for both automatic and custom instrumentation:

DD_TRACE_AGENT_URL
TracerSettings property: AgentUri
Sets the URL endpoint where traces are sent. Overrides DD_AGENT_HOST and DD_TRACE_AGENT_PORT if set.
Default: http://<DD_AGENT_HOST>:<DD_TRACE_AGENT_PORT>
DD_AGENT_HOST
Sets the host where traces are sent (the host running the Agent). Can be a hostname or an IP address. Ignored if DD_TRACE_AGENT_URL is set.
Default: localhost
DD_TRACE_AGENT_PORT
Sets the port where traces are sent (the port where the Agent is listening for connections). Ignored if DD_TRACE_AGENT_URL is set.
Default: 8126
DD_LOGS_INJECTION
TracerSettings property: LogsInjectionEnabled
Enables or disables automatic injection of correlation identifiers into application logs.
DD_TRACE_DEBUG
TracerSettings property: DebugEnabled
Enables or disables debug logging. Valid values are: true or false.
Default: false
DD_TRACE_HEADER_TAGS
TracerSettings property:HeaderTags
Accepts a map of case-insensitive header keys to tag names and automatically applies matching header values as tags on root spans. Also accepts entries without a specified tag name.
Example: CASE-insensitive-Header:my-tag-name,User-ID:userId,My-Header-And-Tag-Name
Added in version 1.18.3. Response header support and entries without tag names added in version 1.26.0.
DD_TAGS
TracerSettings property: GlobalTags
If specified, adds all of the specified tags to all generated spans.
Example: layer:api,team:intake
Added in version 1.17.0.
DD_TRACE_LOG_DIRECTORY
Sets the directory for .NET Tracer logs.
Default: %ProgramData%\Datadog .NET Tracer\logs\
DD_TRACE_LOG_PATH
Sets the path for the automatic instrumentation log file and determines the directory of all other .NET Tracer log files. Ignored if DD_TRACE_LOG_DIRECTORY is set.
DD_TRACE_LOGGING_RATE
Sets rate limiting for log messages. If set, unique log lines are written once per x seconds. For example, to log a given message once per 60 seconds, set to 60. Setting to 0 disables log rate limiting. Added in version 1.24.0. Disabled by default.
DD_TRACE_SERVICE_MAPPING
Rename services using configuration. Accepts a map of service name keys to rename, and the name to use instead, in the format [from-key]:[to-name].
Example: mysql:main-mysql-db, mongodb:offsite-mongodb-service
The from-key value is specific to the integration type, and should exclude the application name prefix. For example, to rename my-application-sql-server to main-db, use sql-server:main-db. Added in version 1.23.0

Automatic instrumentation optional configuration

The following configuration variables are available only when using automatic instrumentation:

DD_TRACE_ENABLED
TracerSettings property: TraceEnabled
Enables or disables all automatic instrumentation. Setting the environment variable to false completely disables the CLR profiler. For other configuration methods, the CLR profiler is still loaded, but traces will not be generated. Valid values are: true or false.
Default: true
DD_HTTP_CLIENT_ERROR_STATUSES
Sets status code ranges that will cause HTTP client spans to be marked as errors.
Default: 400-499
DD_HTTP_SERVER_ERROR_STATUSES
Sets status code ranges that will cause HTTP server spans to be marked as errors.
Default: 500-599
DD_RUNTIME_METRICS_ENABLED
Enables .NET runtime metrics. Valid values are true or false.
Default: false
Added in version 1.23.0.
DD_TRACE_ADONET_EXCLUDED_TYPES
TracerSettings property: AdoNetExcludedTypes
Sets a list of AdoNet types (for example, System.Data.SqlClient.SqlCommand) that will be excluded from automatic instrumentation.

Automatic instrumentation integration configuration

The following table lists configuration variables that are available only when using automatic instrumentation and can be set for each integration.

DD_DISABLED_INTEGRATIONS
TracerSettings property: DisabledIntegrationNames
Sets a list of integrations to disable. All other integrations remain enabled. If not set, all integrations are enabled. Supports multiple values separated with semicolons. Valid values are the integration names listed in the Integrations section.
DD_TRACE_<INTEGRATION_NAME>_ENABLED
TracerSettings property: Integrations[<INTEGRATION_NAME>].Enabled
Enables or disables a specific integration. Valid values are: true or false. Integration names are listed in the Integrations section.
Default: true

Experimental features

The following configuration variables are for features that are available for use but may change in future releases.

DD_TRACE_ROUTE_TEMPLATE_RESOURCE_NAMES_ENABLED
Enables improved resource names for web spans when set to true. Uses route template information where available, adds an additional span for ASP.NET Core integrations, and enables additional tags. Added in version 1.26.0.
Default: false
DD_TRACE_PARTIAL_FLUSH_ENABLED
Enables incrementally flushing large traces to the Datadog Agent, reducing the chance of rejection by the Agent. Use only when you have long-lived traces or traces with many spans. Valid values are true or false. Added in version 1.26.0, only compatible with the Datadog Agent 7.26.0+.
Default: false

Further reading