55
66#include " Monitoring/ProcessMonitor.h"
77#include " Exceptions/MonitoringInternalException.h"
8+ #include " MonLogger.h"
89#include < boost/algorithm/string/classification.hpp>
9- #include < boost/algorithm/string/split.hpp>
1010#include < chrono>
11- #include " MonLogger.h"
1211#include < sstream>
12+ #include < cmath>
1313
1414namespace o2
1515{
@@ -20,18 +20,16 @@ namespace monitoring
2020ProcessMonitor::ProcessMonitor ()
2121{
2222 mPid = static_cast <unsigned int >(::getpid ());
23- for (auto const param : mPsParams ) {
24- mPsCommand = mPsCommand .empty () ? param.first : mPsCommand += (' ,' + param.first );
25- }
26- mPsCommand = " ps --no-headers -o " + mPsCommand + " --pid " ;
23+ getrusage (RUSAGE_SELF, &mPreviousGetrUsage );
24+ mTimeLastRun = std::chrono::high_resolution_clock::now ();
2725}
2826
2927std::vector<Metric> ProcessMonitor::getNetworkUsage ()
3028{
3129 std::vector<Metric> metrics;
3230 std::stringstream ss;
3331 // get bytes received and transmitted per interface
34- ss << " cat /proc/" << mPid << " /net/dev | tail -n +3 |awk ' {print $1 $2 \" :\" $10}'" ;
32+ ss << " cat /proc/" << mPid << " /net/dev | tail -n +3 | grep -v -e 'lo' -e 'virbr0' | awk ' {print $1 $2 \" :\" $10}'" ;
3533 std::string output = exec (ss.str ().c_str ());
3634 // for each line (each network interfrace)
3735 std::istringstream iss (output);
@@ -50,31 +48,37 @@ std::vector<Metric> ProcessMonitor::getNetworkUsage()
5048 return metrics;
5149}
5250
53- std::vector< Metric> ProcessMonitor::getPidStatus ()
51+ Metric ProcessMonitor::getMemoryUsage ()
5452{
55- std::vector<Metric> metrics;
56- std::string command = mPsCommand + std::to_string (mPid );
53+ std::string command = " ps --no-headers -o pmem --pid " + std::to_string (mPid );
5754 std::string output = exec (command.c_str ());
58-
59- // split output into std vector
60- std::vector<std::string> pidParams;
6155 boost::trim (output);
62- boost::split (pidParams, output, boost::is_any_of (" \t " ), boost::token_compress_on);
63-
64- // parse output, cast to propriate types
65- auto j = mPsParams .begin ();
66- for (auto i = pidParams.begin (); i != pidParams.end (); ++i, ++j) {
67- if (j->second == MetricType::DOUBLE) {
68- metrics.emplace_back (Metric{std::stod (*i), j->first });
69- }
70- else if (j->second == MetricType::INT) {
71- metrics.emplace_back (Metric{std::stoi (*i), j->first });
72- }
73- else {
74- metrics.emplace_back (Metric{*i, j->first });
75- }
56+ return Metric{std::stod (output), " memoryUsagePercentage" };
57+ }
58+
59+ std::vector<Metric> ProcessMonitor::getCpuAndContexts () {
60+ std::vector<Metric> metrics;
61+ struct rusage currentUsage;
62+ getrusage (RUSAGE_SELF, ¤tUsage);
63+ auto timeNow = std::chrono::high_resolution_clock::now ();
64+ double timePassed = std::chrono::duration_cast<std::chrono::microseconds>(timeNow - mTimeLastRun ).count ();
65+ if (timePassed < 950 ) { // do not run too often
66+ throw MonitoringInternalException (" Process Monitor getrusage" , " Do not invoke more often then 1ms" );
7667 }
68+ double fractionCpuUsed = (
69+ currentUsage.ru_utime .tv_sec *1000000.0 + currentUsage.ru_utime .tv_usec - (mPreviousGetrUsage .ru_utime .tv_sec *1000000.0 + mPreviousGetrUsage .ru_utime .tv_usec )
70+ + currentUsage.ru_stime .tv_sec *1000000.0 + currentUsage.ru_stime .tv_usec - (mPreviousGetrUsage .ru_stime .tv_sec *1000000.0 + mPreviousGetrUsage .ru_stime .tv_usec )
71+ ) / timePassed;
72+
73+ metrics.emplace_back (Metric{
74+ static_cast <double >(std::round (fractionCpuUsed * 100.0 * 100.0 ) / 100.0 ), " cpuUsedPercentage"
75+ });
76+ metrics.emplace_back (Metric{
77+ static_cast <uint64_t >(currentUsage.ru_nivcsw - mPreviousGetrUsage .ru_nivcsw ), " involuntaryContextSwitches"
78+ });
7779
80+ mTimeLastRun = timeNow;
81+ mPreviousGetrUsage = currentUsage;
7882 return metrics;
7983}
8084
0 commit comments