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 
19 const 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 
30 void
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 
40 void
41 cpuLoad::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 
52 double
54 {
55 
56  this->upDateCPUUsage();
57  return this->cpuUsage.at("cpu");
58 }
59 
60 std::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 
76 void
77 cpuLoad::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 
110 std::map<std::string, std::unordered_map<std::string, uint64_t>>
111 cpuLoad::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 
168 std::string
169 cpuLoad::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 }
cpuLoad::getCPUName
std::string getCPUName(const std::string &cpuNameFile="/proc/cpuinfo")
get CPU Description
Definition: linux_cpuload.cpp:169
linux_cpuload.hpp
cpuLoad::getCurrentCpuUsage
double getCurrentCpuUsage()
get current cpu load in 0-100%
Definition: linux_cpuload.cpp:53
cpuIdentifiers
const std::vector< std::string > cpuIdentifiers
Definition: linux_cpuload.cpp:19
cpuLoad::initCpuUsage
void initCpuUsage()
initialize the parsing algo
Definition: linux_cpuload.cpp:31
cpuLoad::getCurrentMultiCoreUsage
std::vector< double > getCurrentMultiCoreUsage()
get cpu Usage of all cores in percent
Definition: linux_cpuload.cpp:61