4 #include "SystemMetricCollector.hh"
5 #include "sys/sysinfo.h"
9 #define MLEVEL_PROCESS 6
12 #define MLEVEL_NETWORK 9
15 : lastCPU_(), lastProcessCPUTimes_(), lastProcessCPUTime_(0), sendProcessMetrics_(processMetrics), sendSystemMetrics_(systemMetrics)
17 lastCPU_ = ReadProcStat_();
18 lastProcessCPUTime_ = times(&lastProcessCPUTimes_);
19 thisNetStat_ = ReadProcNetDev_();
20 lastNetStat_ = thisNetStat_;
25 auto thisCPU = ReadProcStat_();
26 auto totalUsage = thisCPU.totalUsage - lastCPU_.totalUsage;
27 auto total = thisCPU.total - lastCPU_.total;
29 return totalUsage * 100.0 /
static_cast<double>(total);
34 struct tms this_times;
35 auto now = times(&this_times);
41 auto delta_t = now - lastProcessCPUTime_;
42 auto utime = this_times.tms_utime - lastProcessCPUTimes_.tms_utime;
43 auto stime = this_times.tms_stime - lastProcessCPUTimes_.tms_stime;
45 lastProcessCPUTime_ = now;
46 lastProcessCPUTimes_ = this_times;
48 return utime + stime * 100.0 /
static_cast<double>(delta_t);
53 struct sysinfo meminfo;
54 auto err = sysinfo(&meminfo);
57 return meminfo.freeram * meminfo.mem_unit;
64 struct sysinfo meminfo;
65 auto err = sysinfo(&meminfo);
68 return meminfo.bufferram * meminfo.mem_unit;
75 struct sysinfo meminfo;
76 auto err = sysinfo(&meminfo);
79 return meminfo.totalram * meminfo.mem_unit;
86 struct sysinfo meminfo;
87 auto err = sysinfo(&meminfo);
90 auto available = meminfo.freeram + (buffers ? meminfo.bufferram : 0);
91 return available * 100.0 /
static_cast<double>(meminfo.totalram);
98 auto filp = fopen(
"/proc/self/statm",
"r");
100 fscanf(filp,
"%*u %lu", &mem);
102 return mem * sysconf(_SC_PAGESIZE);
107 auto proc = GetProcessMemUsage();
108 auto total = GetTotalRAM();
109 return proc * 100.0 /
static_cast<double>(total);
115 return thisNetStat_.recv_bytes - lastNetStat_.recv_bytes;
121 return thisNetStat_.send_bytes - lastNetStat_.send_bytes;
127 return thisNetStat_.recv_errs - lastNetStat_.recv_errs;
133 return thisNetStat_.send_errs - lastNetStat_.send_errs;
138 auto start_time = std::chrono::steady_clock::now();
139 std::list<std::unique_ptr<MetricData>> output;
140 if (sendProcessMetrics_)
145 if (sendSystemMetrics_)
153 output.emplace_back(
new MetricData(
"Network Receive Rate", GetNetworkReceiveBytes(),
"B", MLEVEL_NETWORK,
MetricMode::Rate,
"",
false));
154 output.emplace_back(
new MetricData(
"Network Send Rate", GetNetworkSendBytes(),
"B", MLEVEL_NETWORK,
MetricMode::Rate,
"",
false));
160 <<
"Time to collect system metrics: "
161 << std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start_time).count()
166 artdaq::SystemMetricCollector::cpustat artdaq::SystemMetricCollector::ReadProcStat_()
168 auto filp = fopen(
"/proc/stat",
"r");
171 fscanf(filp,
"cpu %llu %llu %llu %llu %llu %llu %llu", &this_cpu.user, &this_cpu.nice, &this_cpu.system,
172 &this_cpu.idle, &this_cpu.iowait, &this_cpu.irq, &this_cpu.softirq);
175 this_cpu.totalUsage =
176 this_cpu.user + this_cpu.nice + this_cpu.system + this_cpu.iowait + this_cpu.irq + this_cpu.softirq;
177 this_cpu.total = this_cpu.totalUsage + this_cpu.idle;
182 artdaq::SystemMetricCollector::netstat artdaq::SystemMetricCollector::ReadProcNetDev_()
184 auto filp = fopen(
"/proc/net/dev",
"r");
185 char buf[200], ifname[20];
187 auto start_time = std::chrono::steady_clock::now();
190 for (
int i = 0; i < 2; i++)
192 fgets(buf, 200, filp);
195 unsigned long rbytes, rerrs, rdrop, rfifo, rframe, tbytes, terrs, tdrop, tfifo, tcolls, tcarrier;
197 while (fgets(buf, 200, filp))
199 sscanf(buf,
"%[^:]: %lu %*u %lu %lu %lu %lu %*u %*u %lu %*u %lu %lu %lu %lu %lu", ifname, &rbytes, &rerrs,
200 &rdrop, &rfifo, &rframe, &tbytes, &terrs, &tdrop, &tfifo, &tcolls, &tcarrier);
202 if (ifname[0] ==
'e')
204 auto total_rerrs = rerrs + rdrop + rfifo + rframe;
205 auto total_terrs = terrs + tdrop + tfifo + tcolls + tcarrier;
206 output.recv_bytes += rbytes;
207 output.send_bytes += tbytes;
208 output.send_errs += total_terrs;
209 output.recv_errs += total_rerrs;
212 output.collectionTime = start_time;
218 void artdaq::SystemMetricCollector::UpdateNetstat_()
220 auto start_time = std::chrono::steady_clock::now();
222 if (std::chrono::duration_cast<std::chrono::duration<
double, std::ratio<1>>>(start_time - thisNetStat_.collectionTime)
225 auto output = ReadProcNetDev_();
226 lastNetStat_ = thisNetStat_;
227 thisNetStat_ = output;
unsigned long GetAvailableRAM()
Get the amount of available RAM in the system
Report the sum of all values. Use for counters to report accurate results.
unsigned long GetProcessMemUsage()
Get the amount of RAM being used by this process
unsigned long GetNetworkReceiveErrors()
Get the number of network receive errors in the last network collection interval (1.0 s)
over. Use to create rates from counters.
Report only the last value recorded. Useful for event counters, run numbers, etc. ...
unsigned long GetBufferedRAM()
Get the amount of RAM currently being used for cache
std::list< std::unique_ptr< MetricData > > SendMetrics()
Send the configured metrics
unsigned long GetNetworkSendBytes()
Get the amount of data sent to the network in the last network collection interval (1...
double GetAvailableRAMPercent(bool buffers)
Get the percentage of available RAM
Small structure used to hold a metric data point before sending to the metric plugins ...
double GetProcessCPUUsagePercent()
Return the current amount of CPU usage for the current process, %
unsigned long GetTotalRAM()
Get the total amount of RAM in the system
Report the average of all values. Use for rates to report accurate results.
SystemMetricCollector(bool processMetrics, bool systemMetrics)
SystemMetricCollector Constructor
double GetProcessMemUsagePercent()
Get the amount of RAM being used by this process
double GetSystemCPUUsagePercent()
Return the current overall system CPU usage in %
unsigned long GetNetworkReceiveBytes()
Get the amount of data received from the network in the last network collection interval (1...
unsigned long GetNetworkSendErrors()
Get the number of network send errors in the last network collection interval (1.0 s) ...