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 {
|
struct sys_metrics_t {
|
||||||
uint32_t process_realmem_kB = 0;
|
uint32_t process_realmem_kB = 0;
|
||||||
uint32_t process_virtualmem_kB = 0;
|
uint32_t process_virtualmem_kB = 0;
|
||||||
float process_realmem = -1.f;
|
float process_realmem = 0.f;
|
||||||
float process_virtualmem = -1.f;
|
|
||||||
uint32_t thread_count = 0;
|
uint32_t thread_count = 0;
|
||||||
float process_cpu_usage = -1.f;
|
float process_cpu_usage = 0.f;
|
||||||
float system_mem = -1.f;
|
float system_mem = 0.f;
|
||||||
|
uint32_t cpu_count = 0;
|
||||||
|
float cpu_load[128];
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace srsran
|
} // namespace srsran
|
||||||
|
|
|
@ -42,6 +42,18 @@ class sys_metrics_processor
|
||||||
std::string comm;
|
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:
|
public:
|
||||||
/// Measures and returns the system metrics.
|
/// Measures and returns the system metrics.
|
||||||
sys_metrics_t get_metrics();
|
sys_metrics_t get_metrics();
|
||||||
|
@ -56,8 +68,16 @@ private:
|
||||||
/// NOTE: on error, metrics memory parameters are set to 0.
|
/// NOTE: on error, metrics memory parameters are set to 0.
|
||||||
void calculate_mem_usage(sys_metrics_t& metrics) const;
|
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:
|
private:
|
||||||
proc_stats_info last_query = {};
|
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();
|
std::chrono::time_point<std::chrono::steady_clock> last_query_time = std::chrono::steady_clock::now();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 (file.is_open() && enb != NULL) {
|
||||||
if (n_reports == 0) {
|
if (n_reports == 0) {
|
||||||
file << "time;nof_ue;dl_brate;ul_brate;"
|
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
|
// 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;
|
const srsran::sys_metrics_t& m = metrics.sys;
|
||||||
file << float_to_string(m.process_realmem, 2);
|
file << float_to_string(m.process_realmem, 2);
|
||||||
file << std::to_string(m.process_realmem_kB) << ";";
|
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 << std::to_string(m.process_virtualmem_kB) << ";";
|
||||||
file << float_to_string(m.system_mem, 2);
|
file << float_to_string(m.system_mem, 2);
|
||||||
file << float_to_string(m.process_cpu_usage, 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";
|
file << "\n";
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,15 @@ void metrics_csv::set_metrics(const ue_metrics_t& metrics, const uint32_t period
|
||||||
"bler;"
|
"bler;"
|
||||||
"rf_o;rf_"
|
"rf_o;rf_"
|
||||||
"u;rf_l;is_attached;"
|
"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++) {
|
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;
|
const srsran::sys_metrics_t& m = metrics.sys;
|
||||||
file << float_to_string(m.process_realmem, 2);
|
file << float_to_string(m.process_realmem, 2);
|
||||||
file << std::to_string(m.process_realmem_kB) << ";";
|
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 << std::to_string(m.process_virtualmem_kB) << ";";
|
||||||
file << float_to_string(m.system_mem, 2);
|
file << float_to_string(m.system_mem, 2);
|
||||||
file << float_to_string(m.process_cpu_usage, 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";
|
file << "\n";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue