I have an assembly that monitors the performance statistics of a number of our microservices running on a machine. The code uses performance counters to retrieve and publish data, as shown below:
_counters = new Dictionary<string, PerformanceCounter>
{
["System Memory Available Bytes"] = new PerformanceCounter { CategoryName = "Memory", CounterName = "Available Bytes", ReadOnly = true },
["System CPU Usage %"] = new PerformanceCounter { CategoryName = "Processor", CounterName = "% Processor Time", InstanceName = "_Total", ReadOnly = true },
["Process CPU Usage %"] = new PerformanceCounter { CategoryName = "Process", CounterName = "% Processor Time", InstanceName = processName, ReadOnly = true },
["Process Thread Count"] = new PerformanceCounter { CategoryName = "Process", CounterName = "Thread Count", InstanceName = processName, ReadOnly = true },
["Process Private Bytes"] = new PerformanceCounter { CategoryName = "Process", CounterName = "Private Bytes", InstanceName = processName, ReadOnly = true },
["Process Working Set Bytes"] = new PerformanceCounter { CategoryName = "Process", CounterName = "Working Set", InstanceName = processName, ReadOnly = true },
["Process Virtual Bytes"] = new PerformanceCounter { CategoryName = "Process", CounterName = "Virtual Bytes", InstanceName = processName, ReadOnly = true },
["Contention Rate/Sec"] = new PerformanceCounter { CategoryName = ".NET CLR LocksAndThreads", CounterName = "Contention Rate / Sec", InstanceName = processName, ReadOnly = true },
["Contention Queue Peak Size"] = new PerformanceCounter { CategoryName = ".NET CLR LocksAndThreads", CounterName = "Queue Length Peak", InstanceName = processName, ReadOnly = true },
["Contention Total Count"] = new PerformanceCounter { CategoryName = ".NET CLR LocksAndThreads", CounterName = "Total # of Contentions", InstanceName = processName, ReadOnly = true },
["Induced GC Count"] = new PerformanceCounter { CategoryName = ".NET CLR Memory", CounterName = "# Induced GC", InstanceName = processName, ReadOnly = true },
["GC Handle Count"] = new PerformanceCounter { CategoryName = ".NET CLR Memory", CounterName = "# GC Handles", InstanceName = processName, ReadOnly = true },
["Finalization Survivors"] = new PerformanceCounter { CategoryName = ".NET CLR Memory", CounterName = "Finalization Survivors", InstanceName = processName, ReadOnly = true },
["LOB Size Bytes"] = new PerformanceCounter { CategoryName = ".NET CLR Memory", CounterName = "Large Object Heap size", InstanceName = processName, ReadOnly = true },
["Total Bytes in all Heaps"] = new PerformanceCounter { CategoryName = ".NET CLR Memory", CounterName = "# Bytes in all Heaps", InstanceName = processName, ReadOnly = true },
["Total Bytes Committed"] = new PerformanceCounter { CategoryName = ".NET CLR Memory", CounterName = "# Total committed Bytes", InstanceName = processName, ReadOnly = true },
["Total Bytes Reserved"] = new PerformanceCounter { CategoryName = ".NET CLR Memory", CounterName = "# Total reserved Bytes", InstanceName = processName, ReadOnly = true },
["Time in GC %"] = new PerformanceCounter { CategoryName = ".NET CLR Memory", CounterName = "% Time in GC", InstanceName = processName, ReadOnly = true },
["Time in JIT %"] = new PerformanceCounter { CategoryName = ".NET CLR Jit", CounterName = "% Time in Jit", InstanceName = processName, ReadOnly = true },
};
foreach (var counter in _counters.Values) { counter.NextValue(); }
Then I start the timer, which publishes the data at every second 1 (I just save it in a variable here for brevity):
_timer = new Timer(1000);
_timer.Elapsed += OnTimerElapsed;
_timer.Start();
private void OnTimerElapsed(object sender, ElapsedEventArgs eArgs)
{
var a = _counters["System CPU Usage %"].NextValue();
var b = _counters["System Memory Available Bytes"].NextValue();
var h = _counters["Contention Rate/Sec"].NextValue();
var i = _counters["Contention Queue Peak Size"].NextValue();
var j = _counters["Contention Total Count"].NextValue();
var k = _counters["Induced GC Count"].NextValue();
var l = _counters["GC Handle Count"].NextValue();
var m = _counters["Finalization Survivors"].NextValue();
var n = _counters["LOB Size Bytes"].NextValue();
var o = _counters["Total Bytes in all Heaps"].NextValue();
var p = _counters["Total Bytes Committed"].NextValue();
var q = _counters["Total Bytes Reserved"].NextValue();
var r = _counters["Time in GC %"].NextValue();
var s = _counters["Time in JIT %"].NextValue();
}
GC gen 0 . , c g, (gen 0 to 2) 1 . , ?