-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathProcessMonitor.cxx
More file actions
97 lines (87 loc) · 2.87 KB
/
ProcessMonitor.cxx
File metadata and controls
97 lines (87 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
///
/// \file ProcessMonitor.cxx
/// \author Adam Wegrzynek <adam.wegrzynek@cern.ch>
///
#include "Monitoring/ProcessMonitor.h"
#include "Exceptions/MonitoringInternalException.h"
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <chrono>
#include "MonLogger.h"
#include <sstream>
namespace o2
{
/// ALICE O2 Monitoring system
namespace monitoring
{
ProcessMonitor::ProcessMonitor()
{
mPid = static_cast<unsigned int>(::getpid());
for (auto const param : mPsParams) {
mPsCommand = mPsCommand.empty() ? param.first : mPsCommand += (',' + param.first);
}
mPsCommand = "ps --no-headers -o " + mPsCommand + " --pid ";
}
std::vector<Metric> ProcessMonitor::getNetworkUsage()
{
std::vector<Metric> metrics;
std::stringstream ss;
// get bytes received and transmitted per interface
ss << "cat /proc/" << mPid << "/net/dev | tail -n +3 |awk ' {print $1 $2 \":\" $10}'";
std::string output = exec(ss.str().c_str());
// for each line (each network interfrace)
std::istringstream iss(output);
for (std::string line; std::getline(iss, line); ) {
auto position = line.find(":");
auto secondPosition = line.find(":", position + 1);
metrics.emplace_back(Metric{
static_cast<uint64_t>(std::stoull(line.substr(position + 1, secondPosition - position - 1))),
"bytesReceived"}.addTags({{"if", line.substr(0, position)}})
);
metrics.emplace_back(Metric{
static_cast<uint64_t>(std::stoull(line.substr(secondPosition + 1, line.size()))),
"bytesTransmitted"}.addTags({{"if", line.substr(0, position)}})
);
}
return metrics;
}
std::vector<Metric> ProcessMonitor::getPidStatus()
{
std::vector<Metric> metrics;
std::string command = mPsCommand + std::to_string(mPid);
std::string output = exec(command.c_str());
// split output into std vector
std::vector<std::string> pidParams;
boost::trim(output);
boost::split(pidParams, output, boost::is_any_of("\t "), boost::token_compress_on);
// parse output, cast to propriate types
auto j = mPsParams.begin();
for (auto i = pidParams.begin(); i != pidParams.end(); ++i, ++j) {
if (j->second == MetricType::DOUBLE) {
metrics.emplace_back(Metric{std::stod(*i), j->first});
}
else if (j->second == MetricType::INT) {
metrics.emplace_back(Metric{std::stoi(*i), j->first});
}
else {
metrics.emplace_back(Metric{*i, j->first});
}
}
return metrics;
}
std::string ProcessMonitor::exec(const char* cmd)
{
char buffer[128];
std::string result = "";
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw MonitoringInternalException("Process Monitor exec", "Issue encountered when running 'ps' (popen)");
}
while (!feof(pipe.get())) {
if (fgets(buffer, 128, pipe.get()) != NULL)
result += buffer;
}
return result;
}
} // namespace monitoring
} // namespace o2