C# 获取 linux 中 进程的CPU、内存、网络读写、磁盘读写
获取进程CPU及内存使用情况
/// <summary>
/// 获取进程CPU及内存使用情况
/// </summary>
/// <param name="processType">进程名称</param>
private void GetCPUandMemory(string processType)
{
try
{
var str = ExecuteCommand("ps -aux");
var str_l = str.Where(o => !string.IsNullOrWhiteSpace(o)).Select(o => o.Split(' ', StringSplitOptions.RemoveEmptyEntries));
var c = str_l.FirstOrDefault();
var l = str_l.Skip(1);
var data = l.Select(o =>
{
Dictionary<string, string> temp = new Dictionary<string, string>();
for (var i = 0; i < c.Length; i++)
if (i == 10) temp.Add(c[i], string.Join(" ", o.Skip(10)));
else temp.Add(c[i], o[i]);
return temp;
});
var ps = data.FirstOrDefault(o => o["COMMAND"].Contains(processType));
var cpuPercent = Convert.ToDouble(ps["%CPU"]);//CPU 占用比例
var memoryValue = Convert.ToInt64(ps["RSS"]);//真实内存
var memoryPercent = Convert.ToDouble(ps["%MEM"]);//内存占用比例
var memoryOther = Convert.ToInt64(ps["VSZ"]);//虚拟内存
}
catch (Exception ex) {
}
}
使用 ps aux 命令获取到的CPU使用率,有可能会出现超过100%的问题,可以通过proc下的stat文件,通过进程的使用时间与CPU总使用时间来计算进程的CPU使用率
通过/proc/stat与/proc/[pid]/stat计算进程的CPU使用率
/// <summary>
/// 获取某进程或多个进程的cpu使用率
/// processType 说明:dotnet、test1.dll|test2.dll
/// </summary>
/// <param name="processType"></param>
private void GetCPUByProcStat(string processType = "dotnet")
{
try
{
//获取到相关进程的PID
var str = ExecuteCommand("ps -aux");
var str_l = str.Where(o => !string.IsNullOrWhiteSpace(o)).Select(o => o.Split(' ', StringSplitOptions.RemoveEmptyEntries));
var c = str_l.FirstOrDefault();
var l = str_l.Skip(1);
var data = l.Select(o =>
{
Dictionary<string, string> temp = new Dictionary<string, string>();
for (var i = 0; i < c.Length; i++)
if (i == 10) temp.Add(c[i], string.Join(" ", o.Skip(10)));
else temp.Add(c[i], o[i]);
return temp;
});
List<int> pids = new List<int>();
string[] types = processType.Split("|");
for (int i = 0; i < types.Length; i++)
{
var ps = data.Where(o => o["COMMAND"].Contains(types[i])).ToList();
for (int j = 0; j < ps.Count(); j++)
{
pids.Add(Convert.ToInt32(ps[j]["PID"]));//PID
}
}
//第一次获取CPU总的运行时间
int totalCPUTimeT1 = GetTotalCPUTime();
//第一次获取进程的运行时间
int processCPUTimeT1 = GetProcessCPUTime(pids);
Thread.Sleep(1000);
//第二次获取CPU总的运行时间
int totalCPUTimeT2 = GetTotalCPUTime();
//第二次获取进程的运行时间
int processCPUTimeT2 = GetProcessCPUTime(pids);
//进程的CPU使用率
Double processCPUUse = ((Convert.ToDouble(processCPUTimeT2 - processCPUTimeT1) / Convert.ToDouble(totalCPUTimeT2 - totalCPUTimeT1)) * 100).ToString("F");
}
catch (Exception ex)
{
}
}
/// <summary>
/// 通过/proc/stat文件查看所有的CPU活动信息,返回CPU活动时间
/// </summary>
/// <returns></returns>
private static int GetTotalCPUTime()
{
int totalCPUTime = 0;
var cpus = ExecuteCommand("cat /proc/stat");
var str_cpu = cpus.Where(o => !string.IsNullOrWhiteSpace(o)).Select(o => o.Split(' ', StringSplitOptions.RemoveEmptyEntries));
var cpu = str_cpu.FirstOrDefault();
//totalCPUTime = user + nice + system + idle + iowait + irq + softirq
totalCPUTime = Convert.ToInt32(cpu[1])
+ Convert.ToInt32(cpu[2])
+ Convert.ToInt32(cpu[3])
+ Convert.ToInt32(cpu[4])
+ Convert.ToInt32(cpu[5])
+ Convert.ToInt32(cpu[6])
+ Convert.ToInt32(cpu[7]);
return totalCPUTime;
}
/// <summary>
/// 通过/proc/[PID]/stat 文件查看某一进程的CPU活动信息,返回进程CPU活动时间
/// </summary>
/// <returns></returns>
private static int GetProcessCPUTime(List<int> pids)
{
int totalProcessCPUTime = 0;
for (int i = 0; i < pids.Count; i++)
{
var cpus = ExecuteCommand($"cat /proc/{pids[i]}/stat");
var str_cpu = cpus.Where(o => !string.IsNullOrWhiteSpace(o)).Select(o => o.Split(' ', StringSplitOptions.RemoveEmptyEntries));
var cpu = str_cpu.FirstOrDefault();
//processCPUTime = utime + stime
totalProcessCPUTime += Convert.ToInt32(cpu[13]) + Convert.ToInt32(cpu[14]);
}
return totalProcessCPUTime;
}
获取网卡的实时速率
/// <summary>
/// 监控容器网卡的实时速率
/// </summary>
/// <param name="name"></param>
private void GetDockerReceiveAndTransmit(string name)
{
try
{
//第一次获取接口发送或接收的数据的
var str1 = ExecuteCommand("cat /proc/net/dev");
Thread.Sleep(1000);
//第二次获取接口发送或接收的数据的
var str2 = ExecuteCommand("cat /proc/net/dev");
//第一次接收到的数据
var firstData = GetFormatData(str1);
var firstReceive = 0.0;//第一次收包
var firstTransmit = 0.0;//第一次发包
//var firstPs = firstData.FirstOrDefault(o => o["face"].Contains(name));
if (firstData != null)
{
foreach (var firstPs in firstData)
{
//第一次收包
firstReceive += Convert.ToDouble(firstPs["|bytes"]);
//第一次发包
firstTransmit += Convert.ToDouble(firstPs["multicast|bytes"]);
}
}
//第二次接收到的数据
var secondData = GetFormatData(str2);
var secondReceive = 0.0;//第二次收包
var secondTransmit = 0.0;//第二次发包
//var secondPs = secondData.FirstOrDefault(o => o["face"].Contains(name));
if (secondData!=null) {
foreach (var secondPs in secondData)
{
//第二次收包
secondReceive += Convert.ToDouble(secondPs["|bytes"]);
//第二次发包
secondTransmit += Convert.ToDouble(secondPs["multicast|bytes"]);
}
}
//接收速率
//var receive = (secondReceive - firstReceive) / 1024;
var receive = (secondReceive - firstReceive);
//读取速率
//var transmit = (secondTransmit - firstTransmit) / 1024;
var transmit = (secondTransmit - firstTransmit);
}
catch (Exception ex)
{
}
}
private IEnumerable<Dictionary<string, string>> GetFormatData(string[] str1)
{
var resArry = new string[] { "face", "|bytes", "multicast|bytes" };
var str_1 = str1.Where(o => !string.IsNullOrWhiteSpace(o)).Select(o => o.Split(' ', StringSplitOptions.RemoveEmptyEntries));
var str_2 = str_1.Skip(1);
var c = str_2.FirstOrDefault();
var l = str_2.Skip(1);
var data = l.Select(o =>
{
Dictionary<string, string> temp = new Dictionary<string, string>();
for (var i = 0; i < c.Length; i++)
{
if (resArry.Contains(c[i]))
{
temp.Add(c[i], o[i]);
}
}
return temp;
});
return data;
}
获取磁盘的读写实时速率
/// <summary>
/// 磁盘的读写实时速率
/// </summary>
/// <param name="name"></param>
private void GetDiskReadAndWrite(string name)
{
try
{
var str = ExecuteCommand("iostat -dx");
var str_l = str.Where(o => !string.IsNullOrWhiteSpace(o)).Select(o => o.Split(' ', StringSplitOptions.RemoveEmptyEntries));
var res = str_l.Skip(1);
var c = res.FirstOrDefault();
var l = res.Skip(1);
var data = l.Select(o =>
{
Dictionary<string, string> temp = new Dictionary<string, string>();
for (var i = 0; i < c.Length; i++)
temp.Add(c[i], o[i]);
return temp;
});
var read = 0.0;//磁盘读取速度
var write = 0.0;//磁盘写入速度
//var ps = data.FirstOrDefault();
if (data!=null) {
foreach (var ps in data)
{
read += Convert.ToDouble(ps["r/s"]);//磁盘读取速度
write += Convert.ToDouble(ps["w/s"]);//磁盘写入速度
}
}
}
catch (Exception ex)
{
}
}
执行 linux 命令公共方法
/// <summary>
/// 执行 linux命令
/// </summary>
/// <param name="pmCommand"></param>
/// <returns></returns>
static string[] ExecuteCommand(string pmCommand)
{
var process = new System.Diagnostics.Process
{
StartInfo = new System.Diagnostics.ProcessStartInfo("/bin/bash", "")
};
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
process.StandardInput.WriteLine(pmCommand);
//process.StandardInput.WriteLine("netstat -an |grep ESTABLISHED |wc -l");
process.StandardInput.Close();
var cpuInfo = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Dispose();
var lines = cpuInfo.Split('\n');
return lines;
}