Alian Drovez
Alian Drovez

Reputation: 81

.net core cpu usage for machine

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

Answers (3)

Luke
Luke

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

Tatiana Racheva
Tatiana Racheva

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

Melih Altıntaş
Melih Altıntaş

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

Related Questions