[metrics] Added the system metrics to the ue stdout

This commit is contained in:
AlaiaL 2021-02-25 12:08:40 +01:00 committed by Andre Puschmann
parent c03dbc6742
commit 3a86c210f9
10 changed files with 299 additions and 10 deletions

View File

@ -0,0 +1,40 @@
/**
* Copyright 2013-2021 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSLTE_SYS_METRICS_H
#define SRSLTE_SYS_METRICS_H
namespace srslte {
/// Metrics that will be returned in the system.
struct sys_metrics_t {
unsigned process_realmem_kB = 0;
unsigned process_virtualmem_kB = 0;
float process_realmem = -1.f;
float process_virtualmem = -1.f;
unsigned thread_count = 0;
float process_cpu_usage = -1.f;
float system_mem = -1.f;
};
} // namespace srslte
#endif // SRSLTE_SYS_METRICS_H

View File

@ -0,0 +1,70 @@
/**
* Copyright 2013-2021 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#ifndef SRSLTE_SYS_METRICS_PROCESSOR_H
#define SRSLTE_SYS_METRICS_PROCESSOR_H
#include "srslte/system/sys_metrics.h"
#include <chrono>
#include <string>
namespace srslte {
/// Process the data from the proc_stats_info.
class sys_metrics_processor
{
/// Contains the information of a process.
struct proc_stats_info {
proc_stats_info();
/// Parsed every field in /proc/[pid]/stats file.
int pid, ppid, pgrp, session, tty_nr, tpgid, exit_signal, processor, exit_code;
unsigned flags, rt_priority, policy;
unsigned long minflt, cminflt, majflt, cmajflt, utime, stime, vsize, rsslim, startcode, endcode, startstack,
kstkesp, kstkeip, signal, blocked, sigignore, sigcatch, wchan, nswap, cnswap, guest_time, start_data, end_data,
start_brk, arg_start, arg_end, env_start, env_end;
int long cutime, cstime, priority, nice, num_threads, itrealvalue, rss, cguest_time;
unsigned long long starttime, delaycct_blkio_ticks;
char state;
std::string comm;
};
public:
/// Performs a new measure and returns the values.
sys_metrics_t get_metrics();
private:
/// Returns the cpu usage in %. current_query is the most recent proc_stats_info, and delta_time_in_seconds is the
/// elapsed time between the last measure and current in seconds.
/// NOTE: Returns -1.0f on error.
float cpu_usage(const proc_stats_info& current_query, float delta_time_in_seconds) const;
/// Returns the memory usage in kB. First element is the real mem whereas the second is the virtual mem.
void mem_usage(sys_metrics_t& metrics) const;
private:
proc_stats_info last_query;
std::chrono::time_point<std::chrono::steady_clock> last_query_time = std::chrono::steady_clock::now();
};
} // namespace srslte
#endif // SRSLTE_SYS_METRICS_PROCESSOR_H

View File

@ -12,4 +12,5 @@ add_subdirectory(mac)
add_subdirectory(phy)
add_subdirectory(radio)
add_subdirectory(srslog)
add_subdirectory(system)
add_subdirectory(upper)

View File

@ -0,0 +1,15 @@
#
# Copyright 2013-2020 Software Radio Systems Limited
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the distribution.
#
set(SOURCES
sys_metrics_processor.cpp)
find_package(Threads REQUIRED)
add_library(system STATIC ${SOURCES})
target_link_libraries(system "${CMAKE_THREAD_LIBS_INIT}")

View File

@ -0,0 +1,147 @@
/**
* Copyright 2013-2021 Software Radio Systems Limited
*
* This file is part of srsLTE.
*
* srsLTE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* srsLTE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* A copy of the GNU Affero General Public License can be found in
* the LICENSE file in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/.
*
*/
#include "srslte/system/sys_metrics_processor.h"
#include "sys/sysinfo.h"
#include <fstream>
#include <sstream>
#include <unistd.h>
using namespace srslte;
sys_metrics_processor::proc_stats_info::proc_stats_info()
{
std::string line;
{
std::ifstream file("/proc/self/stat");
std::getline(file, line);
}
std::istringstream reader(line);
reader >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr >> tpgid >> flags >> minflt >> cminflt >>
majflt >> cmajflt >> utime >> stime >> cutime >> cstime >> priority >> nice >> num_threads >> itrealvalue >>
starttime >> vsize >> rss >> rsslim >> startcode >> endcode >> startstack >> kstkeip >> signal >> blocked >>
sigignore >> sigcatch >> wchan >> nswap >> cnswap >> exit_signal >> processor >> rt_priority >> policy >>
delaycct_blkio_ticks >> guest_time >> cguest_time >> start_data >> end_data >> start_brk >> arg_start >>
arg_end >> env_start >> env_end >> exit_code;
}
sys_metrics_t sys_metrics_processor::get_metrics()
{
auto current_time = std::chrono::steady_clock::now();
unsigned measure_interval_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(current_time - last_query_time).count();
// The time elapsed between 2 measures must be greater that 100 milliseconds.
if (measure_interval_ms < 100u) {
return {};
}
sys_metrics_t metrics;
// Get the memory metrics.
mem_usage(metrics);
// Get the stats from the proc.
proc_stats_info current_query;
metrics.thread_count = current_query.num_threads;
metrics.process_cpu_usage = cpu_usage(current_query, measure_interval_ms / 1000.f);
// Update the last values.
last_query_time = current_time;
last_query = std::move(current_query);
return metrics;
}
float sys_metrics_processor::cpu_usage(const proc_stats_info& current_query, float delta_time_in_seconds) const
{
// Error current value has to be greater than last value.
if (current_query.stime < last_query.stime || current_query.utime < last_query.utime) {
return -1.f;
}
// If current and last tick counter equals, means that the process didn't used CPU.
if (current_query.stime == last_query.stime && current_query.utime == last_query.utime) {
return 0.f;
}
static const unsigned cpu_count = ::sysconf(_SC_NPROCESSORS_CONF);
static const float ticks_per_second = ::sysconf(_SC_CLK_TCK);
printf("delta time is: %f\n", delta_time_in_seconds);
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 unsigned read_memory_value_from_line(const std::string& line)
{
std::istringstream reader(line);
std::string label, unit;
unsigned value;
reader >> label >> value >> unit;
return value;
}
static void calculate_percentage_memory(sys_metrics_t& metrics)
{
std::ifstream file("/proc/meminfo");
std::string line;
// Total system's memory is in the first line.
std::getline(file, line);
unsigned long long total_mem_kB = read_memory_value_from_line(line);
// System's available memory is in the third line.
std::getline(file, line);
std::getline(file, line);
unsigned long long available_mem_kB = read_memory_value_from_line(line);
// 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) / total_mem_kB);
metrics.system_mem = (1.f - float(available_mem_kB) / float(total_mem_kB)) * 100.f;
}
void sys_metrics_processor::mem_usage(sys_metrics_t& metrics) const
{
std::ifstream file("/proc/self/status");
std::string line;
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);
continue;
}
// Looks for physical memory.
if (line.find("VmRSS:") != std::string::npos) {
metrics.process_realmem_kB = read_memory_value_from_line(line);
continue;
}
}
// Now calculate the memory usage in percentage.
calculate_percentage_memory(metrics);
}

View File

@ -28,6 +28,7 @@
#include "srslte/common/log_filter.h"
#include "srslte/radio/radio.h"
#include "srslte/srslog/srslog.h"
#include "srslte/system/sys_metrics_processor.h"
#include "stack/ue_stack_base.h"
#include "ue_metrics_interface.h"
@ -108,6 +109,9 @@ private:
srslte::logger* old_logger = nullptr;
srslog::basic_logger& logger;
// System metrics processor.
srslte::sys_metrics_processor sys_proc;
all_args_t args;
// Helper functions

View File

@ -18,6 +18,7 @@
#include "phy/phy_metrics.h"
#include "srslte/common/metrics_hub.h"
#include "srslte/radio/radio_metrics.h"
#include "srslte/system/sys_metrics.h"
#include "srslte/upper/rlc_metrics.h"
#include "stack/mac/mac_metrics.h"
#include "stack/rrc/rrc_metrics.h"
@ -35,10 +36,11 @@ typedef struct {
} stack_metrics_t;
typedef struct {
srslte::rf_metrics_t rf;
phy_metrics_t phy;
gw_metrics_t gw;
stack_metrics_t stack;
srslte::rf_metrics_t rf;
phy_metrics_t phy;
gw_metrics_t gw;
stack_metrics_t stack;
srslte::sys_metrics_t sys;
} ue_metrics_t;
// UE interface

View File

@ -20,8 +20,8 @@ endif (RPATH)
add_executable(srsue main.cc ue.cc metrics_stdout.cc metrics_csv.cc)
set(SRSUE_SOURCES srsue_phy srsue_stack srsue_upper srsue_mac srsue_rrc srslog)
set(SRSLTE_SOURCES srslte_common srslte_mac srslte_phy srslte_radio srslte_upper rrc_asn1 srslog)
set(SRSUE_SOURCES srsue_phy srsue_stack srsue_upper srsue_mac srsue_rrc srslog system)
set(SRSLTE_SOURCES srslte_common srslte_mac srslte_phy srslte_radio srslte_upper rrc_asn1 srslog system)
set(SRSUE_SOURCES ${SRSUE_SOURCES} srsue_nr_stack srsue_rrc_nr srsue_mac_nr)
set(SRSLTE_SOURCES ${SRSLTE_SOURCES} rrc_nr_asn1 ngap_nr_asn1)

View File

@ -64,13 +64,18 @@ void metrics_stdout::toggle_print(bool b)
void metrics_stdout::print_table(const bool display_neighbours)
{
if (display_neighbours) {
cout << "--------Signal-------------Neighbour--DL-------------------------------------UL----------------------"
cout << "--------Signal-------------Neighbour--DL-------------------------------------UL-----------------------|---"
"--SYS-----"
<< endl;
cout << "cc pci rsrp pl cfo pci rsrp mcs snr turbo brate bler ta_us mcs buff brate bler"
cout << "cc pci rsrp pl cfo pci rsrp mcs snr turbo brate bler ta_us mcs buff brate bler "
"cpu mem"
<< endl;
} else {
cout << "--------Signal--------------DL-------------------------------------UL----------------------" << endl;
cout << "cc pci rsrp pl cfo mcs snr turbo brate bler ta_us mcs buff brate bler" << endl;
cout << "--------Signal--------------DL-------------------------------------UL----------------------|-----SYS----"
"--"
<< endl;
cout << "cc pci rsrp pl cfo mcs snr turbo brate bler ta_us mcs buff brate bler cpu mem"
<< endl;
}
table_has_neighbours = display_neighbours;
n_reports = 0;
@ -162,6 +167,10 @@ void metrics_stdout::set_metrics(const ue_metrics_t& metrics, const uint32_t per
} else {
cout << float_to_string(0, 1) << "%";
}
// Write the system metrics.
cout << float_to_string(metrics.sys.process_cpu_usage, 2);
cout << float_to_string(metrics.sys.system_mem, 2);
cout << endl;
}

View File

@ -328,6 +328,7 @@ bool ue::get_metrics(ue_metrics_t* m)
radio->get_metrics(&m->rf);
stack->get_metrics(&m->stack);
gw_inst->get_metrics(m->gw, m->stack.mac[0].nof_tti);
m->sys = sys_proc.get_metrics();
return true;
}