linux_networkload.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_networkload.hpp"
10 
11 #include <algorithm>
12 #include <cstring>
13 #include <exception>
14 #include <fstream>
15 #include <iostream>
16 #include <list>
17 #include <sstream>
18 #include <stdexcept>
19 #include <string>
20 #include <utility>
21 
22 const std::list<std::string> identifiers{"RXbytes",
23  "RXpackets",
24  "RXerrs",
25  "RXdrop",
26  "RXfifo",
27  "RXframe",
28  "RXcompressed",
29  "RXmulticast",
30  "TXbytes",
31  "TXpackets",
32  "TXerrs",
33  "TXdrop",
34  "TXfifo",
35  "TXcolls",
36  "TXcarrier",
37  "TXcompressed"};
38 
39 std::string
41 {
42  auto it = identifiers.begin();
43  std::advance(it, static_cast<uint32_t>(param));
44  return it->data();
45 }
46 
47 std::shared_ptr<networkLoad::networkParser> networkLoad::networkParser::inst = nullptr;
48 
49 networkLoad::networkLoad(std::string ethernetDataFileName, std::string ethName) :
50  ethernetDataFile(std::move(ethernetDataFileName)), ethDev(std::move(ethName))
51 {
52  networkParser::getNetworkParser()->parse(ethernetDataFileName);
53 }
54 
55 void
56 networkLoad::networkParser::parse(const std::string& netFile)
57 {
58 
59  if ((this->currentTime + std::chrono::milliseconds(10)) > std::chrono::system_clock::now())
60  {
61  return;
62  }
63  else
64  {
65  this->timeBefore = this->currentTime;
66  this->currentTime = std::chrono::system_clock::now();
67  }
68 
69  std::ifstream ethFile;
70 
71  try
72  {
73  ethFile.open(netFile);
74  }
75  catch (std::ifstream::failure& e)
76  {
77  throw std::runtime_error("Exception: " + netFile + std::string(e.what()));
78  }
79 
80  this->timeBefore = std::chrono::system_clock::now();
81  this->ethObjOld = this->ethObj;
82 
83  uint32_t lineCnt = 0;
84  for (std::string line; std::getline(ethFile, line); lineCnt++)
85  {
86  if (lineCnt < 2)
87  {
88  continue;
89  }
90  std::stringstream strStream(line);
91  std::string strPart;
92  std::string ifName = "";
93  std::unordered_map<std::string, uint64_t> ifValues;
94  auto it = identifiers.begin();
95  while (strStream >> strPart)
96  {
97  if (ifName.empty())
98  {
99  strPart.erase(std::remove_if(strPart.begin(),
100  strPart.end(),
101  [](auto c) { return !std::isalnum(c); }),
102  strPart.end());
103  ifName = strPart;
104  }
105  else
106  {
107  if (it != identifiers.end())
108  {
109  ifValues[it->data()] = std::stoull(strPart);
110  }
111  it++;
112  }
113  }
114  this->ethObj[ifName] = ifValues;
115  }
116  if (this->ethObjOld.empty())
117  {
118  this->ethObjOld = this->ethObj;
119  }
120 }
121 
122 const std::unordered_map<std::string, uint64_t>&
123 networkLoad::networkParser::getEthObj(const std::string& ethDevice) const
124 {
125  return this->ethObj.at(ethDevice);
126 }
127 
128 const std::unordered_map<std::string, uint64_t>&
129 networkLoad::networkParser::getEthObjOld(const std::string& ethDevice) const
130 {
131  return this->ethObjOld.at(ethDevice);
132 }
133 
134 std::list<std::string>
135 networkLoad::networkParser::getNetworkDevices(std::string netFile)
136 {
137  std::list<std::string> ifList;
138  this->parse(netFile);
139  for (const auto& elem : this->ethObj)
140  {
141  ifList.push_back(elem.first);
142  }
143  return ifList;
144 }
145 
146 networkLoad::networkParser::networkParser()
147 {
148  this->currentTime = std::chrono::system_clock::now() - std::chrono::milliseconds(100);
149  this->timeBefore = std::chrono::system_clock::now();
150 }
151 
152 std::shared_ptr<networkLoad::networkParser>
153 networkLoad::networkParser::getNetworkParser()
154 {
155  if (networkLoad::networkParser::inst == nullptr)
156  {
157  networkLoad::networkParser::inst = std::make_unique<networkLoad::networkParser>();
158  }
159  return networkLoad::networkParser::inst;
160 }
161 
162 const std::chrono::system_clock::time_point
163 networkLoad::networkParser::getTimeStamp() const
164 {
165  return this->currentTime;
166 }
167 
168 const std::chrono::system_clock::time_point
169 networkLoad::networkParser::getTimeBefore() const
170 {
171  return this->timeBefore;
172 }
173 
174 bool
176 {
177  return this->isDeviceAvailable;
178 }
179 
180 std::string
182 {
183  return this->ethDev;
184 }
185 
186 std::list<std::string>
187 networkLoad::scanNetworkDevices(const std::string& ethernetDataFile)
188 {
189 
190  auto parser = networkParser::getNetworkParser();
191  return parser->getNetworkDevices(ethernetDataFile);
192 }
193 
194 std::string
196 {
197  return getBytesString(bytesPerSecond) + "/s";
198 }
199 
200 std::string
201 networkLoad::getBitsPerSeceondString(uint64_t bytesPerSecond)
202 {
203  return getBitsString(bytesPerSecond) + "/s";
204 }
205 
206 std::string
207 networkLoad::getBytesString(uint64_t totalBytes)
208 {
209  uint64_t Bytes = totalBytes;
210  uint64_t kByte = 0;
211  uint64_t mByte = 0;
212  uint64_t gByte = 0;
213  if (Bytes > 1024)
214  {
215  kByte = Bytes / 1024;
216  Bytes %= 1024;
217  }
218  if (kByte > 1024)
219  {
220  mByte = kByte / 1024;
221  kByte %= 1024;
222  }
223  if (mByte > 1024)
224  {
225  gByte = mByte / 1024;
226  mByte %= 1024;
227  }
228 
229  if (gByte > 0)
230  {
231  std::string net;
232  net += std::to_string(gByte);
233  net += ".";
234  net += std::to_string(mByte / 100);
235  net += "gByte";
236  return net;
237  }
238 
239 
240  if (mByte > 0)
241  {
242  std::string net;
243  net += std::to_string(mByte);
244  net += ".";
245  net += std::to_string(kByte / 100);
246  net += "mByte";
247  return net;
248  }
249 
250  if (kByte > 0)
251  {
252  std::string net;
253  net += std::to_string(kByte);
254  net += ".";
255  net += std::to_string(Bytes / 100);
256  net += "kByte";
257  return net;
258  }
259 
260  std::string net;
261  net += std::to_string(Bytes);
262  net += "Byte";
263  return net;
264 }
265 
266 std::string
267 networkLoad::getBitsString(uint64_t totalBytes)
268 {
269  uint64_t Bytes = totalBytes * 8;
270  uint64_t kByte = 0;
271  uint64_t mByte = 0;
272  uint64_t gByte = 0;
273  if (Bytes > 1024)
274  {
275  kByte = Bytes / 1024;
276  Bytes %= 1024;
277  }
278  if (kByte > 1024)
279  {
280  mByte = kByte / 1024;
281  kByte %= 1024;
282  }
283  if (mByte > 1024)
284  {
285  gByte = mByte / 1024;
286  mByte %= 1024;
287  }
288 
289  if (gByte > 0)
290  {
291  std::string net;
292  net += std::to_string(gByte);
293  net += ".";
294  net += std::to_string(mByte / 100);
295  net += "gBit";
296  return net;
297  }
298 
299 
300  if (mByte > 0)
301  {
302  std::string net;
303  net += std::to_string(mByte);
304  net += ".";
305  net += std::to_string(kByte / 100);
306  net += "mBit";
307  return net;
308  }
309 
310  if (kByte > 0)
311  {
312  std::string net;
313  net += std::to_string(kByte);
314  net += ".";
315  net += std::to_string(Bytes / 100);
316  net += "kBit";
317  return net;
318  }
319 
320 
321  std::string net;
322  net += std::to_string(Bytes);
323  net += "Bit";
324  return net;
325 }
326 
327 uint64_t
328 networkLoad::getParamPerSecond(std::string designator)
329 {
330  networkParser::getNetworkParser()->parse(this->ethernetDataFile);
331  if (!std::count_if(identifiers.begin(),
332  identifiers.end(),
333  [designator](auto elem) { return elem == designator; }))
334  {
335  throw std::runtime_error("invalid designator: " + designator);
336  }
337  auto before = networkParser::getNetworkParser()->getTimeBefore();
338  auto current = networkParser::getNetworkParser()->getTimeStamp();
339 
340  auto msec = std::chrono::duration_cast<std::chrono::milliseconds>(before - current);
341 
342  uint64_t Bytes = (networkParser::getNetworkParser()->getEthObj(this->ethDev).at(designator) -
343  networkParser::getNetworkParser()->getEthObjOld(this->ethDev).at(designator));
344  if (static_cast<unsigned long>(msec.count()) <= 0)
345  {
346  Bytes /= 1;
347  }
348  else
349  {
350  Bytes /= static_cast<unsigned long>(msec.count());
351  }
352  return Bytes;
353 }
354 
355 uint64_t
356 networkLoad::getParamSinceStartup(std::string designator)
357 {
358  networkParser::getNetworkParser()->parse(this->ethernetDataFile);
359  auto ifObj = networkParser::getNetworkParser()->getEthObj(this->ethDev);
360  if (!std::count_if(identifiers.begin(),
361  identifiers.end(),
362  [designator](auto elem) { return elem == designator; }))
363  {
364  throw std::runtime_error("invalid designator: " + designator);
365  }
366  return ifObj[designator];
367 }
networkLoad::networkLoad
networkLoad(std::string ethernetDataFileName="/proc/net/dev", std::string ethName="eth0")
Definition: linux_networkload.cpp:49
networkLoad::getParamSinceStartup
uint64_t getParamSinceStartup(std::string designator)
Definition: linux_networkload.cpp:356
networkLoad::mapEnumToString
static std::string mapEnumToString(networkLoad::networkParam param)
Definition: linux_networkload.cpp:40
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
networkLoad::getBitsString
static std::string getBitsString(uint64_t totalBytes)
Definition: linux_networkload.cpp:267
networkLoad::getBytesPerSeceondString
static std::string getBytesPerSeceondString(uint64_t bytesPerSecond)
Definition: linux_networkload.cpp:195
linux_networkload.hpp
networkLoad::scanNetworkDevices
static std::list< std::string > scanNetworkDevices(const std::string &ethernetDataFile="/proc/net/dev")
Definition: linux_networkload.cpp:187
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
networkLoad::networkParam
networkParam
Definition: linux_networkload.hpp:51
networkLoad::getBytesString
static std::string getBytesString(uint64_t totalBytes)
Definition: linux_networkload.cpp:207
IceStorm::parser
Parser * parser
Definition: Parser.cpp:34
std
Definition: Application.h:66
networkLoad::getDeviceName
std::string getDeviceName()
Definition: linux_networkload.cpp:181
networkLoad::getParamPerSecond
uint64_t getParamPerSecond(std::string designator)
Definition: linux_networkload.cpp:328
networkLoad::getBitsPerSeceondString
static std::string getBitsPerSeceondString(uint64_t bytesPerSecond)
Definition: linux_networkload.cpp:201
networkLoad::isDeviceUp
bool isDeviceUp() const
Definition: linux_networkload.cpp:175
identifiers
const std::list< std::string > identifiers
Definition: linux_networkload.cpp:22