我正在尝试报告 Linux 系统中的 CPU 总使用率。每 10 秒报告一次。我在多个 docker 上运行多个进程,因此运行
Process.GetProcesses()
时出现 unable to retrieve the specified information about the process. it may have exited or may be privileged.
错误。我的计算机有 12 个 CPU,每个线程 2 个: 意味着它使用 6 个核心。我需要一种有效的方法来计算给定时间所有计算机的当前 CPU 使用情况。
我的尝试是:
TimeSpan delta = DateTime.Now - _lastTimeBuildReport;
double cpuLoad = 100* (currentExporterDic["node_cpu_seconds_total"].GetSum("idle") - _previousExporterDic["node_cpu_seconds_total"].GetSum("idle")) / delta.TotalSeconds;
这给了我奇怪的值(是真实值的3倍) 在 ASP.NET CORE LINUX Get CPU USAGE
之后,这给出了错误private double CalculateToTotalCPUUsage(double totalMsPassed)
{
try
{
double totalCpuUsagePercentage = 0;
string getProccesorsCoresCMD = "grep 'cpu cores' /proc/cpuinfo | uniq | grep -Eo '[0-9]{1,4}'";
string[] coresLines = DotNetUtilities.DotNetUtilities.GetOsCmdLineOutput(getProccesorsCoresCMD).Lines;
int cpuCores = int.Parse(coresLines[0]);
Process[] allProc = Process.GetProcesses();
foreach (Process process in allProc)
{
// Start watching CPU
var currentProStartCpuUsage = process.TotalProcessorTime;
//Delay the function so we can measure the same CPU load
Task.Delay(Convert.ToInt32(totalMsPassed)).Wait();
var currentProEndCpuUsage = process.TotalProcessorTime;
var currentProCpuUsedMs = (currentProEndCpuUsage - currentProStartCpuUsage).TotalMilliseconds;
var currentProCpuUsageTotal = currentProCpuUsedMs / (cpuCores * totalMsPassed);
var currentProCpuUsagePercentage = currentProCpuUsageTotal * 100;
totalCpuUsagePercentage += currentProCpuUsagePercentage;
}
return totalCpuUsagePercentage;
}
catch (Exception ex)
{
Logger.LogError($"Couldn't calculate total CPU usage. Reason: {ex.Message} {ex.StackTrace}");
return -1;
}
}
public class Cpu
{
public double CpuUsage { get; set; }
}
public class CpuUsage
{
public Cpu ReadCpuUsage()
{
try
{
var output = "";
var cpuInfo = new ProcessStartInfo("top -b -n 1");
cpuInfo.FileName = "/bin/bash";
cpuInfo.Arguments = "-c \"top -b -n 1\"";
cpuInfo.RedirectStandardOutput = true;
using (var process = Process.Start(cpuInfo))
{
output = process.StandardOutput.ReadToEnd();
//Console.WriteLine(output);
}
var cpuLine = output.Split("\n").ToList();
var cpuLine2 = cpuLine[2].Split(",", StringSplitOptions.RemoveEmptyEntries);
var firstPart = cpuLine2[0].Split(":", StringSplitOptions.RemoveEmptyEntries);
var secondPart = cpuLine2[1].Split("s", StringSplitOptions.RemoveEmptyEntries);
var thirdPart = cpuLine2[2].Split("n", StringSplitOptions.RemoveEmptyEntries);
double cpuUsage = double.Parse(firstPart[1].Split("u", StringSplitOptions.RemoveEmptyEntries)[0]) +
double.Parse(secondPart[0]) +
double.Parse(thirdPart[0]);
cpuUsage = Math.Round(cpuUsage, 2);
return new Cpu()
{
CpuUsage = cpuUsage
};
}
catch (Exception ex)
{
return null;
}
}
}