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 */
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
22const 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
39std::string
41{
42 auto it = identifiers.begin();
43 std::advance(it, static_cast<uint32_t>(param));
44 return it->data();
45}
46
47std::shared_ptr<networkLoad::networkParser> networkLoad::networkParser::inst = nullptr;
48
49networkLoad::networkLoad(std::string ethernetDataFileName, std::string ethName) :
50 ethernetDataFile(std::move(ethernetDataFileName)), ethDev(std::move(ethName))
51{
52 networkParser::getNetworkParser()->parse(ethernetDataFileName);
53}
54
55void
56networkLoad::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
122const std::unordered_map<std::string, uint64_t>&
123networkLoad::networkParser::getEthObj(const std::string& ethDevice) const
124{
125 return this->ethObj.at(ethDevice);
126}
127
128const std::unordered_map<std::string, uint64_t>&
129networkLoad::networkParser::getEthObjOld(const std::string& ethDevice) const
130{
131 return this->ethObjOld.at(ethDevice);
132}
133
134std::list<std::string>
135networkLoad::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
146networkLoad::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
152std::shared_ptr<networkLoad::networkParser>
153networkLoad::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
162const std::chrono::system_clock::time_point
163networkLoad::networkParser::getTimeStamp() const
164{
165 return this->currentTime;
166}
167
168const std::chrono::system_clock::time_point
169networkLoad::networkParser::getTimeBefore() const
170{
171 return this->timeBefore;
172}
173
174bool
176{
177 return this->isDeviceAvailable;
178}
179
180std::string
182{
183 return this->ethDev;
184}
185
186std::list<std::string>
187networkLoad::scanNetworkDevices(const std::string& ethernetDataFile)
188{
189
190 auto parser = networkParser::getNetworkParser();
191 return parser->getNetworkDevices(ethernetDataFile);
192}
193
194std::string
196{
197 return getBytesString(bytesPerSecond) + "/s";
198}
199
200std::string
202{
203 return getBitsString(bytesPerSecond) + "/s";
204}
205
206std::string
207networkLoad::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
266std::string
267networkLoad::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
327uint64_t
328networkLoad::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
355uint64_t
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}
constexpr T c
uint64_t getParamPerSecond(std::string designator)
static std::string getBitsPerSeceondString(uint64_t bytesPerSecond)
static std::string getBitsString(uint64_t totalBytes)
bool isDeviceUp() const
uint64_t getParamSinceStartup(std::string designator)
static std::list< std::string > scanNetworkDevices(const std::string &ethernetDataFile="/proc/net/dev")
std::string getDeviceName()
static std::string getBytesString(uint64_t totalBytes)
static std::string mapEnumToString(networkLoad::networkParam param)
networkLoad(std::string ethernetDataFileName="/proc/net/dev", std::string ethName="eth0")
static std::string getBytesPerSeceondString(uint64_t bytesPerSecond)
const std::list< std::string > identifiers