.NET extension

  • Latest Dynatrace
  • Extension
  • Published Oct 27, 2025

Learn more about end-to-end observability for .NET applications and processes.

Get started

Overview

Gain real-time insights to improve stability and optimize .NET app performance.

With Dynatrace, you can get observability for all applications based on .NET, .NET Core, .NET Framework, ADO.NET, and ASP.NET Owin/Katana. Dynatrace analyzes your applications and detects issues in real-time, including your users' behavior. Thanks to our proprietary AI engine, you can pinpoint the root cause of problems down to the code level, reduce mean time to repair, and proactively stabilize application performance before your customers are affected. Comprehensive memory and thread metrics give you insight into the resource contention of your .NET processes.

Use cases

  • Monitor the performance of your distributed applications across every layer.
  • Trace requests end-to-end from frontend apps via message queues to backend services and databases.
  • Troubleshoot issues with deep code-level visibility down to a single line of code.
  • Analyze resource contention issues with memory, thread, and other process metrics.
  • Capture memory dumps for advanced troubleshooting.
  • Investigate logs in the context of traces and workloads.

Requirements

.NET applications

To get trace insights:

  1. Install OneAgent on the virtual machine or server of your applications.
  2. Set up Dynatrace on Kubernetes or OpenShift for your application workloads.
  3. Activate the following OneAgent features:
    • .NET ASP.NET Sensor V2
    • Real User Monitoring (RUM) for ASP.NET Core

To get log insights:

.NET processes

The .NET processes run on a supported Windows operating system.

To get metric insights:

  1. Install OneAgent on the virtual machine or server of your .NET processes.
  2. Ensure your .NET processes are monitored.
  3. In Dynatrace, select Add to environment to configure the extension.
  4. Open the .NET Extension Overview dashboard.

For more details, see Manage WMI extensions.

Feature sets

When activating your extension using monitoring configuration, you can limit monitoring to one of the feature sets. To work properly the extension has to collect at least one metric after the activation.

In highly segmented networks, feature sets can reflect the segments of your environment. Then, when you create a monitoring configuration, you can select a feature set and a corresponding ActiveGate group that can connect to this particular segment.

All metrics that aren't categorized into any feature set are considered to be the default and are always reported.

A metric inherits the feature set of a subgroup, which in turn inherits the feature set of a group. Also, the feature set defined on the metric level overrides the feature set defined on the subgroup level, which in turn overrides the feature set defined on the group level.

default
Metric nameMetric keyDescription
Total bytes in all heapsdotnet.memory.numberbytesinallheapsThis counter is the sum of four other counters; Gen 0 Heap Size; Gen 1 Heap Size; Gen 2 Heap Size and the Large Object Heap Size. This counter indicates the current memory allocated in bytes on the GC Heaps.
Gen 0 collectionsdotnet.memory.numbergen0collections.countThis counter displays the number of times the generation 0 objects (youngest; most recently allocated) are garbage collected (Gen 0 GC) since the start of the application. Gen 0 GC occurs when the available memory in generation 0 is not sufficient to satisfy an allocation request. This counter is incremented at the end of a Gen 0 GC. Higher generation GCs include all lower generation GCs. This counter is explicitly incremented when a higher generation (Gen 1 or Gen 2) GC occurs. _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value.
Gen 1 collectionsdotnet.memory.numbergen1collections.countThis counter displays the number of times the generation 1 objects are garbage collected since the start of the application. The counter is incremented at the end of a Gen 1 GC. Higher generation GCs include all lower generation GCs. This counter is explicitly incremented when a higher generation (Gen 2) GC occurs. _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value.
Gen 2 collectionsdotnet.memory.numbergen2collections.countThis counter displays the number of times the generation 2 objects (older) are garbage collected since the start of the application. The counter is incremented at the end of a Gen 2 GC (also called full GC). _Global_ counter value is not accurate and should be ignored. This counter displays the last observed value.
Total commited bytesdotnet.memory.numbertotalcommittedbytesThis counter displays the amount of virtual memory (in bytes) currently committed by the Garbage Collector. (Committed memory is the physical memory for which space has been reserved on the disk paging file).
Total reserved bytesdotnet.memory.numbertotaleeservedbytesThis counter displays the amount of virtual memory (in bytes) currently reserved by the Garbage Collector. (Reserved memory is the virtual memory space reserved for the application but no disk or main memory pages have been used.)
Percent of time in GCdotnet.memory.percenttimeingcThe percentage of elapsed time that was spent in performing a garbage collection (GC) since the last GC cycle. This counter is usually an indicator of the work done by the Garbage Collector on behalf of the application to collect and compact memory. This counter is updated only at the end of every GC and the counter value reflects the last observed value; its not an average.
Gen 0 heap sizedotnet.memory.gen0heapsizeThis counter displays the maximum bytes that can be allocated in generation 0 (Gen 0); its does not indicate the current number of bytes allocated in Gen 0. A Gen 0 GC is triggered when the allocations since the last GC exceed this size. The Gen 0 size is tuned by the Garbage Collector and can change during the execution of the application. At the end of a Gen 0 collection the size of the Gen 0 heap is infact 0 bytes; this counter displays the size (in bytes) of allocations that would trigger the next Gen 0 GC. This counter is updated at the end of a GC; its not updated on every allocation.
Gen 1 heap sizedotnet.memory.gen1heapsizeThis counter displays the current number of bytes in generation 1 (Gen 1); this counter does not display the maximum size of Gen 1. Objects are not directly allocated in this generation; they are promoted from previous Gen 0 GCs. This counter is updated at the end of a GC; its not updated on every allocation.
Gen 2 heap sizedotnet.memory.gen2heapsizeThis counter displays the current number of bytes in generation 2 (Gen 2). Objects are not directly allocated in this generation; they are promoted from Gen 1 during previous Gen 1 GCs. This counter is updated at the end of a GC; its not updated on every allocation.
Number of current logical threadsdotnet.locksandthreads.numberofcurrentlogicalthreadsThis counter displays the number of current .NET thread objects in the application. A .NET thread object is created either by new System.Threading.Thread or when an unmanaged thread enters the managed environment. This counters maintains the count of both running and stopped threads. This counter is not an average over time; it just displays the last observed value.
Number of current physical threadsdotnet.locksandthreads.numberofcurrentphysicalthreadsThis counter displays the number of native OS threads created and owned by the CLR to act as underlying threads for .NET thread objects. This counters value does not include the threads used by the CLR in its internal operations; it is a subset of the threads in the OS process.
Current queue lengthdotnet.locksandthreads.currentqueuelengthThis counter displays the total number of threads currently waiting to acquire some managed lock in the application. This counter is not an average over time; it displays the last observed value.
Contention rate per seconddotnet.locksandthreads.contentionratepersecRate at which threads in the runtime attempt to acquire a managed lock unsuccessfully. Managed locks can be acquired in many ways; by the "lock" statement in C# or by calling System.Monitor.Enter or by using MethodImplOptions.Synchronized custom attribute.
Related tags
ApplicationWMIWeb serverMicrosoftApplication Observability