In .NET, we actually have two common methods for performance indicator monitoring, one is CLI tool dotnet-counters
and the other is code level EventListener
.
Use dotnet-counters
dotnet-counters
It is a performance indicator monitoring tool for temporary operation status monitoring and preliminary performance investigation. It can observe the performance counter value published through the EventCounter API. For example, it can quickly lead to abnormal rate monitor CPU usage or .NET Core application, in order to understand in usePerfView
ordotnet-trace
if there are any suspicious actions before a thorough investigation of more serious performance problems.
- from dotnet-counters
command
To install dotnet-counters CLI tool, you can use the following command:
dotnet tool install --global dotnet-counters
The update command is as follows:
dotnet tool update dotnet-counters --global
After installing the tool, we can view the processes that can be monitored:
dotnet-counters ps
12268 dotnet C:\Program Files\dotnet\dotnet.exe
16324 dotnet C:\Program Files\dotnet\dotnet.exe
After obtaining the process ID, we can monitor it with the following command:
dotnet-counters monitor -p 12268
To monitor specific EventSources
, you can provide a list separated by a space EventSources
, as shown below:
dotnet-counters monitor -p 12268 System.Runtime MyEventSource
By default, when we EventSource
monitor, it captures all counters. If we want to track certain counters individually, we can specify them as follows:
dotnet-counters monitor -p 12268 System.Runtime[cpu-usage,gc-heap-size]
For the monitor, we can set the refresh rate, which can be set by --refresh-interval
parameters:
dotnet-counters monitor -p 12268 --refresh-interval 3 System.Runtime[cpu-usage,gc-heap-size]
EventCounters in the code
EventListener
Provides a way to subscribe and consume log events in-process (In-Process), and EventListener
can receive EventSource
log events from distribution. These events cover the behavior of GC, JIT, ThreadPool, and interop.
创建EventListener
在下面我们进行重写OnEventSourceCreated
方法,该方法会在调用时接收一个EventSource
对象,我们可以通过EventSource
对象的Name属性去筛选我们感兴趣的日志事件,筛选后我们需要显示的调用EnableEvents
方法向感兴趣的日志事件发起订阅。
internal sealed class MyEventListener : EventListener
{
protected override void OnEventSourceCreated(EventSource eventSource)
{
if (eventSource.Name.Equals("Microsoft-Windows-DotNETRuntime"))
{
EnableEvents(eventSource, EventLevel.Verbose, (EventKeywords)(-1));
}
}
}
事件消费
接下来我们需要进行重写OnEventWritten
,关于日志事件相关的信息会被封装成一个EventWrittenEventArgs
对象,我们不仅可以通过它获取当前日志事件的所有信息,而且我们还可以进行获取到EventSource
对象。Payload
包含了不同属性的值ReadOnlyCollection<object>
, 而PayLoadNames ReadOnlyCollection<object>
中包含了不同的属性名称,我们现在可以通过如下方式进行获取这些属性:
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
Console.WriteLine($"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventName}");
for (int i = 0; i < eventData.Payload.Count; i++)
{
string payloadString = eventData.Payload[i]?.ToString() ?? string.Empty;
Console.WriteLine($"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\"");
}
Console.WriteLine("\n");
}
参考
https://stackoverflow.com/questions/61081063/get-total-number-of-allocations-in-c-sharp