.NET Custom Instrumentation
New announcements from Dash: Incident Management, Continuous Profiler, and more! New announcements from Dash!

.NET Custom Instrumentation

For instructions on how to setup the .NET Tracer and enable automatic instrumentation, see the .NET setup instructions.

Note: When using both custom and automatic instrumentation, it is important to keep the MSI installer and NuGet package versions in sync.

This page details common use cases for adding and customizing observability with Datadog APM.

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

Custom instrumentation is supported on .NET Framework 4.5+ for Windows and on .NET Core 2.1, 3.0, and 3.1 for Windows and Linux.

Add tags and spans

To customize your observability within Datadog, add custom span tags to your spans. Span tags are applied to your incoming traces, allowing you to correlate observed behavior with code-level information such as merchant tier, checkout amount, user ID, etc.

Add custom span tags

Add custom tags to your spans corresponding to any dynamic value within your application code such as customer.id.

Add tags directly to a Datadog.Trace.Span object by calling Span.SetTag(). For example:

public class ShoppingCartController : Controller
{
    private IShoppingCartRepository _shoppingCartRepository;

    [HttpGet]
    public IActionResult Index(int customerId)
    {
        // Access the active scope through
        // the global tracer (can return null)
        var scope = Tracer.Instance.ActiveScope;

        if (scope != null)
        {
            // Add a tag to the span for use in the Datadog web UI
            scope.Span.SetTag("customer.id", customerId.ToString());
        }

        var cart = _shoppingCartRepository.Get(customerId);

        return View(cart);
    }
}

Note: Datadog.Trace.Tracer.Instance.ActiveScope returns null if there is no active span.

Adding tags globally to all spans

Use the DD_TAGS environment variable to set tags across all generated spans for an application. This can be useful for grouping stats for your applications, data centers, regions, etc. within the Datadog UI. For example:

DD_TAGS=datacenter:njc,key2:value2

Set errors on a span

To recognize and mark errors that occur in your code, utilize the Span.SetException(Exception) method available to spans. The method marks the span as an error and adds related span metadata to provide insight into the exception.

try
{
    // do work that can throw an exception
}
catch(Exception e)
{
    span.SetException(e);
}

This sets three tags on the span: "error.msg":exception.Message, "error.stack":exception.ToString(), and "error.type":exception.GetType().ToString().

Manually creating a new span

Customize your observability by programmatically creating spans around any block of code. Spans created in this manner integrate with other tracing mechanisms automatically. In other words, if a trace has already started, the manual span has its caller as its parent span. Similarly, any traced methods called from the wrapped block of code have the manual span as its parent.

using (var parentScope =
       Tracer.Instance.StartActive("manual.sortorders"))
{
    using (var childScope =
           Tracer.Instance.StartActive("manual.sortorders.child"))
    {
        // Nest using statements around the code to trace
        SortOrders();
    }
}

Resource Filtering

Traces can be excluded based on their resource name, to remove synthetic traffic such as health checks from reporting traces to Datadog. This and other security and fine-tuning configurations can be found on the Security page.

OpenTracing

Datadog also supports the OpenTracing standard. For more details and information, view the OpenTracing API.

Setup

For OpenTracing support, add the Datadog.Trace.OpenTracing NuGet package to your application. During application start-up, initialize the OpenTracing library:

using Datadog.Trace.OpenTracing;

public void ConfigureServices(IServiceCollection services)
{
    // Create an OpenTracing ITracer with the default setting
    OpenTracing.ITracer tracer = OpenTracingTracerFactory.CreateTracer();

    // Use the tracer with ASP.NET Core dependency injection
    services.AddSingleton<ITracer>(tracer);

    // Use the tracer with OpenTracing.GlobalTracer.Instance
    GlobalTracer.Register(tracer);
}

Manually instrument a method

Use OpenTracing to create a span.

using (var scope =
       Tracer.Instance.StartActive("manual.sortorders"))
{
    SortOrders();
}

Asynchronous traces

To trace code running in an asynchronous task, create a new scope within the background task, just as you would wrap synchronous code.

 Task.Run(
     () =>
     {
         using (var scope =
                Tracer.Instance.StartActive("manual.sortorders.async"))
         {
             SortOrders();
         }
     });

Further Reading