I am currently looking for a way to get the current CPU/RAM/Disk usage in a C# web application using .NET CORE.
For CPU and ram usage, I use PerformanceCounter Class
Processor information is available via System.Diagnostics
:
var proc = Process.GetCurrentProcess();
var mem = proc.WorkingSet64;
var cpu = proc.TotalProcessorTime;
Console.WriteLine("My process used working set {0:n3} K of working set and CPU {1:n} msec",
mem / 1024.0, cpu.TotalMilliseconds);
DriveInfo
is available for Core by adding the System.IO.FileSystem.DriveInfo
package
For Windows i'm using this
var memorielines= GetWmicOutput("OS get FreePhysicalMemory,TotalVisibleMemorySize /Value").Split("\n");
var freeMemory= memorielines[0].Split("=", StringSplitOptions.RemoveEmptyEntries)[1];
var totalMemory = memorielines[1].Split("=", StringSplitOptions.RemoveEmptyEntries)[1];
var cpuLines = GetWmicOutput("CPU get Name,LoadPercentage /Value").Split("\n");
var CpuUse = cpuLines[0].Split("=", StringSplitOptions.RemoveEmptyEntries)[1];
var CpuName = cpuLines[1].Split("=", StringSplitOptions.RemoveEmptyEntries)[1];
private string GetWmicOutput(string query, bool redirectStandardOutput = true)
{
var info = new ProcessStartInfo("wmic");
info.Arguments = query;
info.RedirectStandardOutput = redirectStandardOutput;
var output = "";
using (var process = Process.Start(info))
{
output = process.StandardOutput.ReadToEnd();
}
return output.Trim();
}
For the disk infos you can use this query :
LOGICALDISK get Caption,DeviceID,FileSystem,FreeSpace,Size /Value
if you want a better output formatting give a look to this article : https://www.petri.com/command-line-wmi-part-3
You can use PerformnceCounter
in the System.Diagnostics.PerformanceCounter
package
for example, the next code will give you the total processor usage percent
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total",true);
var value = cpuCounter.NextValue();
//Note: In most cases you need to call .NextValue() twice to be able to get the real value
if (Math.Abs(value) <= 0.00)
value = cpuCounter.NextValue();
Console.WriteLine(value);
you can do the same for all OS registered Performance Counters.
I'm not sure if there is something I should do after creating a new instance of the PerformanceCounter class, but sometimes when I get the next value it comes as 0.
So I've decided to make one instance of PerformanceCounter in at the application level.
e.g.
public static class DiagnosticHelpers
{
public static float SystemCPU { get; private set; }
private static readonly object locker = new object();
static DiagnosticHelpers()
{
SystemCPU = 0;
Task.Run(() =>
{
var cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
while (true)
{
Thread.Sleep(1000);
lock (locker)
{
SystemCPU = cpuCounter.NextValue();
}
}
});
}
}