#include #include #include #include #include #include "log.h" #include "utils.h" enum STAT_FIELD { STAT_RX_PKT, STAT_RX_B, STAT_RX_ERR_PKT, STAT_RX_ERR_B, STAT_SUCC_TX_V4_PKT, STAT_SUCC_TX_V4_B, STAT_SUCC_TX_V6_PKT, STAT_SUCC_TX_V6_B, STAT_ERR_TX_V4_PKT, STAT_ERR_TX_V4_B, STAT_ERR_TX_V6_PKT, STAT_ERR_TX_V6_B, STAT_MAX, }; static const char *stat_map[] = { [STAT_RX_PKT] = "nf_rx_pkt", [STAT_RX_B] = "nf_rx_B", [STAT_RX_ERR_PKT] = "rx_err_pkt", [STAT_RX_ERR_B] = "rx_err_B", [STAT_SUCC_TX_V4_PKT] = "succ_tx_4_pkt", [STAT_SUCC_TX_V4_B] = "succ_tx_4_B", [STAT_SUCC_TX_V6_PKT] = "succ_tx_6_pkt", [STAT_SUCC_TX_V6_B] = "succ_tx_6_B", [STAT_ERR_TX_V4_PKT] = "err_tx_4_pkt", [STAT_ERR_TX_V4_B] = "err_tx_4_B", [STAT_ERR_TX_V6_PKT] = "err_tx_6_pkt", [STAT_ERR_TX_V6_B] = "err_tx_6_B", [STAT_MAX] = NULL}; struct stat_config { char output_file[256]; char statsd_server[32]; int statsd_port; int statsd_format; int statsd_cycle; int prometheus_listen_port; char prometheus_listen_url[256]; }; struct packet_stat { struct stat_config config; screen_stat_handle_t fs_handle; int fs_id[512]; }; static void packet_stat_config(const char *profile, struct stat_config *config) { MESA_load_profile_string_def(profile, "STAT", "output_file", config->output_file, sizeof(config->output_file), "log/packet_adapter.fs2"); MESA_load_profile_string_def(profile, "STAT", "statsd_server", config->statsd_server, sizeof(config->statsd_server), "127.0.0.1"); MESA_load_profile_int_def(profile, "STAT", "statsd_port", &(config->statsd_port), 8100); MESA_load_profile_int_def(profile, "STAT", "statsd_format", &(config->statsd_format), 1); // FS_OUTPUT_STATSD=1, FS_OUTPUT_INFLUX_LINE=2 MESA_load_profile_int_def(profile, "STAT", "statsd_cycle", &(config->statsd_cycle), 1); MESA_load_profile_int_def(profile, "STAT", "prometheus_listen_port", &(config->prometheus_listen_port), 9001); MESA_load_profile_string_def(profile, "STAT", "prometheus_listen_url", config->prometheus_listen_url, sizeof(config->prometheus_listen_url), "/packet_prometheus"); if (config->statsd_format != 1 && config->statsd_format != 2) { config->statsd_format = 1; } LOG_DEBUG("STAT->output_file : %s", config->output_file); LOG_DEBUG("STAT->statsd_server : %s", config->statsd_server); LOG_DEBUG("STAT->statsd_port : %d", config->statsd_port); LOG_DEBUG("STAT->statsd_format : %d", config->statsd_format); LOG_DEBUG("STAT->statsd_cycle : %d", config->statsd_cycle); LOG_DEBUG("STAT->prometheus_listen_port : %d", config->prometheus_listen_port); LOG_DEBUG("STAT->prometheus_listen_url : %s", config->prometheus_listen_url); } struct packet_stat *packet_stat_create(const char *profile) { struct packet_stat *handle = (struct packet_stat *)calloc(1, sizeof(struct packet_stat)); assert(handle != NULL); packet_stat_config(profile, &handle->config); FS_library_set_prometheus_port(handle->config.prometheus_listen_port); FS_library_set_prometheus_url_path(handle->config.prometheus_listen_url); FS_library_init(); int value = 0; handle->fs_handle = FS_create_handle(); // TODO memleak no free() API FS_set_para(handle->fs_handle, APP_NAME, "packet_adapter", 13); FS_set_para(handle->fs_handle, OUTPUT_DEVICE, handle->config.output_file, strlen(handle->config.output_file)); value = 1; FS_set_para(handle->fs_handle, OUTPUT_PROMETHEUS, &value, sizeof(value)); value = 1; FS_set_para(handle->fs_handle, PRINT_MODE, &value, sizeof(value)); value = 0; FS_set_para(handle->fs_handle, CREATE_THREAD, &value, sizeof(value)); if (strlen(handle->config.statsd_server) > 0 && handle->config.statsd_port != 0) { FS_set_para(handle->fs_handle, STATS_SERVER_IP, handle->config.statsd_server, strlen(handle->config.statsd_server)); FS_set_para(handle->fs_handle, STATS_SERVER_PORT, &(handle->config.statsd_port), sizeof(handle->config.statsd_port)); FS_set_para(handle->fs_handle, STATS_FORMAT, &handle->config.statsd_format, sizeof(handle->config.statsd_format)); } for (int i = 0; i < STAT_MAX; i++) { handle->fs_id[i] = FS_register(handle->fs_handle, FS_STYLE_FIELD, FS_CALC_CURRENT, stat_map[i]); } FS_start(handle->fs_handle); return handle; } void packet_stat_destory(struct packet_stat *handle) { if (handle) { FS_library_destroy(); free(handle); handle = NULL; } } void packet_stat_output(struct packet_stat *handle, struct metrics *metrics) { FS_operate(handle->fs_handle, handle->fs_id[STAT_RX_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->rx_pkts))); FS_operate(handle->fs_handle, handle->fs_id[STAT_RX_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->rx_bytes))); FS_operate(handle->fs_handle, handle->fs_id[STAT_RX_ERR_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->rx_err_pkts))); FS_operate(handle->fs_handle, handle->fs_id[STAT_RX_ERR_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->rx_err_bytes))); FS_operate(handle->fs_handle, handle->fs_id[STAT_SUCC_TX_V4_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->succ_tx_v4_pkts))); FS_operate(handle->fs_handle, handle->fs_id[STAT_SUCC_TX_V4_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->succ_tx_v4_bytes))); FS_operate(handle->fs_handle, handle->fs_id[STAT_SUCC_TX_V6_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->succ_tx_v6_pkts))); FS_operate(handle->fs_handle, handle->fs_id[STAT_SUCC_TX_V6_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->succ_tx_v6_bytes))); FS_operate(handle->fs_handle, handle->fs_id[STAT_ERR_TX_V4_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->err_tx_v4_pkts))); FS_operate(handle->fs_handle, handle->fs_id[STAT_ERR_TX_V4_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->err_tx_v4_bytes))); FS_operate(handle->fs_handle, handle->fs_id[STAT_ERR_TX_V6_PKT], 0, FS_OP_SET, ATOMIC_READ(&(metrics->err_tx_v6_pkts))); FS_operate(handle->fs_handle, handle->fs_id[STAT_ERR_TX_V6_B], 0, FS_OP_SET, ATOMIC_READ(&(metrics->err_tx_v6_bytes))); FS_passive_output(handle->fs_handle); } int packet_stat_cycle(struct packet_stat *handle) { if (handle) { return handle->config.statsd_cycle; } else { return 0; } }