/** * * \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 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); /// 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); /// 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); 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; } // 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(tp).count() * 1e-3; } void metrics_json::set_metrics(const ue_metrics_t& metrics, const uint32_t period_usec) { std::lock_guard lock(mutex); if (!ue) { return; } metric_context_t ctx("JSON Metrics"); // Fill root object. ctx.write("metrics"); // Fill cc container. auto& carrier_list = ctx.get(); 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(metrics.phy.info[i].dl_earfcn); carrier.write(metrics.phy.info[i].pci); carrier.write(metrics.phy.ch[i].rsrp); carrier.write(metrics.phy.ch[i].pathloss); carrier.write(metrics.phy.sync[i].cfo); carrier.write(metrics.phy.ch[i].sinr); carrier.write(metrics.phy.dl[i].mcs); carrier.write(metrics.phy.ul[i].mcs); carrier.write(metrics.phy.sync[i].ta_us); carrier.write(metrics.phy.sync[i].distance_km); carrier.write(metrics.phy.sync[i].speed_kmph); // MAC carrier.get().write(metrics.stack.mac[i].rx_brate / metrics.stack.mac[i].nof_tti * 1e-3); carrier.get().write( (metrics.stack.mac[i].rx_pkts > 0) ? (float)100 * metrics.stack.mac[i].rx_errors / metrics.stack.mac[i].rx_pkts : 0); carrier.get().write(metrics.stack.mac[i].tx_brate / metrics.stack.mac[i].nof_tti * 1e-3); carrier.get().write( (metrics.stack.mac[i].tx_pkts > 0) ? (float)100 * metrics.stack.mac[i].tx_errors / metrics.stack.mac[i].tx_pkts : 0); carrier.get().write(metrics.stack.mac[i].ul_buffer); } // Fill GW container. ctx.get().write(metrics.gw.dl_tput_mbps); ctx.get().write(metrics.gw.ul_tput_mbps); // Fill RRC container. ctx.get().write(rrc_state_text[metrics.stack.rrc.state]); // Fill neighbour list. auto& neighbour_list = ctx.get(); 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(metrics.stack.rrc.neighbour_cells[i].pci); neigbour.write(metrics.stack.rrc.neighbour_cells[i].rsrp); neigbour.write(metrics.stack.rrc.neighbour_cells[i].cfo_hz); } // Fill NAS container. ctx.get().write(emm_state_text(metrics.stack.nas.state)); // Fill RF container. ctx.get().write(metrics.rf.rf_o); ctx.get().write(metrics.rf.rf_u); ctx.get().write(metrics.rf.rf_l); // Fill system memory container. ctx.get().write(metrics.sys.process_realmem); ctx.get().write(metrics.sys.process_realmem_kB); ctx.get().write(metrics.sys.process_virtualmem_kB); ctx.get().write(metrics.sys.system_mem); // Fill system CPU container. ctx.get().write(metrics.sys.process_cpu_usage); ctx.get().write(metrics.sys.thread_count); auto& core_list = ctx.get().get(); core_list.resize(metrics.sys.cpu_count); for (uint32_t i = 0, e = core_list.size(); i != e; ++i) { core_list[i].write(metrics.sys.cpu_load[i]); } // Log the context. ctx.write(get_time_stamp()); log_c(ctx); }