Reputation: 81
I recently migrated from c# to .net core. In c# I use to get CPU usage with this:
PerformanceCounter cpuCounter;
PerformanceCounter ramCounter;
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
public string getCurrentCpuUsage(){
return cpuCounter.NextValue()+"%";
}
but in .net core PerformanceCounter
is not available what is the solution ? please give me an advice.
Upvotes: 3
Views: 1121
Reputation: 23680
The top answer didn't work for me running on Amazon ECS.
Building on Tatiana's answer, I liked found that this elegant solution worked, where I added an install of sysstat
to the environment (I added it to my docker file):
RUN apt update && \
apt install -y sysstat
Then here's a simple piece of code execution to get the CPU percentage from the command output:
private static double? GetMpStatCpuPercentage()
{
var info = new ProcessStartInfo("bash")
{
Arguments = "-c \"mpstat 1 1 | awk '/Average/ {print 100 - $NF}'\""
};
string output;
using (var process = Process.Start(info))
{
output = process.StandardOutput.ReadToEnd();
}
if (double.TryParse(output.Trim(), out var cpuUsagePercentage))
return cpuUsagePercentage;
return null;
}
awk '/Average/ {print 100 - $NF}'
calculates the CPU usage by subtracting the idle percentage ($NF represents the last field, which is the idle CPU percentage) from 100.
Upvotes: 0
Reputation: 1304
On Mac, I went the same route as you already have to go to get memory usage: shell out to a command-line utility, such as top
, and parse the output.
Here's my code:
private static string[] GetOsXTopOutput()
{
var info = new ProcessStartInfo("top");
info.Arguments = "-l 1 -n 0";
info.RedirectStandardOutput = true;
string output;
using (var process = Process.Start(info))
{
output = process.StandardOutput.ReadToEnd();
}
return output.Split('\n');
}
public static double GetOverallCpuUsagePercentage()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
var lines = GetOsXTopOutput();
// Example: "CPU usage: 8.69% user, 21.73% sys, 69.56% idle"
var pattern = @"CPU usage: \d+\.\d+% user, \d+\.\d+% sys, (\d+\.\d+)% idle";
Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
foreach (var line in lines)
{
Match m = r.Match(line);
if (m.Success)
{
var idle = double.Parse(m.Groups[1].Value);
var used = 100 - idle;
return used;
}
}
// Or throw an exception
return -1.0;
}
else
{
// E.g., Melih Altıntaş's solution: https://stackoverflow.com/a/59465268/132042
...
}
}
Upvotes: 0
Reputation: 2535
Performance counters are not in Linux thus not in NET Core. Alternative way:
private async Task<double> GetCpuUsageForProcess()
{
var startTime = DateTime.UtcNow;
var startCpuUsage = Process.GetProcesses().Sum(a => a.TotalProcessorTime.TotalMilliseconds);
await Task.Delay(500);
var endTime = DateTime.UtcNow;
var endCpuUsage = Process.GetProcesses().Sum(a => a.TotalProcessorTime.TotalMilliseconds);
var cpuUsedMs = endCpuUsage - startCpuUsage;
var totalMsPassed = (endTime - startTime).TotalMilliseconds;
var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed);
return cpuUsageTotal * 100;
}
Upvotes: 3