|
|
@ -18,6 +18,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
using namespace srsran;
|
|
|
|
using namespace srsran;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const uint32_t cpu_count = ::sysconf(_SC_NPROCESSORS_CONF);
|
|
|
|
|
|
|
|
static const float ticks_per_second = ::sysconf(_SC_CLK_TCK);
|
|
|
|
|
|
|
|
|
|
|
|
sys_metrics_processor::proc_stats_info::proc_stats_info()
|
|
|
|
sys_metrics_processor::proc_stats_info::proc_stats_info()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::string line;
|
|
|
|
std::string line;
|
|
|
@ -55,6 +58,9 @@ sys_metrics_t sys_metrics_processor::get_metrics()
|
|
|
|
// Get the memory metrics.
|
|
|
|
// Get the memory metrics.
|
|
|
|
calculate_mem_usage(metrics);
|
|
|
|
calculate_mem_usage(metrics);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Calculate cpu metrics.
|
|
|
|
|
|
|
|
calculate_cpu_metrics(metrics, measure_interval_ms / 1000.f);
|
|
|
|
|
|
|
|
|
|
|
|
// Get the stats from the proc.
|
|
|
|
// Get the stats from the proc.
|
|
|
|
proc_stats_info current_query;
|
|
|
|
proc_stats_info current_query;
|
|
|
|
metrics.thread_count = current_query.num_threads;
|
|
|
|
metrics.thread_count = current_query.num_threads;
|
|
|
@ -80,23 +86,54 @@ float sys_metrics_processor::calculate_cpu_usage(const proc_stats_info& current_
|
|
|
|
return 0.f;
|
|
|
|
return 0.f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const uint32_t cpu_count = ::sysconf(_SC_NPROCESSORS_CONF);
|
|
|
|
|
|
|
|
static const float ticks_per_second = ::sysconf(_SC_CLK_TCK);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ((current_query.stime + current_query.utime) - (last_query.stime + last_query.utime)) * 100.f /
|
|
|
|
return ((current_query.stime + current_query.utime) - (last_query.stime + last_query.utime)) * 100.f /
|
|
|
|
(cpu_count * ticks_per_second * delta_time_in_seconds);
|
|
|
|
(cpu_count * ticks_per_second * delta_time_in_seconds);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Extracts and returns the memory size from the given line.
|
|
|
|
sys_metrics_processor::cpu_metrics_t sys_metrics_processor::read_cpu_idle_from_line(const std::string& line) const
|
|
|
|
static uint32_t read_memory_value_from_line(const std::string& line)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::istringstream reader(line);
|
|
|
|
std::istringstream reader(line);
|
|
|
|
std::string label, unit;
|
|
|
|
cpu_metrics_t m;
|
|
|
|
uint32_t value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reader >> label >> value >> unit;
|
|
|
|
reader >> m.name >> m.user >> m.nice >> m.system >> m.idle >> m.iowait >> m.irq >> m.softirq;
|
|
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
return m;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sys_metrics_processor::calculate_cpu_metrics(sys_metrics_t& metrics, float delta_time_in_seconds)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
metrics.cpu_count = cpu_count;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::ifstream file("/proc/stat");
|
|
|
|
|
|
|
|
std::string line;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!file) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int count = -1;
|
|
|
|
|
|
|
|
while (std::getline(file, line)) {
|
|
|
|
|
|
|
|
// First line is the CPU field that contains all the cores and thread. For now, we skip this one.
|
|
|
|
|
|
|
|
if (count < 0) {
|
|
|
|
|
|
|
|
++count;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parse all the cpus.
|
|
|
|
|
|
|
|
if (line.find("cpu") != std::string::npos) {
|
|
|
|
|
|
|
|
auto tmp = read_cpu_idle_from_line(line);
|
|
|
|
|
|
|
|
auto index = count++;
|
|
|
|
|
|
|
|
if (tmp.idle < last_cpu_thread[index].idle) {
|
|
|
|
|
|
|
|
metrics.cpu_load[index] = 0.f;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
metrics.cpu_load[index] = std::max(
|
|
|
|
|
|
|
|
(1.f - (tmp.idle - last_cpu_thread[index].idle) / (ticks_per_second * delta_time_in_seconds)) * 100.f, 0.f);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
last_cpu_thread[index] = std::move(tmp);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Sets the memory parameters of the given metrics to zero.
|
|
|
|
/// Sets the memory parameters of the given metrics to zero.
|
|
|
@ -104,11 +141,22 @@ static void set_mem_to_zero(sys_metrics_t& metrics)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
metrics.process_realmem_kB = 0;
|
|
|
|
metrics.process_realmem_kB = 0;
|
|
|
|
metrics.process_virtualmem_kB = 0;
|
|
|
|
metrics.process_virtualmem_kB = 0;
|
|
|
|
metrics.process_virtualmem = 0;
|
|
|
|
|
|
|
|
metrics.process_realmem = 0;
|
|
|
|
metrics.process_realmem = 0;
|
|
|
|
metrics.system_mem = 0;
|
|
|
|
metrics.system_mem = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Extracts and returns the memory size from the given line.
|
|
|
|
|
|
|
|
static int32_t read_memory_value_from_line(const std::string& line)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::istringstream reader(line);
|
|
|
|
|
|
|
|
std::string label, unit;
|
|
|
|
|
|
|
|
int32_t value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reader >> label >> value >> unit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void calculate_percentage_memory(sys_metrics_t& metrics)
|
|
|
|
static void calculate_percentage_memory(sys_metrics_t& metrics)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
std::ifstream file("/proc/meminfo");
|
|
|
|
std::ifstream file("/proc/meminfo");
|
|
|
@ -119,19 +167,42 @@ static void calculate_percentage_memory(sys_metrics_t& metrics)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Total system's memory is in the first line.
|
|
|
|
struct meminfo_t {
|
|
|
|
std::getline(file, line);
|
|
|
|
uint32_t total_kB = 0;
|
|
|
|
uint32_t total_mem_kB = read_memory_value_from_line(line);
|
|
|
|
uint32_t free_kB = 0;
|
|
|
|
|
|
|
|
uint32_t buffers_kB = 0;
|
|
|
|
|
|
|
|
uint32_t cached_kB = 0;
|
|
|
|
|
|
|
|
uint32_t slab_kB = 0;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// System's available memory is in the third line.
|
|
|
|
// Retrieve the data
|
|
|
|
std::getline(file, line);
|
|
|
|
meminfo_t m_info;
|
|
|
|
std::getline(file, line);
|
|
|
|
while (std::getline(file, line)) {
|
|
|
|
uint32_t available_mem_kB = read_memory_value_from_line(line);
|
|
|
|
// Looks for Virtual memory.
|
|
|
|
|
|
|
|
if (line.find("MemTotal:") != std::string::npos) {
|
|
|
|
|
|
|
|
m_info.total_kB = std::max(read_memory_value_from_line(line), 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.find("MemFree:") != std::string::npos) {
|
|
|
|
|
|
|
|
m_info.free_kB = std::max(read_memory_value_from_line(line), 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.find("Buffers:") != std::string::npos) {
|
|
|
|
|
|
|
|
m_info.buffers_kB = std::max(read_memory_value_from_line(line), 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.find("Cached:") != std::string::npos) {
|
|
|
|
|
|
|
|
m_info.cached_kB = std::max(read_memory_value_from_line(line), 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.find("Slab:") != std::string::npos) {
|
|
|
|
|
|
|
|
m_info.slab_kB = std::max(read_memory_value_from_line(line), 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Calculate the metrics.
|
|
|
|
// Calculate the metrics.
|
|
|
|
metrics.process_realmem = 100.f * (float(metrics.process_realmem_kB) / total_mem_kB);
|
|
|
|
metrics.process_realmem = (metrics.process_realmem_kB <= m_info.total_kB)
|
|
|
|
metrics.process_virtualmem = 100.f * (float(metrics.process_virtualmem_kB) / total_mem_kB);
|
|
|
|
? 100.f * (float(metrics.process_realmem_kB) / m_info.total_kB)
|
|
|
|
metrics.system_mem = (1.f - float(available_mem_kB) / float(total_mem_kB)) * 100.f;
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
metrics.system_mem =
|
|
|
|
|
|
|
|
(1.f - float(m_info.buffers_kB + m_info.cached_kB + m_info.free_kB + m_info.slab_kB) / float(m_info.total_kB)) *
|
|
|
|
|
|
|
|
100.f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void sys_metrics_processor::calculate_mem_usage(sys_metrics_t& metrics) const
|
|
|
|
void sys_metrics_processor::calculate_mem_usage(sys_metrics_t& metrics) const
|
|
|
@ -147,12 +218,14 @@ void sys_metrics_processor::calculate_mem_usage(sys_metrics_t& metrics) const
|
|
|
|
while (std::getline(file, line)) {
|
|
|
|
while (std::getline(file, line)) {
|
|
|
|
// Looks for Virtual memory.
|
|
|
|
// Looks for Virtual memory.
|
|
|
|
if (line.find("VmSize:") != std::string::npos) {
|
|
|
|
if (line.find("VmSize:") != std::string::npos) {
|
|
|
|
metrics.process_virtualmem_kB = read_memory_value_from_line(line);
|
|
|
|
// NOTE: std::max will clamp negative values to 0.
|
|
|
|
|
|
|
|
metrics.process_virtualmem_kB = std::max(read_memory_value_from_line(line), 0);
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Looks for physical memory.
|
|
|
|
// Looks for physical memory.
|
|
|
|
if (line.find("VmRSS:") != std::string::npos) {
|
|
|
|
if (line.find("VmRSS:") != std::string::npos) {
|
|
|
|
metrics.process_realmem_kB = read_memory_value_from_line(line);
|
|
|
|
// NOTE: std::max will clamp negative values to 0.
|
|
|
|
|
|
|
|
metrics.process_realmem_kB = std::max(read_memory_value_from_line(line), 0);
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|