linux_cpuload.cpp
Go to the documentation of this file.
1/**
2 * @author: Daniel Fuchs
3 * @contact: fuxeysolutions@gmail.com
4 *
5 * distributed under the MIT License (MIT).
6 * Copyright (c) Daniel Fuchs
7 *
8 */
9#include "linux_cpuload.hpp"
10
11#include <chrono>
12#include <cmath>
13#include <fstream>
14#include <iostream>
15#include <sstream>
16#include <stdexcept>
17#include <thread>
18
19const std::vector<std::string> cpuIdentifiers{"user",
20 "nice",
21 "system",
22 "idle",
23 "iowait",
24 "irq",
25 "softirq",
26 "steal",
27 "guest",
28 "guest_nice"};
29
30void
32{
33 this->cpuLoadMap = this->parseStatFile(this->procFile);
34 this->currentTime = std::chrono::system_clock::now();
35 std::this_thread::sleep_for(std::chrono::milliseconds(100));
36
37 this->upDateCPUUsage();
38}
39
40void
41cpuLoad::upDateCPUUsage()
42{
43 if (!((this->currentTime + std::chrono::milliseconds(10)) > std::chrono::system_clock::now()))
44 {
45 this->oldCpuLoadMap = this->cpuLoadMap;
46 this->currentTime = std::chrono::system_clock::now();
47 this->cpuLoadMap = this->parseStatFile(this->procFile);
48 this->calculateCpuUsage();
49 }
50}
51
52double
54{
55
56 this->upDateCPUUsage();
57 return this->cpuUsage.at("cpu");
58}
59
60std::vector<double>
62{
63 this->upDateCPUUsage();
64 std::vector<double> percents;
65 for (const auto& elem : this->cpuUsage)
66 {
67 if (elem.first == "cpu")
68 {
69 continue;
70 }
71 percents.push_back(elem.second);
72 }
73 return percents;
74}
75
76void
77cpuLoad::calculateCpuUsage()
78{
79 for (const auto& elem : this->cpuLoadMap)
80 {
81 if (this->cpuLoadMap.at(elem.first).at("user") <
82 this->oldCpuLoadMap.at(elem.first).at("user") ||
83 this->cpuLoadMap.at(elem.first).at("nice") <
84 this->oldCpuLoadMap.at(elem.first).at("nice") ||
85 this->cpuLoadMap.at(elem.first).at("system") <
86 this->oldCpuLoadMap.at(elem.first).at("system") ||
87 this->cpuLoadMap.at(elem.first).at("idle") <
88 this->oldCpuLoadMap.at(elem.first).at("idle"))
89 {
90 }
91 else
92 {
93 auto total = (this->cpuLoadMap.at(elem.first).at("user") -
94 this->oldCpuLoadMap.at(elem.first).at("user")) +
95 (this->cpuLoadMap.at(elem.first).at("nice") -
96 this->oldCpuLoadMap.at(elem.first).at("nice")) +
97 (this->cpuLoadMap.at(elem.first).at("system") -
98 this->oldCpuLoadMap.at(elem.first).at("system"));
99
100 double percent = total;
101 total += (this->cpuLoadMap.at(elem.first).at("idle") -
102 this->oldCpuLoadMap.at(elem.first).at("idle"));
103 percent /= total;
104 percent *= 100.0;
105 this->cpuUsage[elem.first] = percent;
106 }
107 }
108}
109
110std::map<std::string, std::unordered_map<std::string, uint64_t>>
111cpuLoad::parseStatFile(const std::string& fileName)
112{
113
114 std::map<std::string, std::unordered_map<std::string, uint64_t>> cpuLoad_;
115
116 try
117 {
118 std::ifstream cpuFile(fileName);
119
120 uint32_t lineCnt = 0;
121 bool infoValid = true;
122 for (std::string line; std::getline(cpuFile, line) && infoValid; lineCnt++)
123 {
124
125 std::stringstream strStream(line);
126 std::string strPart;
127 std::string cpuNum;
128 auto it = cpuIdentifiers.begin();
129 std::unordered_map<std::string, uint64_t> cpuValues;
130 while (strStream >> strPart)
131 {
132 if (cpuNum.empty())
133 {
134 if (strPart.find("cpu") != std::string::npos)
135 {
136 cpuNum = strPart;
137 continue;
138 }
139 else
140 {
141 infoValid = false;
142 break;
143 }
144 }
145 if (it != cpuIdentifiers.end())
146 {
147 cpuValues[it->data()] = std::stoull(strPart);
148 }
149 if (it->data() == cpuIdentifiers.at(4))
150 {
151 break;
152 }
153 it++;
154 }
155 if (!cpuNum.empty())
156 {
157 cpuLoad_[cpuNum] = cpuValues;
158 }
159 }
160 }
161 catch (std::ifstream::failure& e)
162 {
163 throw std::runtime_error("Exception: " + fileName + std::string(e.what()));
164 }
165 return cpuLoad_;
166}
167
168std::string
169cpuLoad::getCPUName(const std::string& cpuNameFile)
170{
171
172 if (!this->cpuName.empty())
173 {
174 return this->cpuName;
175 }
176
177 std::ifstream file;
178 file.open(cpuNameFile);
179
180 if (!file.is_open())
181 {
182 throw std::runtime_error("unable to open " + cpuNameFile);
183 }
184 std::string line;
185 while (std::getline(file, line))
186 {
187 if (line.find("model name") != std::string::npos)
188 {
189 size_t pos = line.find(':');
190 if (pos != std::string::npos)
191 {
192 this->cpuName = line.substr(pos, line.size());
193 return this->cpuName;
194 }
195 }
196 }
197 return std::string();
198}
std::string getCPUName(const std::string &cpuNameFile="/proc/cpuinfo")
get CPU Description
double getCurrentCpuUsage()
get current cpu load in 0-100%
void initCpuUsage()
initialize the parsing algo
std::vector< double > getCurrentMultiCoreUsage()
get cpu Usage of all cores in percent
const std::vector< std::string > cpuIdentifiers