mirror of https://github.com/PentHertz/srsLTE.git
Added the cpu metrics to the system metrics.
This commit is contained in:
parent
14bfd55fb9
commit
6cd9bba641
|
@ -21,11 +21,12 @@ namespace srsran {
|
|||
struct sys_metrics_t {
|
||||
uint32_t process_realmem_kB = 0;
|
||||
uint32_t process_virtualmem_kB = 0;
|
||||
float process_realmem = -1.f;
|
||||
float process_virtualmem = -1.f;
|
||||
float process_realmem = 0.f;
|
||||
uint32_t thread_count = 0;
|
||||
float process_cpu_usage = -1.f;
|
||||
float system_mem = -1.f;
|
||||
float process_cpu_usage = 0.f;
|
||||
float system_mem = 0.f;
|
||||
uint32_t cpu_count = 0;
|
||||
float cpu_load[128];
|
||||
};
|
||||
|
||||
} // namespace srsran
|
||||
|
|
|
@ -42,6 +42,18 @@ class sys_metrics_processor
|
|||
std::string comm;
|
||||
};
|
||||
|
||||
/// Helper class to read the cpu metrics.
|
||||
struct cpu_metrics_t {
|
||||
std::string name = "";
|
||||
int32_t user = 0;
|
||||
int32_t nice = 0;
|
||||
int32_t system = 0;
|
||||
int32_t idle = 0;
|
||||
int32_t iowait = 0;
|
||||
int32_t irq = 0;
|
||||
int32_t softirq = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
/// Measures and returns the system metrics.
|
||||
sys_metrics_t get_metrics();
|
||||
|
@ -56,8 +68,16 @@ private:
|
|||
/// NOTE: on error, metrics memory parameters are set to 0.
|
||||
void calculate_mem_usage(sys_metrics_t& metrics) const;
|
||||
|
||||
/// Calculate the cpu metrics and stores them in the given metrics. delta_time_in_seconds is the number of seconds
|
||||
/// elapsed since the last cpu metrics measurement.
|
||||
void calculate_cpu_metrics(sys_metrics_t& metrics, float delta_time_in_seconds);
|
||||
|
||||
/// Returns the cpu metrics from the given line.
|
||||
cpu_metrics_t read_cpu_idle_from_line(const std::string& line) const;
|
||||
|
||||
private:
|
||||
proc_stats_info last_query = {};
|
||||
cpu_metrics_t last_cpu_thread[128] = {};
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_query_time = std::chrono::steady_clock::now();
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
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()
|
||||
{
|
||||
std::string line;
|
||||
|
@ -55,6 +58,9 @@ sys_metrics_t sys_metrics_processor::get_metrics()
|
|||
// Get the memory metrics.
|
||||
calculate_mem_usage(metrics);
|
||||
|
||||
// Calculate cpu metrics.
|
||||
calculate_cpu_metrics(metrics, measure_interval_ms / 1000.f);
|
||||
|
||||
// Get the stats from the proc.
|
||||
proc_stats_info current_query;
|
||||
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;
|
||||
}
|
||||
|
||||
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 /
|
||||
(cpu_count * ticks_per_second * delta_time_in_seconds);
|
||||
}
|
||||
|
||||
/// Extracts and returns the memory size from the given line.
|
||||
static uint32_t read_memory_value_from_line(const std::string& line)
|
||||
sys_metrics_processor::cpu_metrics_t sys_metrics_processor::read_cpu_idle_from_line(const std::string& line) const
|
||||
{
|
||||
std::istringstream reader(line);
|
||||
std::string label, unit;
|
||||
uint32_t value;
|
||||
cpu_metrics_t m;
|
||||
|
||||
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.
|
||||
|
@ -104,11 +141,22 @@ static void set_mem_to_zero(sys_metrics_t& metrics)
|
|||
{
|
||||
metrics.process_realmem_kB = 0;
|
||||
metrics.process_virtualmem_kB = 0;
|
||||
metrics.process_virtualmem = 0;
|
||||
metrics.process_realmem = 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)
|
||||
{
|
||||
std::ifstream file("/proc/meminfo");
|
||||
|
@ -119,19 +167,42 @@ static void calculate_percentage_memory(sys_metrics_t& metrics)
|
|||
return;
|
||||
}
|
||||
|
||||
// Total system's memory is in the first line.
|
||||
std::getline(file, line);
|
||||
uint32_t total_mem_kB = read_memory_value_from_line(line);
|
||||
struct meminfo_t {
|
||||
uint32_t total_kB = 0;
|
||||
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.
|
||||
std::getline(file, line);
|
||||
std::getline(file, line);
|
||||
uint32_t available_mem_kB = read_memory_value_from_line(line);
|
||||
// Retrieve the data
|
||||
meminfo_t m_info;
|
||||
while (std::getline(file, 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.
|
||||
metrics.process_realmem = 100.f * (float(metrics.process_realmem_kB) / total_mem_kB);
|
||||
metrics.process_virtualmem = 100.f * (float(metrics.process_virtualmem_kB) / total_mem_kB);
|
||||
metrics.system_mem = (1.f - float(available_mem_kB) / float(total_mem_kB)) * 100.f;
|
||||
metrics.process_realmem = (metrics.process_realmem_kB <= m_info.total_kB)
|
||||
? 100.f * (float(metrics.process_realmem_kB) / m_info.total_kB)
|
||||
: 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
|
||||
|
@ -147,12 +218,14 @@ void sys_metrics_processor::calculate_mem_usage(sys_metrics_t& metrics) const
|
|||
while (std::getline(file, line)) {
|
||||
// Looks for Virtual memory.
|
||||
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;
|
||||
}
|
||||
// Looks for physical memory.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,15 @@ void metrics_csv::set_metrics(const enb_metrics_t& metrics, const uint32_t perio
|
|||
if (file.is_open() && enb != NULL) {
|
||||
if (n_reports == 0) {
|
||||
file << "time;nof_ue;dl_brate;ul_brate;"
|
||||
"proc_rmem;proc_rmem_kB;proc_vmem;proc_vmem_kB;sys_mem;proc_cpu;thread_count\n";
|
||||
"proc_rmem;proc_rmem_kB;proc_vmem_kB;sys_mem;system_load;thread_count";
|
||||
|
||||
// Add the cores.
|
||||
for (uint32_t i = 0, e = ::sysconf(_SC_NPROCESSORS_CONF); i != e; ++i) {
|
||||
file << ";cpu_" << std::to_string(i);
|
||||
}
|
||||
|
||||
// Add the new line.
|
||||
file << "\n";
|
||||
}
|
||||
|
||||
// Time
|
||||
|
@ -90,11 +98,15 @@ void metrics_csv::set_metrics(const enb_metrics_t& metrics, const uint32_t perio
|
|||
const srsran::sys_metrics_t& m = metrics.sys;
|
||||
file << float_to_string(m.process_realmem, 2);
|
||||
file << std::to_string(m.process_realmem_kB) << ";";
|
||||
file << float_to_string(m.process_virtualmem, 2);
|
||||
file << std::to_string(m.process_virtualmem_kB) << ";";
|
||||
file << float_to_string(m.system_mem, 2);
|
||||
file << float_to_string(m.process_cpu_usage, 2);
|
||||
file << std::to_string(m.thread_count);
|
||||
file << std::to_string(m.thread_count) << ";";
|
||||
|
||||
// Write the cpu metrics.
|
||||
for (uint32_t i = 0, e = m.cpu_count, last_cpu_index = e - 1; i != e; ++i) {
|
||||
file << float_to_string(m.cpu_load[i], 2, (i != last_cpu_index));
|
||||
}
|
||||
|
||||
file << "\n";
|
||||
|
||||
|
|
|
@ -78,7 +78,15 @@ void metrics_csv::set_metrics(const ue_metrics_t& metrics, const uint32_t period
|
|||
"bler;"
|
||||
"rf_o;rf_"
|
||||
"u;rf_l;is_attached;"
|
||||
"proc_rmem;proc_rmem_kB;proc_vmem;proc_vmem_kB;sys_mem;proc_cpu;thread_count\n";
|
||||
"proc_rmem;proc_rmem_kB;proc_vmem_kB;sys_mem;sys_load;thread_count";
|
||||
|
||||
// Add the cores.
|
||||
for (uint32_t i = 0, e = ::sysconf(_SC_NPROCESSORS_CONF); i != e; ++i) {
|
||||
file << ";cpu_" << std::to_string(i);
|
||||
}
|
||||
|
||||
// Add the new line.
|
||||
file << "\n";
|
||||
}
|
||||
|
||||
for (uint32_t r = 0; r < metrics.phy.nof_active_cc; r++) {
|
||||
|
@ -159,11 +167,15 @@ void metrics_csv::set_metrics(const ue_metrics_t& metrics, const uint32_t period
|
|||
const srsran::sys_metrics_t& m = metrics.sys;
|
||||
file << float_to_string(m.process_realmem, 2);
|
||||
file << std::to_string(m.process_realmem_kB) << ";";
|
||||
file << float_to_string(m.process_virtualmem, 2);
|
||||
file << std::to_string(m.process_virtualmem_kB) << ";";
|
||||
file << float_to_string(m.system_mem, 2);
|
||||
file << float_to_string(m.process_cpu_usage, 2);
|
||||
file << std::to_string(m.thread_count);
|
||||
file << std::to_string(m.thread_count) << ";";
|
||||
|
||||
// Write the cpu metrics.
|
||||
for (uint32_t i = 0, e = m.cpu_count, last_cpu_index = e - 1; i != e; ++i) {
|
||||
file << float_to_string(m.cpu_load[i], 2, (i != last_cpu_index));
|
||||
}
|
||||
|
||||
file << "\n";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue