srsLTE/srsue/src/metrics_json.cc

236 lines
9.7 KiB
C++

/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 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.
*
*/
#include "srsue/hdr/metrics_json.h"
#include "srsran/srslog/context.h"
using namespace srsue;
void metrics_json::set_ue_handle(ue_metrics_interface* ue_)
{
std::lock_guard<std::mutex> lock(mutex);
ue = ue_;
}
namespace {
/// Shared metrics between containers.
DECLARE_METRIC("pci", metric_pci, uint32_t, "");
DECLARE_METRIC("dl_bitrate", metric_dl_brate, float, "");
DECLARE_METRIC("ul_bitrate", metric_ul_brate, float, "");
DECLARE_METRIC("rsrp", metric_rsrp, float, "");
/// MAC container.
DECLARE_METRIC("dl_bler", metric_dl_bler, float, "");
DECLARE_METRIC("ul_bler", metric_ul_bler, float, "");
DECLARE_METRIC("ul_buff", metric_ul_buff, uint32_t, "");
DECLARE_METRIC_SET("mac_container",
mset_mac_container,
metric_dl_brate,
metric_dl_bler,
metric_ul_brate,
metric_ul_bler,
metric_ul_buff);
/// Carrier container.
DECLARE_METRIC("earfcn", metric_earfcn, uint32_t, "");
DECLARE_METRIC("pathloss", metric_pathloss, float, "");
DECLARE_METRIC("cfo", metric_cfo, float, "");
DECLARE_METRIC("dl_snr", metric_dl_snr, float, "");
DECLARE_METRIC("dl_mcs", metric_dl_mcs, float, "");
DECLARE_METRIC("ul_mcs", metric_ul_mcs, float, "");
DECLARE_METRIC("ul_ta", metric_ul_ta, float, "");
DECLARE_METRIC("distance_km", metric_distance_km, float, "");
DECLARE_METRIC("speed_kmph", metric_speed_kmph, float, "");
DECLARE_METRIC_SET("carrier_container",
mset_carrier_container,
metric_earfcn,
metric_pci,
metric_rsrp,
metric_pathloss,
metric_cfo,
metric_dl_snr,
metric_dl_mcs,
metric_ul_mcs,
metric_ul_ta,
metric_distance_km,
metric_speed_kmph,
mset_mac_container);
DECLARE_METRIC_LIST("carrier_list", mlist_carriers, std::vector<mset_carrier_container>);
/// GW container.
DECLARE_METRIC_SET("gw_container", mset_gw_container, metric_dl_brate, metric_ul_brate);
/// RRC container.
DECLARE_METRIC("rrc_state", metric_rrc_state, std::string, "");
DECLARE_METRIC_SET("rrc_container", mset_rrc_container, metric_rrc_state);
/// Neighbour cell list.
DECLARE_METRIC_SET("neighbour_cell_container", mset_neighbour_cell_container, metric_pci, metric_rsrp, metric_cfo);
DECLARE_METRIC_LIST("neighbour_cell_list", mlist_neighbours, std::vector<mset_neighbour_cell_container>);
/// NAS container.
DECLARE_METRIC("emm_state", metric_emm_state, std::string, "");
DECLARE_METRIC_SET("nas_container", mset_nas_container, metric_emm_state);
/// RF container.
DECLARE_METRIC("rf_o", metric_rf_o, uint32_t, "");
DECLARE_METRIC("rf_u", metric_rf_u, uint32_t, "");
DECLARE_METRIC("rf_l", metric_rf_l, uint32_t, "");
DECLARE_METRIC_SET("rf_container", mset_rf_container, metric_rf_o, metric_rf_u, metric_rf_l);
/// System memory container.
DECLARE_METRIC("proc_realmem_percent", metric_proc_rmem_percent, uint32_t, "");
DECLARE_METRIC("proc_realmem_kB", metric_proc_rmem_kB, uint32_t, "");
DECLARE_METRIC("proc_vmem_kB", metric_proc_vmem_kB, uint32_t, "");
DECLARE_METRIC("sys_mem_usage_percent", metric_sys_mem_percent, uint32_t, "");
DECLARE_METRIC_SET("sys_memory_container",
mset_sys_mem_container,
metric_proc_rmem_percent,
metric_proc_rmem_kB,
metric_proc_vmem_kB,
metric_sys_mem_percent);
/// System CPU container
DECLARE_METRIC("proc_cpu_usage", metric_proc_cpu_usage, uint32_t, "");
DECLARE_METRIC("proc_thread_count", metric_thread_count, uint32_t, "");
DECLARE_METRIC("sys_core_usage", metric_proc_core_usage, uint32_t, "");
DECLARE_METRIC_SET("cpu_core_container", mset_cpu_core_container, metric_proc_core_usage);
DECLARE_METRIC_LIST("cpu_core_list", mlist_cpu_core_list, std::vector<mset_cpu_core_container>);
DECLARE_METRIC_SET("sys_cpu_container",
mset_sys_cpu_container,
metric_proc_cpu_usage,
metric_thread_count,
mlist_cpu_core_list);
/// Metrics root object.
DECLARE_METRIC("type", metric_type_tag, std::string, "");
DECLARE_METRIC("timestamp", metric_timestamp_tag, double, "");
/// Metrics context.
using metric_context_t = srslog::build_context_type<metric_type_tag,
metric_timestamp_tag,
mlist_carriers,
mset_gw_container,
mset_rrc_container,
mlist_neighbours,
mset_nas_container,
mset_rf_container,
mset_sys_mem_container,
mset_sys_cpu_container>;
} // namespace
/// Returns the current time in seconds with ms precision since UNIX epoch.
static double get_time_stamp()
{
auto tp = std::chrono::system_clock::now().time_since_epoch();
return std::chrono::duration_cast<std::chrono::milliseconds>(tp).count() * 1e-3;
}
void metrics_json::set_metrics(const ue_metrics_t& metrics, const uint32_t period_usec)
{
std::lock_guard<std::mutex> lock(mutex);
if (!ue) {
return;
}
metric_context_t ctx("JSON Metrics");
// Fill root object.
ctx.write<metric_type_tag>("metrics");
// Fill cc container.
auto& carrier_list = ctx.get<mlist_carriers>();
carrier_list.resize(metrics.phy.nof_active_cc);
for (uint32_t i = 0, e = carrier_list.size(); i != e; ++i) {
if (metrics.stack.mac[i].nof_tti == 0) {
continue;
}
auto& carrier = carrier_list[i];
// PHY.
carrier.write<metric_earfcn>(metrics.phy.info[i].dl_earfcn);
carrier.write<metric_pci>(metrics.phy.info[i].pci);
carrier.write<metric_rsrp>(metrics.phy.ch[i].rsrp);
carrier.write<metric_pathloss>(metrics.phy.ch[i].pathloss);
carrier.write<metric_cfo>(metrics.phy.sync[i].cfo);
carrier.write<metric_dl_snr>(metrics.phy.ch[i].sinr);
carrier.write<metric_dl_mcs>(metrics.phy.dl[i].mcs);
carrier.write<metric_ul_mcs>(metrics.phy.ul[i].mcs);
carrier.write<metric_ul_ta>(metrics.phy.sync[i].ta_us);
carrier.write<metric_distance_km>(metrics.phy.sync[i].distance_km);
carrier.write<metric_speed_kmph>(metrics.phy.sync[i].speed_kmph);
// MAC
carrier.get<mset_mac_container>().write<metric_dl_brate>(metrics.stack.mac[i].rx_brate /
metrics.stack.mac[i].nof_tti * 1e-3);
carrier.get<mset_mac_container>().write<metric_dl_bler>(
(metrics.stack.mac[i].rx_pkts > 0) ? (float)100 * metrics.stack.mac[i].rx_errors / metrics.stack.mac[i].rx_pkts
: 0);
carrier.get<mset_mac_container>().write<metric_ul_brate>(metrics.stack.mac[i].tx_brate /
metrics.stack.mac[i].nof_tti * 1e-3);
carrier.get<mset_mac_container>().write<metric_ul_bler>(
(metrics.stack.mac[i].tx_pkts > 0) ? (float)100 * metrics.stack.mac[i].tx_errors / metrics.stack.mac[i].tx_pkts
: 0);
carrier.get<mset_mac_container>().write<metric_ul_buff>(metrics.stack.mac[i].ul_buffer);
}
// Fill GW container.
ctx.get<mset_gw_container>().write<metric_dl_brate>(metrics.gw.dl_tput_mbps);
ctx.get<mset_gw_container>().write<metric_ul_brate>(metrics.gw.ul_tput_mbps);
// Fill RRC container.
ctx.get<mset_rrc_container>().write<metric_rrc_state>(rrc_state_text[metrics.stack.rrc.state]);
// Fill neighbour list.
auto& neighbour_list = ctx.get<mlist_neighbours>();
neighbour_list.resize(metrics.stack.rrc.neighbour_cells.size());
for (uint32_t i = 0, e = neighbour_list.size(); i != e; ++i) {
auto& neigbour = neighbour_list[i];
neigbour.write<metric_pci>(metrics.stack.rrc.neighbour_cells[i].pci);
neigbour.write<metric_rsrp>(metrics.stack.rrc.neighbour_cells[i].rsrp);
neigbour.write<metric_cfo>(metrics.stack.rrc.neighbour_cells[i].cfo_hz);
}
// Fill NAS container.
ctx.get<mset_nas_container>().write<metric_emm_state>(emm_state_text(metrics.stack.nas.state));
// Fill RF container.
ctx.get<mset_rf_container>().write<metric_rf_o>(metrics.rf.rf_o);
ctx.get<mset_rf_container>().write<metric_rf_u>(metrics.rf.rf_u);
ctx.get<mset_rf_container>().write<metric_rf_l>(metrics.rf.rf_l);
// Fill system memory container.
ctx.get<mset_sys_mem_container>().write<metric_proc_rmem_percent>(metrics.sys.process_realmem);
ctx.get<mset_sys_mem_container>().write<metric_proc_rmem_kB>(metrics.sys.process_realmem_kB);
ctx.get<mset_sys_mem_container>().write<metric_proc_vmem_kB>(metrics.sys.process_virtualmem_kB);
ctx.get<mset_sys_mem_container>().write<metric_sys_mem_percent>(metrics.sys.system_mem);
// Fill system CPU container.
ctx.get<mset_sys_cpu_container>().write<metric_proc_cpu_usage>(metrics.sys.process_cpu_usage);
ctx.get<mset_sys_cpu_container>().write<metric_thread_count>(metrics.sys.thread_count);
auto& core_list = ctx.get<mset_sys_cpu_container>().get<mlist_cpu_core_list>();
core_list.resize(metrics.sys.cpu_count);
for (uint32_t i = 0, e = core_list.size(); i != e; ++i) {
core_list[i].write<metric_proc_core_usage>(metrics.sys.cpu_load[i]);
}
// Log the context.
ctx.write<metric_timestamp_tag>(get_time_stamp());
log_c(ctx);
}