/* \brief 状态监测数据输出 * * \author Lu Qiuwen * \date 2016-11-30 */ #include #include #include #include #include #include #include #include "cJSON.h" #include "common.h" extern unsigned int g_monit_interval; static cJSON * __create_uint64_array(const uint64_t * value, int nr_value) { struct cJSON * uint64_array = cJSON_CreateArray(); for (int i = 0; i < nr_value; i++) { cJSON_AddItemToArray(uint64_array, cJSON_CreateNumber(value[i])); } return uint64_array; } static cJSON * __create_uint64_delta_array(const uint64_t * value_large, const uint64_t * value_small, int nr_value, int interval) { struct cJSON * uint64_array = cJSON_CreateArray(); for (int i = 0; i < nr_value; i++) { uint64_t delta = (value_large[i] - value_small[i]) / interval; cJSON_AddItemToArray(uint64_array, cJSON_CreateNumber(delta)); } return uint64_array; } static cJSON * __create_vdev_stats(struct vdev * vdev, unsigned int nr_serv_thread) { struct vdev_stat_info _stat_info; struct vdev_stat_info _stat_info_last; vdev_stats_get(vdev, &_stat_info); vdev_stats_last_get(vdev, &_stat_info_last); vdev_stats_last_save(vdev, &_stat_info); /* 统计节点句柄 */ struct cJSON * j_vdev_stats = cJSON_CreateObject(); /* 累计量 */ struct cJSON * j_vdev_value = cJSON_CreateObject(); /* 瞬时值 */ struct cJSON * j_vdev_speed = cJSON_CreateObject(); #define __JOIN_VDEV_VALUE_STATS_ITEM(item) \ do \ { \ cJSON_AddItemToObject(j_vdev_value, #item, __create_uint64_array(_stat_info.item, nr_serv_thread)); \ } while (0) __JOIN_VDEV_VALUE_STATS_ITEM(rx_on_line); __JOIN_VDEV_VALUE_STATS_ITEM(rx_deliver); __JOIN_VDEV_VALUE_STATS_ITEM(rx_missed); __JOIN_VDEV_VALUE_STATS_ITEM(rx_total_len); __JOIN_VDEV_VALUE_STATS_ITEM(tx_on_line); __JOIN_VDEV_VALUE_STATS_ITEM(tx_deliver); __JOIN_VDEV_VALUE_STATS_ITEM(tx_missed); __JOIN_VDEV_VALUE_STATS_ITEM(tx_total_len); __JOIN_VDEV_VALUE_STATS_ITEM(ftx_on_line); __JOIN_VDEV_VALUE_STATS_ITEM(ftx_deliver); __JOIN_VDEV_VALUE_STATS_ITEM(ftx_missed); __JOIN_VDEV_VALUE_STATS_ITEM(ftx_total_len); __JOIN_VDEV_VALUE_STATS_ITEM(ltx_on_line); __JOIN_VDEV_VALUE_STATS_ITEM(ltx_deliver); __JOIN_VDEV_VALUE_STATS_ITEM(ltx_missed); __JOIN_VDEV_VALUE_STATS_ITEM(ltx_total_len); /* notify events */ #if 0 __JOIN_VDEV_VALUE_STATS_ITEM(notify_state_waiting); __JOIN_VDEV_VALUE_STATS_ITEM(notify_state_running); __JOIN_VDEV_VALUE_STATS_ITEM(notify_state_ready); #endif __JOIN_VDEV_VALUE_STATS_ITEM(batch_size_total); __JOIN_VDEV_VALUE_STATS_ITEM(batch_size_count); #define __JOIN_VDEV_SPEED_STATS_ITEM(item) \ do \ { \ cJSON_AddItemToObject( \ j_vdev_speed, #item, \ __create_uint64_delta_array(_stat_info.item, _stat_info_last.item, nr_serv_thread, g_monit_interval)); \ } while (0) __JOIN_VDEV_SPEED_STATS_ITEM(rx_on_line); __JOIN_VDEV_SPEED_STATS_ITEM(rx_deliver); __JOIN_VDEV_SPEED_STATS_ITEM(rx_missed); __JOIN_VDEV_SPEED_STATS_ITEM(rx_total_len); __JOIN_VDEV_SPEED_STATS_ITEM(tx_on_line); __JOIN_VDEV_SPEED_STATS_ITEM(tx_deliver); __JOIN_VDEV_SPEED_STATS_ITEM(tx_missed); __JOIN_VDEV_SPEED_STATS_ITEM(tx_total_len); __JOIN_VDEV_SPEED_STATS_ITEM(ftx_on_line); __JOIN_VDEV_SPEED_STATS_ITEM(ftx_deliver); __JOIN_VDEV_SPEED_STATS_ITEM(ftx_missed); __JOIN_VDEV_SPEED_STATS_ITEM(ftx_total_len); __JOIN_VDEV_SPEED_STATS_ITEM(ltx_on_line); __JOIN_VDEV_SPEED_STATS_ITEM(ltx_deliver); __JOIN_VDEV_SPEED_STATS_ITEM(ltx_missed); __JOIN_VDEV_SPEED_STATS_ITEM(ltx_total_len); cJSON_AddItemToObject(j_vdev_stats, "accumulative", j_vdev_value); cJSON_AddItemToObject(j_vdev_stats, "speed", j_vdev_speed); return j_vdev_stats; } static cJSON * monit_pkt_latency_global(struct sc_main * sc) { if (sc->en_pkt_latency == 0) { return NULL; } static struct rte_metric_name * metric_names = NULL; static struct rte_metric_value * metric_values = NULL; static unsigned int nr_metrics = 0; if (metric_names == NULL) { nr_metrics = rte_latencystats_get_names(NULL, 0); metric_names = ZMALLOC(sizeof(struct rte_metric_name) * nr_metrics); metric_values = ZMALLOC(sizeof(struct rte_metric_value) * nr_metrics); rte_latencystats_get_names(metric_names, nr_metrics); rte_latencystats_get(metric_values, nr_metrics); } assert(metric_names != NULL); assert(metric_values != NULL); rte_latencystats_update(); /* get the metric value */ cJSON * j_metric = cJSON_CreateObject(); rte_latencystats_get(metric_values, nr_metrics); for (unsigned int i = 0; i < nr_metrics; i++) { struct rte_metric_name * name_iter = &metric_names[i]; struct rte_metric_value * value_iter = &metric_values[i]; cJSON_AddNumberToObject(j_metric, name_iter->name, value_iter->value); } return j_metric; } // 运行时原始报文设备统计计数 static cJSON * monit_vdev(struct sc_main * sc) { struct cJSON * j_raw_device_array = cJSON_CreateArray(); struct vdev * vdev_iter = NULL; unsigned int vdev_next = 0; while (vdev_iterate(sc->vdev_main, &vdev_iter, &vdev_next) >= 0) { cJSON * j_vdev = cJSON_CreateObject(); cJSON_AddStringToObject(j_vdev, "symbol", vdev_iter->symbol); cJSON_AddItemToObject(j_vdev, "stats", __create_vdev_stats(vdev_iter, sc->nr_io_thread)); cJSON_AddItemToArray(j_raw_device_array, j_vdev); } return j_raw_device_array; } // 基础运行参数 static cJSON * monit_service_info(struct sc_main * sc) { struct cJSON * j_service_info = cJSON_CreateObject(); time_t _now_time = time(NULL); cJSON_AddNumberToObject(j_service_info, "unixtime", _now_time); cJSON_AddStringToObject(j_service_info, "g_cfgfile", sc->local_cfgfile); cJSON_AddStringToObject(j_service_info, "g_hwfile", sc->local_hwfile); return j_service_info; } extern cJSON * mrb_monit_loop(struct sc_main * sc); extern cJSON * app_monit_loop(struct sc_main * sc); extern cJSON * malloc_monit_loop(struct sc_main * sc); extern cJSON * service_monit_loop(struct sc_main * sc); extern cJSON * vwire_ingress_node_monit_loop(struct sc_main * sc); extern cJSON * classifier_node_monit_loop(struct sc_main * sc); extern cJSON * forwarder_node_monit_loop(struct sc_main * sc); extern cJSON * vwire_egress_node_monit_loop(struct sc_main * sc); extern cJSON * lb_node_monit_loop(struct sc_main * sc); extern cJSON * ef_ingress_node_monit_loop(struct sc_main * sc); extern cJSON * ef_egress_node_monit_loop(struct sc_main * sc); extern cJSON * eth_ingress_node_monit_loop(struct sc_main * sc); extern cJSON * bridge_node_monit_loop(struct sc_main * sc); extern cJSON * eth_egress_node_monit_loop(struct sc_main * sc); extern cJSON * bfd_node_monit_loop(struct sc_main * sc); extern cJSON * shmdev_tx_node_monit_loop(struct sc_main * sc); extern cJSON * shmdev_rx_node_monit_loop(struct sc_main * sc); extern cJSON * health_check_ask_node_monit_loop(struct sc_main * sc); extern cJSON * health_check_deal_answer_node_monit_loop(struct sc_main * sc); extern cJSON * health_check_session_monit_loop(struct sc_main * sc); extern cJSON * forwarder_table_monit_loop(struct sc_main * sc); extern cJSON * ef_peer_monit_loop(struct sc_main * sc); extern cJSON * olp_manager_monit_loop(struct sc_main * sc); extern cJSON * tera_ingress_node_monit_loop(struct sc_main * sc); extern cJSON * tera_egress_node_monit_loop(struct sc_main * sc); extern cJSON * devmgr_monit_loop(struct sc_main * sc); extern cJSON * dp_trace_monit_loop(struct sc_main * sc); extern cJSON * phydev_rx_node_monit_loop(struct sc_main * sc); extern cJSON * lai_node_monit_loop(struct sc_main * sc); static cJSON * monit_root(struct sc_main * sc) { struct cJSON * j_root = cJSON_CreateObject(); cJSON_AddItemToObject(j_root, "general", monit_service_info(sc)); cJSON_AddItemToObject(j_root, "device", devmgr_monit_loop(sc)); cJSON_AddItemToObject(j_root, "raw", monit_vdev(sc)); cJSON_AddItemToObject(j_root, "mrb", mrb_monit_loop(sc)); #if 0 cJSON_AddItemToObject(j_root, "malloc", malloc_monit_loop(sc)); #endif cJSON_AddItemToObject(j_root, "app", app_monit_loop(sc)); cJSON_AddItemToObject(j_root, "service", service_monit_loop(sc)); cJSON_AddItemToObject(j_root, "pkt_latency", monit_pkt_latency_global(sc)); // cJSON_AddItemToObject(j_root, "offload", smartoffload_monit_loop(sc)); cJSON_AddItemToObject(j_root, "phydev", phydev_rx_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "eth-ingress", eth_ingress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "bridge", bridge_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "vwire-ingress", vwire_ingress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "ef-ingress", ef_ingress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "tera-ingress", tera_ingress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "bfd", bfd_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "classifier", classifier_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "forwarder", forwarder_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "link-aware-injector", lai_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "vwire-egress", vwire_egress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "lb", lb_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "ef-egress", ef_egress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "tera-egress", tera_egress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "shmdev_tx", shmdev_tx_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "shmdev_rx", shmdev_rx_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "eth-egress", eth_egress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "health-check-ask", health_check_ask_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "health-check-deal-answer", health_check_deal_answer_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "health-session-state", health_check_session_monit_loop(sc)); cJSON_AddItemToObject(j_root, "forwarder-table", forwarder_table_monit_loop(sc)); cJSON_AddItemToObject(j_root, "ef-peer-table", ef_peer_monit_loop(sc)); cJSON_AddItemToObject(j_root, "OBP", olp_manager_monit_loop(sc)); cJSON_AddItemToObject(j_root, "dp-trace-path", dp_trace_monit_loop(sc)); return j_root; } int sc_monit_loop(struct sc_main * sc) { cJSON * j_root = monit_root(sc); char * str_json_print = cJSON_Print(j_root); FILE * fp_monit = fopen(sc->local_monitfile, "w"); if (fp_monit == NULL) { MR_WARNING("monit file %s open failed, cannot dump program stat info : %s", sc->local_monitfile, strerror(errno)); return 0; } fprintf(fp_monit, "%s", str_json_print); fclose(fp_monit); free(str_json_print); cJSON_Delete(j_root); return 0; }