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