22 static const std::list<std::string> stats{
23 "pid",
"comm",
"state",
"ppid",
"pgrp",
"session",
24 "tty_nr",
"tpgid",
"flags",
"minflt",
"cminflt",
"majflt",
25 "cmajflt",
"utime",
"stime",
"cutime",
"cstime",
"priority",
26 "nice",
"num_threads",
"itrealvalue",
"starttime",
"vsize",
"rss",
27 "rsslim",
"startcode",
"endcode",
"startstack",
"kstkesp",
"kstkeip",
28 "signal",
"blocked",
"sigignore",
"sigcatch",
"wchan",
"nswap",
29 "cnswap",
"exit_signal",
"processor",
"rt_priority",
"policy",
"delaycct_blkio_ticks",
30 "guest_time",
"cguest_time",
"start_data",
"end_data",
"start_brk",
"arg_start",
31 "arg_end",
"env_start",
"env_end",
"exit_code"};
33 std::map<std::string, double>
36 this->findProcesses();
37 return this->procCPUUsage;
41 linuxProcessLoad::calculateProcessLoad()
43 auto [cpuTotalUserTime, cpuTotalUserLowTime, cpuTotalSysTime, cpuTotalIdleTime] = CpuTimes;
45 auto [oldCpuTotalUserTime, oldCpuTotalUserLowTime, oldCpuTotalSysTime, oldCpuTotalIdleTime] =
47 auto TotalUserTime = cpuTotalUserTime - oldCpuTotalUserTime;
48 auto TotalSysTime = cpuTotalSysTime - oldCpuTotalSysTime;
50 this->procCPUUsage.clear();
51 for (
const auto& elem : processStat)
53 auto pid = elem.first;
56 auto oldProc = oldProcessStat.at(pid);
57 auto proc = elem.second;
58 auto procName = proc.at(
"comm");
60 cpuTime += (std::stoull(proc.at(
"utime")) - std::stoull(oldProc.at(
"utime")));
61 cpuTime += (std::stoull(proc.at(
"stime")) - std::stoull(oldProc.at(
"stime")));
64 double percentage = ((
static_cast<double>(cpuTime) * 100.0) /
65 static_cast<double>((TotalUserTime + TotalSysTime)));
69 this->procCPUUsage[procName] = percentage;
74 std::cerr <<
"process: " << pid <<
" disappeared in meantime" << std::endl;
80 linuxProcessLoad::findProcesses()
83 auto cpuMonitoring = std::make_unique<cpuLoad>(
"/proc/stat");
85 this->CpuTimes = cpuMonitoring->getCpuTimes();
88 std::string path{
"/proc/"};
89 std::vector<std::string> processes;
90 for (
auto& elem : std::filesystem::directory_iterator(path))
92 auto procPath = elem.path().string();
95 procPath.erase(procPath.begin(), procPath.begin() +
static_cast<int32_t
>(path.size()));
96 if (std::isdigit(procPath.at(0)))
99 procPath.begin(), procPath.end(), [](
auto c) { return std::isalpha(c); }))
101 parseProcess(procPath);
106 this->calculateProcessLoad();
108 this->oldProcessStat = this->processStat;
109 this->oldCpuTimes = this->CpuTimes;
113 linuxProcessLoad::parseProcess(
const std::string& pid)
115 std::string path{
"/proc/" + pid +
"/stat"};
116 std::ifstream ethFile(path);
119 std::unordered_map<std::string, std::string> procStat;
120 auto identifierStart = stats.begin();
128 bool isProcessFound =
false;
129 while (ethFile >> strPart)
132 if (identifierStart != stats.end())
136 procStat[identifierStart->data()] +=
" " + strPart;
138 if (std::count_if(strPart.begin(), strPart.end(), [](
auto c) { return c ==
'('; }))
140 isProcessFound =
true;
141 procStat[identifierStart->data()] = strPart;
145 procStat[identifierStart->data()] = strPart;
149 if (std::count_if(strPart.begin(), strPart.end(), [](
auto c) { return c ==
')'; }))
151 isProcessFound =
false;
161 procStat[
"comm"].erase(std::remove_if(procStat[
"comm"].begin(),
162 procStat[
"comm"].end(),
163 [](
auto c) {
return c ==
'(' ||
c ==
')'; }),
164 procStat[
"comm"].end());
165 processStat[pid] = procStat;