diff options
| -rw-r--r-- | ctest/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | src/fieldstat.cpp | 27 | ||||
| -rw-r--r-- | src/fieldstat_dynamic.cpp | 6 | ||||
| -rw-r--r-- | src/fieldstat_internal.h | 6 | ||||
| -rw-r--r-- | src/file_output.cpp | 16 | ||||
| -rw-r--r-- | src/line_protocol_output.cpp | 30 | ||||
| -rw-r--r-- | src/prometheus_output.cpp | 9 | ||||
| -rw-r--r-- | test/src/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | test/src/gtest_dynamic_fieldstat_output.cpp | 126 | ||||
| -rw-r--r-- | test/src/gtest_fieldstat_interface.cpp (renamed from test/src/gtest_fieldstat.cpp) | 1 | ||||
| -rw-r--r-- | test/src/gtest_fieldstat_output.cpp | 694 |
11 files changed, 893 insertions, 39 deletions
diff --git a/ctest/CMakeLists.txt b/ctest/CMakeLists.txt index d9a7c17..c25ad35 100644 --- a/ctest/CMakeLists.txt +++ b/ctest/CMakeLists.txt @@ -4,11 +4,15 @@ project(fieldstat_ctest) add_test(NAME COPY_CREATE_DIR COMMAND sh -c "mkdir -p ${CMAKE_BINARY_DIR}/testing/ ") -add_test(NAME COPY_GTEST_BINARY COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/src/gtest_fieldstat ${CMAKE_BINARY_DIR}/testing/") +add_test(NAME COPY_GTEST_INTERFACE_BINARY COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/src/gtest_fieldstat_interface ${CMAKE_BINARY_DIR}/testing/") +add_test(NAME COPY_GTEST_OUTPUT_BINARY COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/src/gtest_fieldstat_output ${CMAKE_BINARY_DIR}/testing/") add_test(NAME COPY_GTEST_DYNAMIC_BINARY COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/src/gtest_dynamic_fieldstat ${CMAKE_BINARY_DIR}/testing/") +add_test(NAME COPY_GTEST_DYNAMIC_OUTPUT_BINARY COMMAND sh -c "cp ${CMAKE_BINARY_DIR}/test/src/gtest_dynamic_fieldstat_output ${CMAKE_BINARY_DIR}/testing/") set(GTEST_RUN_DIR ${CMAKE_BINARY_DIR}/testing) #add_test(NAME GTEST_RULE COMMAND gtest_rule WORKING_DIRECTORY ${GTEST_RUN_DIR}) -add_test(NAME GTEST_FIELDSTAT COMMAND gtest_fieldstat WORKING_DIRECTORY ${GTEST_RUN_DIR}) +add_test(NAME GTEST_FIELDSTAT_INTERFACE COMMAND gtest_fieldstat_interface WORKING_DIRECTORY ${GTEST_RUN_DIR}) +add_test(NAME GTEST_FIELDSTAT_OUTPUT COMMAND gtest_fieldstat_output WORKING_DIRECTORY ${GTEST_RUN_DIR}) add_test(NAME GTEST_DYNAMIC_FIELDSTAT COMMAND gtest_dynamic_fieldstat WORKING_DIRECTORY ${GTEST_RUN_DIR}) +add_test(NAME GTEST_DYNAMIC_FIELDSTAT_OUTPUT COMMAND gtest_dynamic_fieldstat_output WORKING_DIRECTORY ${GTEST_RUN_DIR}) diff --git a/src/fieldstat.cpp b/src/fieldstat.cpp index 0ad0e67..6014600 100644 --- a/src/fieldstat.cpp +++ b/src/fieldstat.cpp @@ -344,6 +344,7 @@ int fieldstat_set_local_output(struct fieldstat_instance *instance, const char * strncpy(instance->local_output_filename, (char *)filename, len_filename); strncpy(instance->local_output_format, (char *)format, len_format); instance->local_output_enable = 1; + instance->output_type |= 8; return 0; } @@ -360,6 +361,7 @@ int fieldstat_set_line_protocol_server(struct fieldstat_instance *instance, cons if(ret == 0) { instance->line_protocol_output_enable = 1; + instance->output_type |= 4; } return ret; @@ -379,6 +381,7 @@ int fieldstat_set_statsd_server(struct fieldstat_instance *instance, const char instance->statsd_server_port = port; instance->statsd_output_enable = 1; + instance->output_type |= 2; return 0; } @@ -460,6 +463,28 @@ long long get_metric_unit_val(struct metric *metric,enum field_calc_algo calc_ty return value; } +long long read_metric_current_value(struct metric *metric) +{ + stat_unit_t* target = NULL; + long long value = 0; + switch(metric->field_type) + { + case FIELD_TYPE_COUNTER: + target = &(metric->counter); + break; + case FIELD_TYPE_GAUGE: + target = &(metric->gauge); + break; + default: + break; + } + + value = threadsafe_counter_read(&(target->changing)); + value += target->accumulated; + + return value; +} + long long hdr_count_le_value(const struct hdr_histogram* h, long long value) { struct hdr_iter iter; @@ -494,7 +519,7 @@ void fieldstat_passive_output(struct fieldstat_instance *instance) if(instance->local_output_enable) { - ret = fieldstat_output_file(instance, interval_ms); + ret = file_output(instance, interval_ms); } if(instance->line_protocol_output_enable) { diff --git a/src/fieldstat_dynamic.cpp b/src/fieldstat_dynamic.cpp index 5a0609e..c10dc56 100644 --- a/src/fieldstat_dynamic.cpp +++ b/src/fieldstat_dynamic.cpp @@ -111,6 +111,7 @@ int fieldstat_dynamic_set_line_protocol_server(struct fieldstat_dynamic_instance if(ret == 0) { instance->line_protocol_output_enable = 1; + instance->output_type |= 4; } return ret; @@ -513,9 +514,8 @@ static long long dynamic_metric_value_read(struct fieldstat_dynamic_instance *in { return 0; } - metric->field_type == FIELD_TYPE_GAUGE - ?value = get_metric_unit_val(metric, FS_CALC_CURRENT, 0) - :value = get_metric_unit_val(metric, FS_CALC_SPEED, 0); + value = read_metric_current_value(metric); + return value; } diff --git a/src/fieldstat_internal.h b/src/fieldstat_internal.h index 58bd58c..eb3b5d0 100644 --- a/src/fieldstat_internal.h +++ b/src/fieldstat_internal.h @@ -194,7 +194,7 @@ struct fieldstat_instance int summary_cnt; struct timespec last_output_time; - + int output_type; // 0b0000:not output, 0b1000:output file, 0b0100:output line_protocol, 0b0010: output statsd, 0b0001: output prometheus }; struct prometheus_endpoint_instance @@ -236,6 +236,7 @@ struct fieldstat_dynamic_instance struct dynamic_metric **n_thread_dynamic_metric; int n_thread; + int output_type; // 0b0000:not output, 0b1000:output file, 0b0100:output line_protocol, 0b0010: output statsd, 0b0001: output prometheus }; @@ -245,12 +246,13 @@ char* __str_dup(const char* str); long long hdr_count_le_value(const struct hdr_histogram* h, long long value); struct metric * get_metric(struct fieldstat_instance *instance, int metric_id); long long get_metric_unit_val(struct metric *metric,enum field_calc_algo calc_type,int is_refer); +long long read_metric_current_value(struct metric *metric); int is_valid_field_name(const char* name); int is_valid_tags(const struct fieldstat_tag *tags, size_t n_tags); struct metric ** read_metric_slot(struct fieldstat_instance *instance, int metric_id); struct metric * metric_new(enum field_type type, const char *field_name, const struct fieldstat_tag tags[], size_t n_tag); void metric_free(struct metric *metric); -int fieldstat_output_file(struct fieldstat_instance *instance,long long interval_ms); +int file_output(struct fieldstat_instance *instance,long long interval_ms); struct table_line * read_table_line(struct table_metric *table, int line_id); int send_udp(int sd, unsigned int dest_ip, unsigned short dest_port, const char * data, int len); int line_protocol_output(struct fieldstat_instance *instance); diff --git a/src/file_output.cpp b/src/file_output.cpp index 3ffea17..d585160 100644 --- a/src/file_output.cpp +++ b/src/file_output.cpp @@ -53,11 +53,6 @@ static int output_file_format_default_type_gauge(struct fieldstat_instance *inst { continue; } - if(metric->is_invisible == 1) - { - value = get_metric_unit_val(metric, FS_CALC_SPEED, 0); - continue; - } value = get_metric_unit_val(metric, FS_CALC_CURRENT, 0); memset(tags_buf, 0, sizeof(tags_buf)); @@ -115,11 +110,6 @@ static int output_file_format_default_type_counter(struct fieldstat_instance *in { continue; } - if(metric->is_invisible == 1) - { - get_metric_unit_val(metric, FS_CALC_CURRENT, 0); - continue; - } metric_id[metric_cnt] = i; metric_cnt++; } @@ -481,8 +471,8 @@ int output_file_format_json(struct fieldstat_instance *instance, int n_cur_metri cJSON_AddStringToObject(tmp_obj, "column_name", metric->table->column_name[metric->table_column_id]); } metric->field_type == FIELD_TYPE_COUNTER - ?cJSON_AddStringToObject(tmp_obj, "type", "gauge") - :cJSON_AddStringToObject(tmp_obj, "type", "counter"); + ?cJSON_AddStringToObject(tmp_obj, "type", "counter") + :cJSON_AddStringToObject(tmp_obj, "type", "gauge"); value = get_metric_unit_val(metric, FS_CALC_CURRENT, 1); cJSON_AddNumberToObject(tmp_obj, "acc", value); value = get_metric_unit_val(metric, FS_CALC_SPEED, 0); @@ -560,7 +550,7 @@ int output_file_format_json(struct fieldstat_instance *instance, int n_cur_metri } -int fieldstat_output_file(struct fieldstat_instance *instance,long long interval_ms) +int file_output(struct fieldstat_instance *instance,long long interval_ms) { int used_len = 0; int current_table_cnt = 0; diff --git a/src/line_protocol_output.cpp b/src/line_protocol_output.cpp index bead3ca..372db3d 100644 --- a/src/line_protocol_output.cpp +++ b/src/line_protocol_output.cpp @@ -84,12 +84,16 @@ static int add_user_tag_set(struct metric *metric, char *line_buf, unsigned int return used_len; } -static long long read_single_metric_value(struct metric *metric) +static long long read_single_metric_value(struct metric *metric, int output_type) { long long value = 0; + int is_refer = 1; + (output_type >= 4 && output_type < 8) + ?is_refer = 0 + :is_refer = 1; metric->field_type == FIELD_TYPE_GAUGE - ?value = get_metric_unit_val(metric, FS_CALC_CURRENT, 0) - :value = get_metric_unit_val(metric, FS_CALC_SPEED, 0); + ?value = get_metric_unit_val(metric, FS_CALC_CURRENT, is_refer) + :value = get_metric_unit_val(metric, FS_CALC_SPEED, is_refer); return value; } @@ -141,12 +145,12 @@ static int add_table_row_field_set(char *column_name[], long long *row_value, in -static int build_single_metric_line_buf(char *instance_name, struct metric *metric, char *line_buf, int line_buf_size) +static int build_single_metric_line_buf(char *instance_name, int output_type, struct metric *metric, char *line_buf, int line_buf_size) { int used_len = 0; long long value = 0; - value = read_single_metric_value(metric); + value = read_single_metric_value(metric, output_type); if(value == 0) { @@ -169,7 +173,7 @@ static int build_single_metric_line_buf(char *instance_name, struct metric *metr } -static int read_table_row_value(struct metric **row_metric, int n_column, long long *out_row_value) +static int read_table_row_value(struct metric **row_metric, int output_type, int n_column, long long *out_row_value) { int i = 0; struct metric *metric = NULL; @@ -182,13 +186,13 @@ static int read_table_row_value(struct metric **row_metric, int n_column, long l for(i = 0; i < n_column; i++) { metric = row_metric[i]; - out_row_value[i] = read_single_metric_value(metric); + out_row_value[i] = read_single_metric_value(metric, output_type); } return 0; } -static int build_table_row_line_buf(char *instance_name, struct table_metric *table, struct metric **row_metric, char *line_buf, int line_buf_size) +static int build_table_row_line_buf(char *instance_name, int output_type, struct table_metric *table, struct metric **row_metric, char *line_buf, int line_buf_size) { int used_len = 0; struct metric *metric = NULL; @@ -199,7 +203,7 @@ static int build_table_row_line_buf(char *instance_name, struct table_metric *ta } long long row_value[table->column_cnt]; - if(-1 == read_table_row_value(row_metric, table->column_cnt, row_value)) + if(-1 == read_table_row_value(row_metric, output_type, table->column_cnt, row_value)) { return 0; } @@ -245,7 +249,7 @@ static void output_line_protocol_single_metric(struct fieldstat_instance *instan } memset(line_buf, 0, sizeof(line_buf)); - used_len = build_single_metric_line_buf(instance->name, metric, line_buf, sizeof(line_buf)); + used_len = build_single_metric_line_buf(instance->name, instance->output_type, metric, line_buf, sizeof(line_buf)); send_line_buf(&instance->line_protocol_output, line_buf, used_len); } @@ -280,7 +284,7 @@ static void output_line_protocol_table_row(struct fieldstat_instance *instance, row_metrics[k] = get_metric(instance, row->metric_id_belong_to_line[k]); } - used_len = build_table_row_line_buf(instance->name, table, row_metrics, line_buf, sizeof(line_buf)); + used_len = build_table_row_line_buf(instance->name, instance->output_type, table, row_metrics, line_buf, sizeof(line_buf)); send_line_buf(&instance->line_protocol_output, line_buf, used_len); } @@ -330,11 +334,11 @@ int line_protocol_dynamic_metric_output(struct fieldstat_dynamic_instance *insta memset(line_buf, 0, sizeof(line_buf)); if(metric->table) { - used_len = build_table_row_line_buf(instance->name, metric->table, metrics, line_buf, sizeof(line_buf)); + used_len = build_table_row_line_buf(instance->name, instance->output_type, metric->table, metrics, line_buf, sizeof(line_buf)); } else { - used_len = build_single_metric_line_buf(instance->name, metric, line_buf, sizeof(line_buf)); + used_len = build_single_metric_line_buf(instance->name, instance->output_type, metric, line_buf, sizeof(line_buf)); } send_line_buf(&instance->line_protocol_output, line_buf, used_len); } diff --git a/src/prometheus_output.cpp b/src/prometheus_output.cpp index 2b605e8..a4e4d88 100644 --- a/src/prometheus_output.cpp +++ b/src/prometheus_output.cpp @@ -129,14 +129,14 @@ static void prometheus_output_uri_list(struct prometheus_endpoint_instance *prom static int prometheus_output_read_metric_tags(struct metric *metric, char *instance_name, char *tags_buf, unsigned int size) { int i = 0;//used_len = 0; - char unescape[STR_LEN_256] = {0}; + char unescape[256] = {0}; int used_len = 0; used_len += snprintf(tags_buf + used_len, size - used_len, "app_name=\"%s\"", instance_name); if(metric->table) { - used_len += snprintf(tags_buf + used_len, size - used_len, ",line_name=\"%s\"", metric->field_name); + used_len += snprintf(tags_buf + used_len, size - used_len, ",table_name=\"%s\",line_name=\"%s\"", metric->table->name, metric->field_name); } for(i = 0; i < (int)metric->n_tag; i++) @@ -322,7 +322,9 @@ static int prometheus_get_instance_metric_playload(struct fieldstat_instance *in { case FIELD_TYPE_COUNTER: case FIELD_TYPE_GAUGE: - value = get_metric_unit_val(metric, FS_CALC_CURRENT, 1); + instance->output_type == 1 + ?value = get_metric_unit_val(metric, FS_CALC_CURRENT, 0) + :value = get_metric_unit_val(metric, FS_CALC_CURRENT, 1); append_offset += snprintf(new_payload + append_offset, new_payload_size - append_offset, "%s{%s} %lld\n", @@ -443,6 +445,7 @@ int fieldstat_enable_prometheus_output(struct fieldstat_instance *instance) fs_instance_id = g_prometheus_endpoint_instance.fs_instance_cnt++; g_prometheus_endpoint_instance.fs_instance[fs_instance_id] = instance; + instance->output_type |= 1; return 0; } diff --git a/test/src/CMakeLists.txt b/test/src/CMakeLists.txt index fa02909..044eb5d 100644 --- a/test/src/CMakeLists.txt +++ b/test/src/CMakeLists.txt @@ -6,9 +6,14 @@ add_definitions(-std=c++11) #add_executable(gtest_rule ${PROJECT_SOURCE_DIR}/src/tsg_rule.cpp ${PROJECT_SOURCE_DIR}/src/tsg_bridge.cpp ${PROJECT_SOURCE_DIR}/src/tsg_leaky_bucket.cpp gtest_common.cpp gtest_rule.cpp) #target_link_libraries(gtest_rule gtest-static ctemplate-static cjson MESA_prof_load MESA_handle_logger MESA_jump_layer MESA_field_stat2 maatframe) -add_executable(gtest_fieldstat ${SRC} gtest_fieldstat.cpp) -target_link_libraries(gtest_fieldstat gtest-static) +add_executable(gtest_fieldstat_interface ${SRC} gtest_fieldstat_interface.cpp) +target_link_libraries(gtest_fieldstat_interface gtest-static) +add_executable(gtest_fieldstat_output ${SRC} gtest_fieldstat_output.cpp) +target_link_libraries(gtest_fieldstat_output gtest-static) add_executable(gtest_dynamic_fieldstat ${SRC} gtest_dynamic_fieldstat.cpp) target_link_libraries(gtest_dynamic_fieldstat gtest-static) + +add_executable(gtest_dynamic_fieldstat_output ${SRC} gtest_dynamic_fieldstat_output.cpp) +target_link_libraries(gtest_dynamic_fieldstat_output gtest-static)
\ No newline at end of file diff --git a/test/src/gtest_dynamic_fieldstat_output.cpp b/test/src/gtest_dynamic_fieldstat_output.cpp new file mode 100644 index 0000000..fb066c4 --- /dev/null +++ b/test/src/gtest_dynamic_fieldstat_output.cpp @@ -0,0 +1,126 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <gtest/gtest.h> +#include "fieldstat.h" +#include "fieldstat_internal.h" +#include "cJSON.h" + +extern struct prometheus_endpoint_instance g_prometheus_endpoint_instance; + + + +struct thread_para +{ + int loops; + struct fieldstat_dynamic_instance * instance; + int thread_id; + int table_id; + unsigned int *out_column_ids; +}; + +void _worker_thread_multi_incrby(void *arg) +{ + + struct thread_para *para = (struct thread_para*)arg; + int loops = para->loops; + int thread_id = para->thread_id; + int table_id = para->table_id; + unsigned int *out_column_ids = para->out_column_ids; + + struct fieldstat_dynamic_instance *instance = para->instance; + int ret = 0; + struct fieldstat_tag tags[3]; + + int i = 0; + + tags[0].key = "policy_id"; + tags[0].value_int = 1; + tags[0].value_type = 0; + + tags[1].key = "quanlity"; + tags[1].value_double = 0.50; + tags[1].value_type = 1; + + tags[2].key = "device_id"; + tags[2].value_str = "test_device"; + tags[2].value_type = 2; + + for(i = 0; i < loops; i++) + { + ret = fieldstat_dynamic_metric_value_incrby(instance, FIELD_TYPE_GAUGE, "Active_sessions", 10, tags, sizeof(tags)/sizeof(tags[0]), thread_id); + EXPECT_EQ(0, ret); + ret = fieldstat_dynamic_metric_value_incrby(instance, FIELD_TYPE_COUNTER, "Traffic_bytes", 20, tags, sizeof(tags)/sizeof(tags[0]), thread_id); + EXPECT_EQ(0, ret); + + ret = fieldstat_dynamic_table_metric_value_incrby(instance, table_id, out_column_ids[0], "security_rule_hits", 30, tags, sizeof(tags)/sizeof(tags[0]), thread_id); + EXPECT_EQ(0, ret); + ret = fieldstat_dynamic_table_metric_value_incrby(instance, table_id, out_column_ids[1], "security_rule_hits", 31, tags, sizeof(tags)/sizeof(tags[0]), thread_id); + EXPECT_EQ(0, ret); + usleep(1000); + } + return; +} +void * worker_thread_multi_incrby(void *arg) +{ + _worker_thread_multi_incrby(arg); + usleep(1000 * 100); + return NULL; +} + + +TEST(FeildStatDynamicAPI, FieldStatDynamicInstanceMultiIncrby) +{ + int ret = 0; + int n_thread = 64; + int n_loops = 100000; + + long long value = 0; + + const char *column_name[] = {"packages", "bytes"}; + enum field_type column_type[] = {FIELD_TYPE_COUNTER, FIELD_TYPE_COUNTER}; + unsigned int out_column_ids[2]; + int table_id = -1; + + struct thread_para para[n_thread]; + pthread_t thread_ids[n_thread]; + + + struct fieldstat_dynamic_instance *instance = fieldstat_dynamic_instance_new("firewall", n_thread); + ret = fieldstat_dynamic_set_line_protocol_server(instance, "127.0.0.1", 8600); + EXPECT_EQ(0, ret); + + table_id = fieldstat_register_dynamic_table(instance, "shaping", column_name, column_type, sizeof(column_name)/sizeof(column_name[0]), out_column_ids); + EXPECT_EQ(0, table_id); + system("cat /dev/null > /tmp/metrics.out"); + fieldstat_dynamic_instance_start(instance); + + for(int i = 0; i < n_thread; i++) + { + para[i].loops = n_loops; + para[i].instance = instance; + para[i].thread_id = i; + para[i].table_id = table_id; + para[i].out_column_ids = out_column_ids; + } + + for(int i = 0; i < n_thread; i++) + { + ret = pthread_create(&(thread_ids[i]), NULL, worker_thread_multi_incrby, &(para[i])); + EXPECT_EQ(0, ret); + } + + void *temp; + for(int i = 0; i < n_thread; i++) + { + pthread_join(thread_ids[i], (void**)&temp); + } + sleep(6); + fieldstat_dynamic_instance_free(instance); +} + +int main(int argc, char *argv[]) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}
\ No newline at end of file diff --git a/test/src/gtest_fieldstat.cpp b/test/src/gtest_fieldstat_interface.cpp index 6683a31..558f267 100644 --- a/test/src/gtest_fieldstat.cpp +++ b/test/src/gtest_fieldstat_interface.cpp @@ -291,6 +291,7 @@ TEST(FeildStatAPI, FieldStatLineProtocolOutputTableMetric) ret = fieldstat_set_line_protocol_server(instance, "127.0.0.1", 8600); EXPECT_EQ(0, ret); + EXPECT_EQ(4, instance->output_type); ret = fieldstat_disable_background_thread(instance); EXPECT_EQ(0, ret); fieldstat_instance_start(instance); diff --git a/test/src/gtest_fieldstat_output.cpp b/test/src/gtest_fieldstat_output.cpp new file mode 100644 index 0000000..9ae18de --- /dev/null +++ b/test/src/gtest_fieldstat_output.cpp @@ -0,0 +1,694 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <gtest/gtest.h> +#include "fieldstat.h" +#include "fieldstat_internal.h" + +extern struct prometheus_endpoint_instance g_prometheus_endpoint_instance; + +TEST(FeildStatOutput, OutputFile) +{ + int ret = 0; + int n_loops = 4; + struct fieldstat_instance * instance = NULL; + int table_id = -1; + FILE *fp; + char read_line_buf[2048] = {0}; + + int output_metric_ids[54] = {0}; + + const char *output_file_path = "/tmp/fieldstat.txt"; + const char *table_column = "network_activity new_conn_num established_conn_num" + " close_conn_num total_in_bytes total_out_bytes total_in_packets " + "total_out_packets default_conn_num default_in_bytes default_out_bytes " + "default_in_packets default_out_packets allow_conn_num allow_in_bytes " + "allow_out_bytes allow_in_packets allow_out_packets deny_conn_num " + "deny_in_bytes deny_out_bytes deny_in_packets deny_out_packets monitor_conn_num " + "monitor_in_bytes monitor_out_bytes monitor_in_packets monitor_out_packets intercept_conn_num " + "intercept_in_bytes intercept_out_bytes intercept_in_packets intercept_out_packets " + "ipv4_in_packets ipv4_in_bytes ipv4_out_packetsipv4_out_bytes ipv6_in_packets ipv6_in_bytes " + "ipv6_out_packets ipv6_out_bytes tcp_conn_num tcp_in_packets tcp_in_bytes tcp_out_packets " + "tcp_out_bytes udp_conn_num udp_in_packets udp_in_bytes udp_out_packets udp_out_bytes " + "alert_bytes block_bytes pinning_num maybe_pinning_num not_pinning_num\n"; + + const char *table_row_value = "TRAFFIC 1000 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 \n"; + + const char *table_column_name[] = {"new_conn_num", "established_conn_num", "close_conn_num", "total_in_bytes", "total_out_bytes", "total_in_packets", + "total_out_packets", "default_conn_num", "default_in_bytes", "default_out_bytes", "default_in_packets", "default_out_packets", "allow_conn_num", + "allow_in_bytes", "allow_out_bytes", "allow_in_packets", "allow_out_packets", "deny_conn_num", "deny_in_bytes", "deny_out_bytes", "deny_in_packets", + "deny_out_packets", "monitor_conn_num", "monitor_in_bytes", "monitor_out_bytes", "monitor_in_packets", "monitor_out_packets", "intercept_conn_num", + "intercept_in_bytes", "intercept_out_bytes", "intercept_in_packets", "intercept_out_packets", "ipv4_in_packets", "ipv4_in_bytes", "ipv4_out_packets" + "ipv4_out_bytes", "ipv6_in_packets", "ipv6_in_bytes", "ipv6_out_packets", "ipv6_out_bytes", "tcp_conn_num", "tcp_in_packets", "tcp_in_bytes", + "tcp_out_packets", "tcp_out_bytes", "udp_conn_num", "udp_in_packets", "udp_in_bytes", "udp_out_packets", "udp_out_bytes", "alert_bytes", "block_bytes", + "pinning_num", "maybe_pinning_num", "not_pinning_num"}; + enum field_type table_column_type[54] = {FIELD_TYPE_COUNTER}; + + instance = fieldstat_instance_new("tsg_statistic"); + EXPECT_STREQ("tsg_statistic", instance->name); + + table_id = fieldstat_register_table(instance, "network_activity", table_column_name, table_column_type, sizeof(table_column_name)/sizeof(table_column_name[0])); + EXPECT_EQ(0, table_id); + ret = fieldstat_register_table_row(instance, table_id, "TRAFFIC", NULL, 0, output_metric_ids); + EXPECT_EQ(0, ret); + ret = fieldstat_set_local_output(instance, output_file_path, "default"); + EXPECT_EQ(0, ret); + fieldstat_instance_start(instance); + fieldstat_value_incrby(instance, output_metric_ids[0], 1000); + sleep(3); + fp = fopen(output_file_path, "r"); + EXPECT_NE(nullptr, fp); + int n_line = 0; + + while(!feof(fp)) + { + if(NULL == fgets(read_line_buf, sizeof(read_line_buf), fp)) + { + continue; + } + if(n_line == 1) + { + EXPECT_STREQ(table_column, read_line_buf); + } + if(n_line == 2) + { + EXPECT_STREQ(table_row_value, read_line_buf); + } + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + fieldstat_instance_free(instance); + +} + + +TEST(FeildStatOutput, OutputLineProtocol) +{ + int ret = 0; + int n_loops = 1; + struct fieldstat_instance * instance = NULL; + int table_id = -1; + int output_metric_ids[54] = {0}; + const char *telegraf_output_file = "/tmp/metrics.out"; + FILE *fp; + char line[2048] = {0}; + cJSON *cjson_metric = NULL; + cJSON *cjson_tags = NULL; + const char *compare = "{\"fields\":{\"alert_bytes\":0,\"allow_conn_num\":0,\"allow_in_bytes\":0,\"allow_in_packets\":0,\"allow_out_bytes\":0,"\ + "\"allow_out_packets\":0,\"block_bytes\":0,\"close_conn_num\":0,\"default_conn_num\":0,\"default_in_bytes\":0,"\ + "\"default_in_packets\":0,\"default_out_bytes\":0,\"default_out_packets\":0,\"deny_conn_num\":0,\"deny_in_bytes\":0,"\ + "\"deny_in_packets\":0,\"deny_out_bytes\":0,\"deny_out_packets\":0,\"established_conn_num\":0,\"intercept_conn_num\":0,"\ + "\"intercept_in_bytes\":0,\"intercept_in_packets\":0,\"intercept_out_bytes\":0,\"intercept_out_packets\":0,"\ + "\"ipv4_in_bytes\":0,\"ipv4_in_packets\":0,\"ipv4_out_packetsipv4_out_bytes\":0,\"ipv6_in_bytes\":0,\"ipv6_in_packets\":0,"\ + "\"ipv6_out_bytes\":0,\"ipv6_out_packets\":0,\"maybe_pinning_num\":0,\"monitor_conn_num\":0,\"monitor_in_bytes\":0,"\ + "\"monitor_in_packets\":0,\"monitor_out_bytes\":0,\"monitor_out_packets\":0,\"new_conn_num\":1000,\"not_pinning_num\":0,"\ + "\"pinning_num\":0,\"tcp_conn_num\":0,\"tcp_in_bytes\":0,\"tcp_in_packets\":0,\"tcp_out_bytes\":0,\"tcp_out_packets\":0,"\ + "\"total_in_bytes\":0,\"total_in_packets\":0,\"total_out_bytes\":0,\"total_out_packets\":0,\"udp_conn_num\":0,"\ + "\"udp_in_bytes\":0,\"udp_in_packets\":0,\"udp_out_bytes\":0,\"udp_out_packets\":0},\"name\":\"TRAFFIC\","\ + "\"tags\":{\"app_name\":\"tsg_statistic\",\"table_name\":\"network_activity\"}}"; + char *cjson_metric_str = NULL; + + const char *table_column_name[] = {"new_conn_num", "established_conn_num", "close_conn_num", "total_in_bytes", "total_out_bytes", "total_in_packets", + "total_out_packets", "default_conn_num", "default_in_bytes", "default_out_bytes", "default_in_packets", "default_out_packets", "allow_conn_num", + "allow_in_bytes", "allow_out_bytes", "allow_in_packets", "allow_out_packets", "deny_conn_num", "deny_in_bytes", "deny_out_bytes", "deny_in_packets", + "deny_out_packets", "monitor_conn_num", "monitor_in_bytes", "monitor_out_bytes", "monitor_in_packets", "monitor_out_packets", "intercept_conn_num", + "intercept_in_bytes", "intercept_out_bytes", "intercept_in_packets", "intercept_out_packets", "ipv4_in_packets", "ipv4_in_bytes", "ipv4_out_packets" + "ipv4_out_bytes", "ipv6_in_packets", "ipv6_in_bytes", "ipv6_out_packets", "ipv6_out_bytes", "tcp_conn_num", "tcp_in_packets", "tcp_in_bytes", + "tcp_out_packets", "tcp_out_bytes", "udp_conn_num", "udp_in_packets", "udp_in_bytes", "udp_out_packets", "udp_out_bytes", "alert_bytes", "block_bytes", + "pinning_num", "maybe_pinning_num", "not_pinning_num"}; + enum field_type table_column_type[54] = {FIELD_TYPE_COUNTER}; + + instance = fieldstat_instance_new("tsg_statistic"); + EXPECT_STREQ("tsg_statistic", instance->name); + + table_id = fieldstat_register_table(instance, "network_activity", table_column_name, table_column_type, sizeof(table_column_name)/sizeof(table_column_name[0])); + EXPECT_EQ(0, table_id); + ret = fieldstat_register_table_row(instance, table_id, "TRAFFIC", NULL, 0, output_metric_ids); + EXPECT_EQ(0, ret); + + ret = fieldstat_set_line_protocol_server(instance, "127.0.0.1", 8600); + EXPECT_EQ(0, ret); + EXPECT_EQ(4, instance->output_type); + fieldstat_instance_start(instance); + fieldstat_value_incrby(instance, output_metric_ids[0], 1000); + ret = system("cat /dev/null > /tmp/metrics.out"); + sleep(3); + fp = fopen(telegraf_output_file, "r"); + EXPECT_NE(nullptr, fp); + int n_line = 0; + + while(!feof(fp)) + { + if(NULL == fgets(line, sizeof(line), fp)) + { + continue; + } + cjson_metric = cJSON_Parse(line); + EXPECT_NE(nullptr, cjson_metric); + cJSON_DeleteItemFromObject(cjson_metric, "timestamp"); + + cjson_tags = cJSON_GetObjectItem(cjson_metric, "tags"); + EXPECT_NE(nullptr, cjson_tags); + cJSON_DeleteItemFromObject(cjson_tags, "host"); + cjson_metric_str = cJSON_PrintUnformatted(cjson_metric); + EXPECT_NE(nullptr, cjson_metric_str); + if(cjson_metric_str) + { + EXPECT_STREQ(compare, cjson_metric_str); + free(cjson_metric_str); + cjson_metric_str = NULL; + } + cJSON_Delete(cjson_metric); + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + + fieldstat_instance_free(instance); + +} + +TEST(FeildStatOutput, OutputPrometheus) +{ + int ret = 0; + int table_id = -1; + int n_loops = 54; + int output_metric_ids[54] = {0}; + struct fieldstat_instance * instance = NULL; + FILE *fp; + const char *prometheus_output_file = "/tmp/prometheus.txt"; + char line[2048] = {0}; + const char *compare = "tsg_statistic_new_conn_num{app_name=\"tsg_statistic\",table_name=\"network_activity\",line_name=\"TRAFFIC\"} 1000\n"; + + const char *table_column_name[] = {"new_conn_num", "established_conn_num", "close_conn_num", "total_in_bytes", "total_out_bytes", "total_in_packets", + "total_out_packets", "default_conn_num", "default_in_bytes", "default_out_bytes", "default_in_packets", "default_out_packets", "allow_conn_num", + "allow_in_bytes", "allow_out_bytes", "allow_in_packets", "allow_out_packets", "deny_conn_num", "deny_in_bytes", "deny_out_bytes", "deny_in_packets", + "deny_out_packets", "monitor_conn_num", "monitor_in_bytes", "monitor_out_bytes", "monitor_in_packets", "monitor_out_packets", "intercept_conn_num", + "intercept_in_bytes", "intercept_out_bytes", "intercept_in_packets", "intercept_out_packets", "ipv4_in_packets", "ipv4_in_bytes", "ipv4_out_packets" + "ipv4_out_bytes", "ipv6_in_packets", "ipv6_in_bytes", "ipv6_out_packets", "ipv6_out_bytes", "tcp_conn_num", "tcp_in_packets", "tcp_in_bytes", + "tcp_out_packets", "tcp_out_bytes", "udp_conn_num", "udp_in_packets", "udp_in_bytes", "udp_out_packets", "udp_out_bytes", "alert_bytes", "block_bytes", + "pinning_num", "maybe_pinning_num", "not_pinning_num"}; + enum field_type table_column_type[54] = {FIELD_TYPE_COUNTER}; + + instance = fieldstat_instance_new("tsg_statistic"); + EXPECT_STREQ("tsg_statistic", instance->name); + + table_id = fieldstat_register_table(instance, "network_activity", table_column_name, table_column_type, sizeof(table_column_name)/sizeof(table_column_name[0])); + EXPECT_EQ(0, table_id); + ret = fieldstat_register_table_row(instance, table_id, "TRAFFIC", NULL, 0, output_metric_ids); + EXPECT_EQ(0, ret); + ret = fieldstat_global_enable_prometheus_endpoint(9020, NULL); + EXPECT_EQ(0, ret); + ret = fieldstat_enable_prometheus_output(instance); + EXPECT_EQ(0, ret); + fieldstat_instance_start(instance); + fieldstat_value_incrby(instance, output_metric_ids[0], 1000); + EXPECT_EQ(0, ret); + sleep(1); + system("cat /dev/null > /tmp/prometheus.txt"); + system("curl -s http://127.0.0.1:9020/metrics -o /tmp/prometheus.txt"); + + int n_line = 0; + fp = fopen(prometheus_output_file, "r"); + EXPECT_NE(nullptr, fp); + while(!feof(fp)) + { + if(NULL == fgets(line, sizeof(line), fp)) + { + continue; + } + if(n_line == 0) + { + EXPECT_STREQ(compare, line); + } + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + + fieldstat_global_disable_prometheus_endpoint(); + fieldstat_instance_free(instance); +} + +TEST(FeildStatOutput, OutputFileAndLineProtocol) +{ + int ret = 0; + int n_loops = 1; + struct fieldstat_instance * instance = NULL; + int table_id = -1; + int output_metric_ids[54] = {0}; + const char *telegraf_output_file = "/tmp/metrics.out"; + FILE *fp; + char line[2048] = {0}; + char read_line_buf[2048] = {0}; + cJSON *cjson_metric = NULL; + cJSON *cjson_tags = NULL; + + const char *output_file_path = "/tmp/fieldstat.txt"; + const char *table_column = "network_activity new_conn_num established_conn_num" + " close_conn_num total_in_bytes total_out_bytes total_in_packets " + "total_out_packets default_conn_num default_in_bytes default_out_bytes " + "default_in_packets default_out_packets allow_conn_num allow_in_bytes " + "allow_out_bytes allow_in_packets allow_out_packets deny_conn_num " + "deny_in_bytes deny_out_bytes deny_in_packets deny_out_packets monitor_conn_num " + "monitor_in_bytes monitor_out_bytes monitor_in_packets monitor_out_packets intercept_conn_num " + "intercept_in_bytes intercept_out_bytes intercept_in_packets intercept_out_packets " + "ipv4_in_packets ipv4_in_bytes ipv4_out_packetsipv4_out_bytes ipv6_in_packets ipv6_in_bytes " + "ipv6_out_packets ipv6_out_bytes tcp_conn_num tcp_in_packets tcp_in_bytes tcp_out_packets " + "tcp_out_bytes udp_conn_num udp_in_packets udp_in_bytes udp_out_packets udp_out_bytes " + "alert_bytes block_bytes pinning_num maybe_pinning_num not_pinning_num\n"; + + const char *table_row_value = "TRAFFIC 1000 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 \n"; + + + const char *compare = "{\"fields\":{\"alert_bytes\":0,\"allow_conn_num\":0,\"allow_in_bytes\":0,\"allow_in_packets\":0,\"allow_out_bytes\":0,"\ + "\"allow_out_packets\":0,\"block_bytes\":0,\"close_conn_num\":0,\"default_conn_num\":0,\"default_in_bytes\":0,"\ + "\"default_in_packets\":0,\"default_out_bytes\":0,\"default_out_packets\":0,\"deny_conn_num\":0,\"deny_in_bytes\":0,"\ + "\"deny_in_packets\":0,\"deny_out_bytes\":0,\"deny_out_packets\":0,\"established_conn_num\":0,\"intercept_conn_num\":0,"\ + "\"intercept_in_bytes\":0,\"intercept_in_packets\":0,\"intercept_out_bytes\":0,\"intercept_out_packets\":0,"\ + "\"ipv4_in_bytes\":0,\"ipv4_in_packets\":0,\"ipv4_out_packetsipv4_out_bytes\":0,\"ipv6_in_bytes\":0,\"ipv6_in_packets\":0,"\ + "\"ipv6_out_bytes\":0,\"ipv6_out_packets\":0,\"maybe_pinning_num\":0,\"monitor_conn_num\":0,\"monitor_in_bytes\":0,"\ + "\"monitor_in_packets\":0,\"monitor_out_bytes\":0,\"monitor_out_packets\":0,\"new_conn_num\":1000,\"not_pinning_num\":0,"\ + "\"pinning_num\":0,\"tcp_conn_num\":0,\"tcp_in_bytes\":0,\"tcp_in_packets\":0,\"tcp_out_bytes\":0,\"tcp_out_packets\":0,"\ + "\"total_in_bytes\":0,\"total_in_packets\":0,\"total_out_bytes\":0,\"total_out_packets\":0,\"udp_conn_num\":0,"\ + "\"udp_in_bytes\":0,\"udp_in_packets\":0,\"udp_out_bytes\":0,\"udp_out_packets\":0},\"name\":\"TRAFFIC\","\ + "\"tags\":{\"app_name\":\"tsg_statistic\",\"table_name\":\"network_activity\"}}"; + char *cjson_metric_str = NULL; + + const char *table_column_name[] = {"new_conn_num", "established_conn_num", "close_conn_num", "total_in_bytes", "total_out_bytes", "total_in_packets", + "total_out_packets", "default_conn_num", "default_in_bytes", "default_out_bytes", "default_in_packets", "default_out_packets", "allow_conn_num", + "allow_in_bytes", "allow_out_bytes", "allow_in_packets", "allow_out_packets", "deny_conn_num", "deny_in_bytes", "deny_out_bytes", "deny_in_packets", + "deny_out_packets", "monitor_conn_num", "monitor_in_bytes", "monitor_out_bytes", "monitor_in_packets", "monitor_out_packets", "intercept_conn_num", + "intercept_in_bytes", "intercept_out_bytes", "intercept_in_packets", "intercept_out_packets", "ipv4_in_packets", "ipv4_in_bytes", "ipv4_out_packets" + "ipv4_out_bytes", "ipv6_in_packets", "ipv6_in_bytes", "ipv6_out_packets", "ipv6_out_bytes", "tcp_conn_num", "tcp_in_packets", "tcp_in_bytes", + "tcp_out_packets", "tcp_out_bytes", "udp_conn_num", "udp_in_packets", "udp_in_bytes", "udp_out_packets", "udp_out_bytes", "alert_bytes", "block_bytes", + "pinning_num", "maybe_pinning_num", "not_pinning_num"}; + enum field_type table_column_type[54] = {FIELD_TYPE_COUNTER}; + + instance = fieldstat_instance_new("tsg_statistic"); + EXPECT_STREQ("tsg_statistic", instance->name); + + table_id = fieldstat_register_table(instance, "network_activity", table_column_name, table_column_type, sizeof(table_column_name)/sizeof(table_column_name[0])); + EXPECT_EQ(0, table_id); + ret = fieldstat_register_table_row(instance, table_id, "TRAFFIC", NULL, 0, output_metric_ids); + EXPECT_EQ(0, ret); + + ret = fieldstat_set_line_protocol_server(instance, "127.0.0.1", 8600); + EXPECT_EQ(0, ret); + ret = fieldstat_set_local_output(instance, output_file_path, "default"); + EXPECT_EQ(0, ret); + + EXPECT_EQ(12, instance->output_type); + ret = system("cat /dev/null > /tmp/metrics.out"); + ret = system("cat /dev/null > /tmp/fieldstat.txt"); + fieldstat_instance_start(instance); + fieldstat_value_incrby(instance, output_metric_ids[0], 1000); + sleep(3); + int n_line = 0; + fp = fopen(telegraf_output_file, "r"); + EXPECT_NE(nullptr, fp); + while(!feof(fp)) + { + if(NULL == fgets(line, sizeof(line), fp)) + { + continue; + } + cjson_metric = cJSON_Parse(line); + EXPECT_NE(nullptr, cjson_metric); + cJSON_DeleteItemFromObject(cjson_metric, "timestamp"); + + cjson_tags = cJSON_GetObjectItem(cjson_metric, "tags"); + EXPECT_NE(nullptr, cjson_tags); + cJSON_DeleteItemFromObject(cjson_tags, "host"); + cjson_metric_str = cJSON_PrintUnformatted(cjson_metric); + EXPECT_NE(nullptr, cjson_metric_str); + if(cjson_metric_str) + { + EXPECT_STREQ(compare, cjson_metric_str); + free(cjson_metric_str); + cjson_metric_str = NULL; + } + cJSON_Delete(cjson_metric); + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + + fp = fopen("/tmp/fieldstat.txt", "r"); + EXPECT_NE(nullptr, fp); + n_line = 0; + n_loops = 4; + + while(!feof(fp)) + { + if(NULL == fgets(read_line_buf, sizeof(read_line_buf), fp)) + { + continue; + } + if(n_line == 1) + { + EXPECT_STREQ(table_column, read_line_buf); + } + if(n_line == 2) + { + EXPECT_STREQ(table_row_value, read_line_buf); + } + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + + + fieldstat_instance_free(instance); + +} + + +TEST(FeildStatOutput, OutputFileAndPrometheus) +{ + int ret = 0; + int n_loops = 0; + struct fieldstat_instance * instance = NULL; + int table_id = -1; + int output_metric_ids[54] = {0}; + FILE *fp; + char line[2048] = {0}; + + const char *prometheus_output_path = "/tmp/prometheus.txt"; + const char *file_output_path = "/tmp/fieldstat.txt"; + const char *prometheus_output_result = "tsg_statistic_new_conn_num{app_name=\"tsg_statistic\",table_name=\"network_activity\",line_name=\"TRAFFIC\"} 1000\n"; + const char *table_column = "network_activity new_conn_num established_conn_num" + " close_conn_num total_in_bytes total_out_bytes total_in_packets " + "total_out_packets default_conn_num default_in_bytes default_out_bytes " + "default_in_packets default_out_packets allow_conn_num allow_in_bytes " + "allow_out_bytes allow_in_packets allow_out_packets deny_conn_num " + "deny_in_bytes deny_out_bytes deny_in_packets deny_out_packets monitor_conn_num " + "monitor_in_bytes monitor_out_bytes monitor_in_packets monitor_out_packets intercept_conn_num " + "intercept_in_bytes intercept_out_bytes intercept_in_packets intercept_out_packets " + "ipv4_in_packets ipv4_in_bytes ipv4_out_packetsipv4_out_bytes ipv6_in_packets ipv6_in_bytes " + "ipv6_out_packets ipv6_out_bytes tcp_conn_num tcp_in_packets tcp_in_bytes tcp_out_packets " + "tcp_out_bytes udp_conn_num udp_in_packets udp_in_bytes udp_out_packets udp_out_bytes " + "alert_bytes block_bytes pinning_num maybe_pinning_num not_pinning_num\n"; + + const char *table_row_value = "TRAFFIC 1000 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 \n"; + + + + const char *table_column_name[] = {"new_conn_num", "established_conn_num", "close_conn_num", "total_in_bytes", "total_out_bytes", "total_in_packets", + "total_out_packets", "default_conn_num", "default_in_bytes", "default_out_bytes", "default_in_packets", "default_out_packets", "allow_conn_num", + "allow_in_bytes", "allow_out_bytes", "allow_in_packets", "allow_out_packets", "deny_conn_num", "deny_in_bytes", "deny_out_bytes", "deny_in_packets", + "deny_out_packets", "monitor_conn_num", "monitor_in_bytes", "monitor_out_bytes", "monitor_in_packets", "monitor_out_packets", "intercept_conn_num", + "intercept_in_bytes", "intercept_out_bytes", "intercept_in_packets", "intercept_out_packets", "ipv4_in_packets", "ipv4_in_bytes", "ipv4_out_packets" + "ipv4_out_bytes", "ipv6_in_packets", "ipv6_in_bytes", "ipv6_out_packets", "ipv6_out_bytes", "tcp_conn_num", "tcp_in_packets", "tcp_in_bytes", + "tcp_out_packets", "tcp_out_bytes", "udp_conn_num", "udp_in_packets", "udp_in_bytes", "udp_out_packets", "udp_out_bytes", "alert_bytes", "block_bytes", + "pinning_num", "maybe_pinning_num", "not_pinning_num"}; + enum field_type table_column_type[54] = {FIELD_TYPE_COUNTER}; + + instance = fieldstat_instance_new("tsg_statistic"); + EXPECT_STREQ("tsg_statistic", instance->name); + + table_id = fieldstat_register_table(instance, "network_activity", table_column_name, table_column_type, sizeof(table_column_name)/sizeof(table_column_name[0])); + EXPECT_EQ(0, table_id); + ret = fieldstat_register_table_row(instance, table_id, "TRAFFIC", NULL, 0, output_metric_ids); + EXPECT_EQ(0, ret); + ret = fieldstat_set_local_output(instance, file_output_path, "default"); + EXPECT_EQ(0, ret); + ret = fieldstat_global_enable_prometheus_endpoint(9021, NULL); + EXPECT_EQ(0, ret); + ret = fieldstat_enable_prometheus_output(instance); + EXPECT_EQ(0, ret); + + EXPECT_EQ(9, instance->output_type); + ret = system("cat /dev/null > /tmp/prometheus.txt"); + ret = system("cat /dev/null > /tmp/fieldstat.txt"); + fieldstat_instance_start(instance); + fieldstat_value_incrby(instance, output_metric_ids[0], 1000); + sleep(3); + system("curl -s http://127.0.0.1:9021/metrics -o /tmp/prometheus.txt"); + int n_line = 0; + + fp = fopen("/tmp/fieldstat.txt", "r"); + EXPECT_NE(nullptr, fp); + n_line = 0; + n_loops = 4; + + while(!feof(fp)) + { + if(NULL == fgets(line, sizeof(line), fp)) + { + continue; + } + if(n_line == 1) + { + EXPECT_STREQ(table_column, line); + } + if(n_line == 2) + { + EXPECT_STREQ(table_row_value, line); + } + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + n_loops = 54; + n_line = 0; + fp = fopen(prometheus_output_path, "r"); + EXPECT_NE(nullptr, fp); + while(!feof(fp)) + { + if(NULL == fgets(line, sizeof(line), fp)) + { + continue; + } + if(n_line == 0) + { + EXPECT_STREQ(prometheus_output_result, line); + } + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + fieldstat_global_disable_prometheus_endpoint(); + fieldstat_instance_free(instance); + +} + +TEST(FeildStatOutput, OutputFileAndPrometheusAndLineProtocol) +{ + int ret = 0; + int n_loops = 0; + struct fieldstat_instance * instance = NULL; + int table_id = -1; + int output_metric_ids[54] = {0}; + FILE *fp; + char line[2048] = {0}; + + const char *prometheus_output_path = "/tmp/prometheus.txt"; + const char *file_output_path = "/tmp/fieldstat.txt"; + const char *telegraf_output_file = "/tmp/metrics.out"; + const char *prometheus_output_result = "tsg_statistic_new_conn_num{app_name=\"tsg_statistic\",table_name=\"network_activity\",line_name=\"TRAFFIC\"} 1000\n"; + const char *table_column = "network_activity new_conn_num established_conn_num" + " close_conn_num total_in_bytes total_out_bytes total_in_packets " + "total_out_packets default_conn_num default_in_bytes default_out_bytes " + "default_in_packets default_out_packets allow_conn_num allow_in_bytes " + "allow_out_bytes allow_in_packets allow_out_packets deny_conn_num " + "deny_in_bytes deny_out_bytes deny_in_packets deny_out_packets monitor_conn_num " + "monitor_in_bytes monitor_out_bytes monitor_in_packets monitor_out_packets intercept_conn_num " + "intercept_in_bytes intercept_out_bytes intercept_in_packets intercept_out_packets " + "ipv4_in_packets ipv4_in_bytes ipv4_out_packetsipv4_out_bytes ipv6_in_packets ipv6_in_bytes " + "ipv6_out_packets ipv6_out_bytes tcp_conn_num tcp_in_packets tcp_in_bytes tcp_out_packets " + "tcp_out_bytes udp_conn_num udp_in_packets udp_in_bytes udp_out_packets udp_out_bytes " + "alert_bytes block_bytes pinning_num maybe_pinning_num not_pinning_num\n"; + + const char *table_row_value = "TRAFFIC 1000 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 " + "0 0 0 0 \n"; + + + + const char *table_column_name[] = {"new_conn_num", "established_conn_num", "close_conn_num", "total_in_bytes", "total_out_bytes", "total_in_packets", + "total_out_packets", "default_conn_num", "default_in_bytes", "default_out_bytes", "default_in_packets", "default_out_packets", "allow_conn_num", + "allow_in_bytes", "allow_out_bytes", "allow_in_packets", "allow_out_packets", "deny_conn_num", "deny_in_bytes", "deny_out_bytes", "deny_in_packets", + "deny_out_packets", "monitor_conn_num", "monitor_in_bytes", "monitor_out_bytes", "monitor_in_packets", "monitor_out_packets", "intercept_conn_num", + "intercept_in_bytes", "intercept_out_bytes", "intercept_in_packets", "intercept_out_packets", "ipv4_in_packets", "ipv4_in_bytes", "ipv4_out_packets" + "ipv4_out_bytes", "ipv6_in_packets", "ipv6_in_bytes", "ipv6_out_packets", "ipv6_out_bytes", "tcp_conn_num", "tcp_in_packets", "tcp_in_bytes", + "tcp_out_packets", "tcp_out_bytes", "udp_conn_num", "udp_in_packets", "udp_in_bytes", "udp_out_packets", "udp_out_bytes", "alert_bytes", "block_bytes", + "pinning_num", "maybe_pinning_num", "not_pinning_num"}; + + cJSON *cjson_metric = NULL; + cJSON *cjson_tags = NULL; + const char *compare = "{\"fields\":{\"alert_bytes\":0,\"allow_conn_num\":0,\"allow_in_bytes\":0,\"allow_in_packets\":0,\"allow_out_bytes\":0,"\ + "\"allow_out_packets\":0,\"block_bytes\":0,\"close_conn_num\":0,\"default_conn_num\":0,\"default_in_bytes\":0,"\ + "\"default_in_packets\":0,\"default_out_bytes\":0,\"default_out_packets\":0,\"deny_conn_num\":0,\"deny_in_bytes\":0,"\ + "\"deny_in_packets\":0,\"deny_out_bytes\":0,\"deny_out_packets\":0,\"established_conn_num\":0,\"intercept_conn_num\":0,"\ + "\"intercept_in_bytes\":0,\"intercept_in_packets\":0,\"intercept_out_bytes\":0,\"intercept_out_packets\":0,"\ + "\"ipv4_in_bytes\":0,\"ipv4_in_packets\":0,\"ipv4_out_packetsipv4_out_bytes\":0,\"ipv6_in_bytes\":0,\"ipv6_in_packets\":0,"\ + "\"ipv6_out_bytes\":0,\"ipv6_out_packets\":0,\"maybe_pinning_num\":0,\"monitor_conn_num\":0,\"monitor_in_bytes\":0,"\ + "\"monitor_in_packets\":0,\"monitor_out_bytes\":0,\"monitor_out_packets\":0,\"new_conn_num\":1000,\"not_pinning_num\":0,"\ + "\"pinning_num\":0,\"tcp_conn_num\":0,\"tcp_in_bytes\":0,\"tcp_in_packets\":0,\"tcp_out_bytes\":0,\"tcp_out_packets\":0,"\ + "\"total_in_bytes\":0,\"total_in_packets\":0,\"total_out_bytes\":0,\"total_out_packets\":0,\"udp_conn_num\":0,"\ + "\"udp_in_bytes\":0,\"udp_in_packets\":0,\"udp_out_bytes\":0,\"udp_out_packets\":0},\"name\":\"TRAFFIC\","\ + "\"tags\":{\"app_name\":\"tsg_statistic\",\"table_name\":\"network_activity\"}}"; + char *cjson_metric_str = NULL; + + enum field_type table_column_type[54] = {FIELD_TYPE_COUNTER}; + + instance = fieldstat_instance_new("tsg_statistic"); + EXPECT_STREQ("tsg_statistic", instance->name); + + table_id = fieldstat_register_table(instance, "network_activity", table_column_name, table_column_type, sizeof(table_column_name)/sizeof(table_column_name[0])); + EXPECT_EQ(0, table_id); + ret = fieldstat_register_table_row(instance, table_id, "TRAFFIC", NULL, 0, output_metric_ids); + EXPECT_EQ(0, ret); + ret = fieldstat_set_local_output(instance, file_output_path, "default"); + EXPECT_EQ(0, ret); + ret = fieldstat_global_enable_prometheus_endpoint(9022, NULL); + EXPECT_EQ(0, ret); + ret = fieldstat_enable_prometheus_output(instance); + EXPECT_EQ(0, ret); + + EXPECT_EQ(9, instance->output_type); + ret = system("cat /dev/null > /tmp/prometheus.txt"); + ret = system("cat /dev/null > /tmp/fieldstat.txt"); + fieldstat_instance_start(instance); + fieldstat_value_incrby(instance, output_metric_ids[0], 1000); + sleep(3); + system("curl -s http://127.0.0.1:9022/metrics -o /tmp/prometheus.txt"); + int n_line = 0; + + fp = fopen("/tmp/fieldstat.txt", "r"); + EXPECT_NE(nullptr, fp); + n_line = 0; + n_loops = 4; + + while(!feof(fp)) + { + if(NULL == fgets(line, sizeof(line), fp)) + { + continue; + } + if(n_line == 1) + { + EXPECT_STREQ(table_column, line); + } + if(n_line == 2) + { + EXPECT_STREQ(table_row_value, line); + } + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + n_loops = 54; + n_line = 0; + fp = fopen(prometheus_output_path, "r"); + EXPECT_NE(nullptr, fp); + while(!feof(fp)) + { + if(NULL == fgets(line, sizeof(line), fp)) + { + continue; + } + if(n_line == 0) + { + EXPECT_STREQ(prometheus_output_result, line); + } + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + + n_loops = 1; + n_line = 0; + fp = fopen(telegraf_output_file, "r"); + EXPECT_NE(nullptr, fp); + + while(!feof(fp)) + { + if(NULL == fgets(line, sizeof(line), fp)) + { + continue; + } + cjson_metric = cJSON_Parse(line); + EXPECT_NE(nullptr, cjson_metric); + cJSON_DeleteItemFromObject(cjson_metric, "timestamp"); + + cjson_tags = cJSON_GetObjectItem(cjson_metric, "tags"); + EXPECT_NE(nullptr, cjson_tags); + cJSON_DeleteItemFromObject(cjson_tags, "host"); + cjson_metric_str = cJSON_PrintUnformatted(cjson_metric); + EXPECT_NE(nullptr, cjson_metric_str); + if(cjson_metric_str) + { + EXPECT_STREQ(compare, cjson_metric_str); + free(cjson_metric_str); + cjson_metric_str = NULL; + } + cJSON_Delete(cjson_metric); + n_line++; + } + fclose(fp); + EXPECT_EQ(n_line, n_loops); + + fieldstat_global_disable_prometheus_endpoint(); + fieldstat_instance_free(instance); + +} + + +int main(int argc, char *argv[]) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}
\ No newline at end of file |
