Learn more about end-to-end observability for .NET applications and processes.
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.
To get trace insights:
To get log insights:
The .NET processes run on a supported Windows operating system.
To get metric insights:
For more details, see Manage WMI extensions.
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.
| Metric name | Metric key | Description |
|---|---|---|
| Total bytes in all heaps | dotnet.memory.numberbytesinallheaps | This 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 collections | dotnet.memory.numbergen0collections.count | This 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 collections | dotnet.memory.numbergen1collections.count | This 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 collections | dotnet.memory.numbergen2collections.count | This 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 bytes | dotnet.memory.numbertotalcommittedbytes | This 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 bytes | dotnet.memory.numbertotaleeservedbytes | This 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 GC | dotnet.memory.percenttimeingc | The 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 size | dotnet.memory.gen0heapsize | This 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 size | dotnet.memory.gen1heapsize | This 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 size | dotnet.memory.gen2heapsize | This 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 threads | dotnet.locksandthreads.numberofcurrentlogicalthreads | This 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 threads | dotnet.locksandthreads.numberofcurrentphysicalthreads | This 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 length | dotnet.locksandthreads.currentqueuelength | This 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 second | dotnet.locksandthreads.contentionratepersec | Rate 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. |