diff options
| author | fumingwei <[email protected]> | 2023-09-07 18:38:18 +0800 |
|---|---|---|
| committer | fumingwei <[email protected]> | 2023-09-07 18:38:18 +0800 |
| commit | 6b814df254290b8d24fac50d8040441807c8e80b (patch) | |
| tree | 28420ceb9ee6d5994f3bd38a2759ac9abf9a7830 | |
| parent | 7509a711cf291cebb9340258f564f0e470ba4640 (diff) | |
temp commit 8
| -rw-r--r-- | include/fieldstat/fieldstat.h | 2 | ||||
| -rw-r--r-- | include/fieldstat/fieldstat_exporter.h | 2 | ||||
| -rw-r--r-- | src/exporter/exporter.c | 7 | ||||
| -rw-r--r-- | src/exporter/exporter_internal.h | 2 | ||||
| -rw-r--r-- | src/exporter/prometheus_exporter.c | 244 | ||||
| -rw-r--r-- | src/fieldstat.c | 20 | ||||
| -rw-r--r-- | src/metrics/metric.c | 30 | ||||
| -rw-r--r-- | src/metrics/metric.h | 3 | ||||
| -rw-r--r-- | test/test_exporter_prometheus.cpp | 294 |
9 files changed, 447 insertions, 157 deletions
diff --git a/include/fieldstat/fieldstat.h b/include/fieldstat/fieldstat.h index 6d078c0..9ea2d5f 100644 --- a/include/fieldstat/fieldstat.h +++ b/include/fieldstat/fieldstat.h @@ -243,6 +243,8 @@ int fieldstat_get_max_cell_num(const struct fieldstat *instance, int cube_id); long long fieldstat_counter_get(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id); double fieldstat_hll_get(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id); long long fieldstat_hist_value_at_percentile(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id, double percentile); +long long fieldstat_hist_value_total_count(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id); +long long fieldstat_hist_value_sum(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id); long long fieldstat_hist_count_le_value(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id, long long value); // get the base 64 encoded string of the serialized blob of a cell diff --git a/include/fieldstat/fieldstat_exporter.h b/include/fieldstat/fieldstat_exporter.h index 2f2b69c..784e932 100644 --- a/include/fieldstat/fieldstat_exporter.h +++ b/include/fieldstat/fieldstat_exporter.h @@ -77,8 +77,6 @@ int fieldstat_exporter_merge_fieldstat(struct fieldstat_exporter *exporter, int fieldstat_exporter_local_export(struct fieldstat_exporter *exporter, struct fieldstat *instance); -int fieldstat_exporter_prometheus_export(struct fieldstat_exporter *exporter, - struct fieldstat *instance); /* -------------------------------------------------------------------------- */ /* fieldstat_json_exporter */ /* -------------------------------------------------------------------------- */ diff --git a/src/exporter/exporter.c b/src/exporter/exporter.c index d1b8398..36d5173 100644 --- a/src/exporter/exporter.c +++ b/src/exporter/exporter.c @@ -91,6 +91,8 @@ struct fieldstat_exporter *fieldstat_exporter_new(const char *name, memcpy((void *)exporter->tags, (const void *)tags, sizeof(struct fieldstat_tag) * n_tags); exporter->n_tags = n_tags; + pthread_spin_init(&(exporter->lock), PTHREAD_PROCESS_SHARED); + return exporter; } @@ -120,6 +122,8 @@ void fieldstat_exporter_free(struct fieldstat_exporter *exporter) exporter->n_tags = 0; } + pthread_spin_destroy(&(exporter->lock)); + free(exporter); exporter = NULL; } @@ -236,8 +240,9 @@ int fieldstat_exporter_merge_fieldstat(struct fieldstat_exporter *exporter, return -1; } } - + pthread_spin_lock(&(exporter->lock)); ret = fieldstat_merge(exporter->accumulated, exporter->changing); + pthread_spin_unlock(&(exporter->lock)); if(ret == -1) { fieldstat_reset(exporter->changing); diff --git a/src/exporter/exporter_internal.h b/src/exporter/exporter_internal.h index eddb81d..e3e06bb 100644 --- a/src/exporter/exporter_internal.h +++ b/src/exporter/exporter_internal.h @@ -35,6 +35,8 @@ struct fieldstat_exporter struct fieldstat *changing; struct fieldstat *accumulated; + pthread_spinlock_t lock; + char local_exporter_filename[MAX_PATH_LEN]; int enable_local_exporter; diff --git a/src/exporter/prometheus_exporter.c b/src/exporter/prometheus_exporter.c index 28588bf..911844f 100644 --- a/src/exporter/prometheus_exporter.c +++ b/src/exporter/prometheus_exporter.c @@ -177,8 +177,8 @@ static char* str_unescape(char* s, char *d, int d_len) } -static int build_payload_append_metric_name(char *metric_name, char *exporter_name, - char *buf, size_t size) +static int build_metric_name_buf(char *metric_name, char *exporter_name, + char *buf, size_t size) { char unescape[256] = {0}; int used = 0; @@ -199,54 +199,44 @@ static int covert_tags_to_string(struct fieldstat_tag *tags, size_t n_tags, for(int i = 0; i < n_tags; i++) { memset(unescape, 0, sizeof(unescape)); - + str_unescape((char *)tags[i].key, unescape, sizeof(unescape)); switch(tags[i].type) { case TAG_INTEGER: - used += snprintf(buf + used, size - used, "%s=\"%lld\",", - tags[i].key, tags[i].value_longlong); + used += snprintf(buf + used, size - used, ",%s=\"%lld\"", + unescape, tags[i].value_longlong); break; case TAG_DOUBLE: - used += snprintf(buf + used, size - used, "%s=\"%lf\",", - tags[i].key, tags[i].value_double); + used += snprintf(buf + used, size - used, ",%s=\"%lf\"", + unescape, tags[i].value_double); break; case TAG_CSTRING: - used += snprintf(buf + used, size - used, "%s=\"%s\",", - tags[i].key, tags[i].value_str); + used += snprintf(buf + used, size - used, ",%s=\"%s\"", + unescape, tags[i].value_str); break; default: assert(0); } } - // if(used > 0) - // { - // buf[used- 1] = '\0'; - // used --; - // } - return used; } -static int build_payload_append_global_tags(struct fieldstat_exporter *exporter, - char *buf, - size_t size) +static int build_global_tags_buf(struct fieldstat_exporter *exporter, char *buf, + size_t size) { int used = 0; - used += snprintf(buf, size - used, "app_name=\"%s\",", exporter->name); - used += covert_tags_to_string(exporter->tags, exporter->n_tags, - buf + used, size - used); - + used += snprintf(buf, size - used, "app_name=\"%s\"", exporter->name); + used += covert_tags_to_string(exporter->tags, exporter->n_tags, buf + used, + size - used); return used; } -static int build_payload_append_cube_tags(struct fieldstat *instance, - int cube_id, - char *buf, - size_t size) +static int build_cube_tags_buf(struct fieldstat *instance, int cube_id, + char *buf, size_t size) { int used = 0; struct fieldstat_tag_list *tags_list = NULL; @@ -258,10 +248,8 @@ static int build_payload_append_cube_tags(struct fieldstat *instance, } -static int build_payload_append_cell_tags(struct fieldstat_tag *tags, - size_t n_tags, - char *buf, - size_t size) +static int build_cell_tags_buf(struct fieldstat_tag *tags, size_t n_tags, + char *buf, size_t size) { int used = 0; @@ -271,151 +259,98 @@ static int build_payload_append_cell_tags(struct fieldstat_tag *tags, } -static int build_payload_append_metric_value(const struct fieldstat *instance, - enum metric_type metric_type, - int cube_id, - int metric_id, - int cell_id, - char *buf, - size_t size) -{ - int used = 0; - long long value = 0; - const char *quantiles = "0.1,0.5,0.8,0.9,0.95,0.99"; - const double quantiles[] = {0.1,0.5,0.8,0.9,0.95,0.99}; - const char *compared_p10 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.10\"} 10\n"; - const char *compared_p50 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.50\"} 50\n"; - const char *compared_p80 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.80\"} 80\n"; - const char *compared_p90 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.90\"} 90\n"; - const char *compared_p95 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.95\"} 95\n"; - const char *compared_p99 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.99\"} 99\n"; - const char *compared_cnt = "maat_hit_rate_count{app_name=\"maat\"} 100\n"; - const char *compared_sum = "maat_hit_rate_sum{app_name=\"maat\"} 5050\n"; - - switch(metric_type) - { - case METRIC_TYPE_COUNTER: - value = fieldstat_counter_get(instance, cube_id, metric_id, cell_id); - used += snprintf(buf, size - used, "%lld\n", value); - break; - case METRIC_TYPE_HLL: - break; - case METRIC_TYPE_HISTOGRAM: - for(int i = 0; i < sizeof(quantiles)/sizeof(quantiles[0]); i++) - { - value = - fieldstat_hist_value_at_percentile(instance, cube_id, metric_id, - cube_id, quantiles[i] * 100); - - used += snprintf(buf + used, size - used, "%lld\n", value); - } - break; - default: - assert(0); - break; - } - - return used; -} - - -int build_fieldstat_exporter_payload(struct fieldstat_exporter *exporter, - char **payload, - int *payload_size, +int build_fieldstat_exporter_payload(struct fieldstat_exporter *exporter, char **payload_buf, int *payload_size, int *payload_offset) { - int *cube_ids = NULL; - int n_cube = 0; + double quantiles[6] = {0.1, 0.5, 0.8, 0.9, 0.95, 0.99}; - int max_metric_id = 0; - char *metric_name = NULL; - enum metric_type metric_type; + pthread_spin_lock(&(exporter->lock)); struct fieldstat *instance = exporter->accumulated; - char *new_payload = *payload; - int new_payload_size = *payload_size; - int new_payload_offset = *payload_offset; + char *buf = *payload_buf; + int size = *payload_size; + int offset = *payload_offset; - char global_buf[512] = {0}; - int global_buf_offset = 0; + int *cube_ids = NULL; + int n_cube_ids = 0; - global_buf_offset += build_payload_append_global_tags(exporter, global_buf, - sizeof(global_buf)); - - fieldstat_get_cubes(instance, &cube_ids, &n_cube); - - if(n_cube == 0) + fieldstat_get_cubes(instance, &cube_ids, &n_cube_ids); + if(n_cube_ids == 0) { return -1; } - - for(int i = 0; i < n_cube; i++) + //part of one metric + char global_buf[512] = {0}; + build_global_tags_buf(exporter, global_buf, sizeof(global_buf)); + + for(int i = 0; i < n_cube_ids; i++) { - max_metric_id = fieldstat_get_max_metric_id(instance, cube_ids[i]); + int max_metric_id = fieldstat_get_max_metric_id(instance, cube_ids[i]); + //part of one metric + char cube_buf[512] = {0}; + build_cube_tags_buf(instance, cube_ids[i], cube_buf, sizeof(cube_buf)); for(int j = 0; j <= max_metric_id; j++) { int *cell_ids = NULL; size_t n_cell = 0; + + char name_buf[256] = {0}; + char cell_buf[512] = {0}; + struct fieldstat_tag_list *tags_list = NULL; + enum metric_type metric_type = fieldstat_get_metric_type(instance, cube_ids[i], j); - fieldstat_get_cells(instance, cube_ids[i], j, &cell_ids, &tags_list, - &n_cell); + char *metric_name = (char *)fieldstat_get_metric_name(instance, cube_ids[i], j); + //part of one metric + build_metric_name_buf(metric_name, exporter->name, name_buf, sizeof(name_buf)); + fieldstat_get_cells(instance, cube_ids[i], j, &cell_ids, &tags_list, &n_cell); + //part of one metric + build_cell_tags_buf(tags_list->tag, tags_list->n_tag, cell_buf, sizeof(cell_buf)); + for(int k = 0; k < n_cell; k++) { - payload_realloc(&new_payload, &new_payload_size, new_payload_offset); - - metric_name = (char *)fieldstat_get_metric_name(instance, cube_ids[i], j); - metric_type = fieldstat_get_metric_type(instance, cube_ids[i], j); + long long value = 0; + double hll_value = 0.0; + payload_realloc(&buf, &size, offset); - new_payload_offset += build_payload_append_metric_name( - metric_name, - exporter->name, - new_payload + new_payload_offset, - new_payload_size - new_payload_offset); - - new_payload_offset += snprintf( - new_payload + new_payload_offset, - new_payload_size - new_payload_offset, - "{"); - - new_payload_offset += build_payload_append_global_tags( - exporter, - new_payload + new_payload_offset, - new_payload_size - new_payload_offset); - - new_payload_offset += snprintf(new_payload + new_payload_offset,new_payload_size - new_payload_offset, "%s", - - - new_payload_offset += build_payload_append_cube_tags( - instance, - cube_ids[i], - new_payload + new_payload_offset, - new_payload_size - new_payload_offset); - - new_payload_offset += build_payload_append_cell_tags( - tags_list->tag, - tags_list->n_tag, - new_payload + new_payload_offset, - new_payload_size - new_payload_offset); - - if(new_payload[new_payload_offset - 1] == ',') + switch(metric_type) { - new_payload_offset--; + case METRIC_TYPE_COUNTER: + value = fieldstat_counter_get(instance, i, j, k); + offset += snprintf(buf + offset, size - offset, "%s{%s%s%s} %lld\n", + name_buf, global_buf, cube_buf, cell_buf, value); + break; + + case METRIC_TYPE_HLL: + hll_value = fieldstat_hll_get(instance, i, j, k); + offset += snprintf(buf + offset, size - offset, "%s_total_count{%s%s%s} %.0f\n", + name_buf, global_buf, cube_buf, cell_buf, hll_value); + break; + + case METRIC_TYPE_HISTOGRAM: + + for(int m = 0; m < sizeof(quantiles)/sizeof(quantiles[0]); m++) + { + value = fieldstat_hist_value_at_percentile(instance, i, j, k, quantiles[m] * 100); + offset += snprintf(buf + offset, size - offset, + "%s{%s%s%s,quantile=\"%0.2f\"} %lld\n", + name_buf, global_buf, cube_buf, cell_buf, quantiles[m], value); + } + + value = fieldstat_hist_value_total_count(instance, i, j, k); + offset += snprintf(buf + offset, size - offset, "%s_count{%s%s%s} %lld\n", + name_buf, global_buf, cube_buf, cell_buf, value); + + value = fieldstat_hist_value_sum(instance, i, j, k); + offset += snprintf(buf + offset, size - offset, "%s_sum{%s%s%s} %lld\n", + name_buf, global_buf, cube_buf, cell_buf, value); + break; + default: + assert(0); + break; } - - new_payload_offset += snprintf( - new_payload + new_payload_offset, - new_payload_size - new_payload_offset, - "} "); - - new_payload_offset += build_payload_append_metric_value( - instance, - metric_type, - i, j, k, - new_payload + new_payload_offset, - new_payload_size - new_payload_offset); } if(cell_ids) @@ -433,10 +368,11 @@ int build_fieldstat_exporter_payload(struct fieldstat_exporter *exporter, free(cube_ids); cube_ids = NULL; } + pthread_spin_unlock(&(exporter->lock)); - *payload = new_payload; - *payload_size = new_payload_size; - *payload_offset = new_payload_offset; + *payload_buf = buf; + *payload_size = size; + *payload_offset = offset; return 0; } diff --git a/src/fieldstat.c b/src/fieldstat.c index 19846d5..12ab2ed 100644 --- a/src/fieldstat.c +++ b/src/fieldstat.c @@ -1029,6 +1029,26 @@ long long fieldstat_hist_value_at_percentile(const struct fieldstat *instance, i return metric_histogram_value_at_percentile(metric, cell_id, percentile); } +long long fieldstat_hist_value_total_count(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id) +{ + const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id); + if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_HISTOGRAM) { + return -1; + } + + return metric_histogram_value_total_count(metric, cell_id); +} + +long long fieldstat_hist_value_sum(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id) +{ + const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id); + if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_HISTOGRAM) { + return -1; + } + + return metric_histogram_value_sum(metric, cell_id); +} + long long fieldstat_hist_count_le_value(const struct fieldstat *instance, int cube_id, int metric_id, int cell_id, long long value) { const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id); diff --git a/src/metrics/metric.c b/src/metrics/metric.c index 0b6c025..335ee2b 100644 --- a/src/metrics/metric.c +++ b/src/metrics/metric.c @@ -815,6 +815,36 @@ long long metric_histogram_value_at_percentile(const struct metric *pthis, int c return hdr_value_at_percentile(data->hdr, percentile); } + +long long metric_histogram_value_total_count(const struct metric *pthis, int cell_id) +{ + const struct metric_measure_data *data = metric_find_one_cell(pthis, cell_id); + if (data == NULL) { + return -1; + } + return (long long)data->hdr->total_count; +} + +long long metric_histogram_value_sum(const struct metric *pthis, int cell_id) +{ + const struct metric_measure_data *data = metric_find_one_cell(pthis, cell_id); + if (data == NULL) { + return -1; + } + + struct hdr_iter iter; + long long sum = 0; + + hdr_iter_recorded_init(&iter, data->hdr); + while (hdr_iter_next(&iter)) + { + sum+=(long long)iter.value; + } + return sum; +} + + + static long long hdr_count_le_value(const struct hdr_histogram* h, long long value) { struct hdr_iter iter; diff --git a/src/metrics/metric.h b/src/metrics/metric.h index 6122746..17da701 100644 --- a/src/metrics/metric.h +++ b/src/metrics/metric.h @@ -33,6 +33,9 @@ struct metric *metric_histogram_new(const char *name, long long lowest_trackable int metric_histogram_record(struct metric *pthis, int cell_id, long long value); // for the meaning of these two query method, refer to https://prometheus.io/docs/concepts/metric_types/, and search for "histogram" and "summary" long long metric_histogram_value_at_percentile(const struct metric *pthis, int cell_id, double percentile); +long long metric_histogram_value_total_count(const struct metric *pthis, int cell_id); +long long metric_histogram_value_sum(const struct metric *pthis, int cell_id); + long long metric_histogram_count_le_value(const struct metric *pthis, int cell_id, long long value); diff --git a/test/test_exporter_prometheus.cpp b/test/test_exporter_prometheus.cpp index c19466d..656a1f3 100644 --- a/test/test_exporter_prometheus.cpp +++ b/test/test_exporter_prometheus.cpp @@ -548,6 +548,300 @@ TEST(ExporterPrometheus, AllTags) } +/******************************************************************************* + * case: MetricTypeCounter +*******************************************************************************/ +static struct fieldstat *test_new_exporter_MetricTypeCounter() +{ + struct fieldstat *instance = fieldstat_new(); + EXPECT_NE(nullptr, instance); + + int cube_id = fieldstat_register_cube(instance, NULL, 0, + SAMPLING_MODE_COMPREHENSIVE, 3); + EXPECT_EQ(0, cube_id); + + int counter_id = fieldstat_register_counter(instance, cube_id, "Traffic_bytes", + COUNTER_MERGE_BY_SUM); + + int cell_id = fieldstat_cube_add(instance, cube_id, NULL, 0, 1); + EXPECT_EQ(0, cell_id); + + if(cell_id >= 0) + { + fieldstat_counter_incrby(instance, cube_id, counter_id, cell_id, 1); + } + + return instance; +} + +static void test_analyze_MetricTypeCounter() +{ + int n_line = 0; + char buffer[512]; + const char *desired = "firewall_Traffic_bytes{app_name=\"firewall\"} 1\n"; + + FILE *fp = fopen("/tmp/prometheus.txt", "r"); + EXPECT_NE(nullptr, fp); + + while(fgets(buffer, sizeof(buffer), fp) != NULL) + { + n_line++; + } + fclose(fp); + + EXPECT_EQ(1, n_line); + EXPECT_STREQ(desired, buffer); + + return; +} + + +TEST(ExporterPrometheus, MetricTypeCounter) +{ + int ret = 0; + unsigned short port = 40009; + struct fieldstat_exporter *exporter = NULL; + struct fieldstat *instance = NULL; + // input start + const char *exporter_name = "firewall"; + + exporter = fieldstat_exporter_new(exporter_name, NULL, 0); + EXPECT_NE(nullptr, exporter); + + ret = fieldstat_exporter_enable_prometheus_exporter(exporter); + EXPECT_EQ(0, ret); + + ret = fieldstat_exporter_global_enable_prometheus_endpoint(port, "/metrics"); + EXPECT_EQ(0, ret); + + fieldstat_exporter_start(exporter); + + instance = test_new_exporter_MetricTypeCounter(); + + ret = fieldstat_exporter_merge_fieldstat(exporter, &instance, 1); + EXPECT_EQ(0, ret); + + //test function start + sleep(1); + test_pull_metrics_request(port, "/metrics"); + test_analyze_MetricTypeCounter(); + sleep(1); + //test function end + + fieldstat_exporter_free(exporter); + fieldstat_free(instance); + fieldstat_exporter_global_disable_prometheus_endpoint(); +} + +/******************************************************************************* + * case: MetricTypeHistogram +*******************************************************************************/ + +//maat_hit_rate{app_name=\"maat\",quantile=\"0.10\"} 20\n +static struct fieldstat *test_new_exporter_MetricTypeHistogram() +{ + struct fieldstat *instance = fieldstat_new(); + EXPECT_NE(nullptr, instance); + + int cube_id = fieldstat_register_cube(instance, NULL, 0, + SAMPLING_MODE_COMPREHENSIVE, 3); + EXPECT_EQ(0, cube_id); + + int metric_id = fieldstat_register_hist(instance, cube_id, "hit_rate", 1, 100, 3); + EXPECT_EQ(metric_id, 0); + + int cell_id = fieldstat_cube_add(instance, cube_id, NULL, 0, 1); + EXPECT_EQ(0, cell_id); + + for(int i = 0; i < 100; i++) + { + fieldstat_hist_record(instance, cube_id, metric_id, cell_id, i + 1); + } + + return instance; +} + +static void test_analyze_MetricTypeHistogram() +{ + int n_line = 0; + char buffer[512]; + + const char *desired_p10 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.10\"} 10\n"; + const char *desired_p50 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.50\"} 50\n"; + const char *desired_p80 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.80\"} 80\n"; + const char *desired_p90 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.90\"} 90\n"; + const char *desired_p95 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.95\"} 95\n"; + const char *desired_p99 = "maat_hit_rate{app_name=\"maat\",quantile=\"0.99\"} 99\n"; + const char *desired_cnt = "maat_hit_rate_count{app_name=\"maat\"} 100\n"; + const char *desired_sum = "maat_hit_rate_sum{app_name=\"maat\"} 5050\n"; + + FILE *fp = fopen("/tmp/prometheus.txt", "r"); + EXPECT_NE(nullptr, fp); + + while(fgets(buffer, sizeof(buffer), fp) != NULL) + { + switch(n_line) + { + case 0: + EXPECT_STREQ(desired_p10, buffer); + break; + case 1: + EXPECT_STREQ(desired_p50, buffer); + break; + case 2: + EXPECT_STREQ(desired_p80, buffer); + break; + case 3: + EXPECT_STREQ(desired_p90, buffer); + break; + case 4: + EXPECT_STREQ(desired_p95, buffer); + break; + case 5: + EXPECT_STREQ(desired_p99, buffer); + break; + case 6: + EXPECT_STREQ(desired_cnt, buffer); + break; + case 7: + EXPECT_STREQ(desired_sum, buffer); + break; + default: + break; + } + n_line++; + } + fclose(fp); + + EXPECT_EQ(8, n_line); + + return; +} + + +TEST(ExporterPrometheus, MetricTypeHistogram) +{ + int ret = 0; + unsigned short port = 40010; + struct fieldstat_exporter *exporter = NULL; + struct fieldstat *instance = NULL; + // input start + const char *exporter_name = "maat"; + + exporter = fieldstat_exporter_new(exporter_name, NULL, 0); + EXPECT_NE(nullptr, exporter); + + ret = fieldstat_exporter_enable_prometheus_exporter(exporter); + EXPECT_EQ(0, ret); + + ret = fieldstat_exporter_global_enable_prometheus_endpoint(port, "/metrics"); + EXPECT_EQ(0, ret); + + fieldstat_exporter_start(exporter); + + instance = test_new_exporter_MetricTypeHistogram(); + + ret = fieldstat_exporter_merge_fieldstat(exporter, &instance, 1); + EXPECT_EQ(0, ret); + + //test function start + sleep(1); + test_pull_metrics_request(port, "/metrics"); + test_analyze_MetricTypeHistogram(); + sleep(1); + //test function end + + fieldstat_exporter_free(exporter); + fieldstat_free(instance); + fieldstat_exporter_global_disable_prometheus_endpoint(); +} + +/******************************************************************************* + * case: MetricTypeHyperloglog +*******************************************************************************/ + +static struct fieldstat *test_new_exporter_MetricTypeHyperloglog() +{ + struct fieldstat *instance = fieldstat_new(); + EXPECT_NE(nullptr, instance); + + int cube_id = fieldstat_register_cube(instance, NULL, 0, + SAMPLING_MODE_COMPREHENSIVE, 3); + EXPECT_EQ(0, cube_id); + + int metric_id = fieldstat_register_hll(instance, cube_id, "hit_policy", 10); + EXPECT_EQ(metric_id, 0); + + int cell_id = fieldstat_cube_add(instance, cube_id, NULL, 0, 1); + EXPECT_EQ(0, cell_id); + + fieldstat_hll_add(instance, cube_id, metric_id, cell_id, "192.168.1.1", 11); + fieldstat_hll_add(instance, cube_id, metric_id, cell_id, "192.168.1.2", 11); + fieldstat_hll_add(instance, cube_id, metric_id, cell_id, "192.168.1.3", 11); + fieldstat_hll_add(instance, cube_id, metric_id, cell_id, "192.168.1.4", 11); + fieldstat_hll_add(instance, cube_id, metric_id, cell_id, "192.168.1.5", 11); + + return instance; +} + +static void test_analyze_MetricTypeHyperloglog() +{ + int n_line = 0; + char buffer[512]; + const char *desired = "firewall_hit_policy_total_count{app_name=\"firewall\"} 5\n"; + FILE *fp = fopen("/tmp/prometheus.txt", "r"); + EXPECT_NE(nullptr, fp); + + while(fgets(buffer, sizeof(buffer), fp) != NULL) + { + n_line++; + } + fclose(fp); + + EXPECT_EQ(1, n_line); + EXPECT_STREQ(desired, buffer); + return; +} + + +TEST(ExporterPrometheus, MetricTypeHyperloglog) +{ + int ret = 0; + unsigned short port = 40011; + struct fieldstat_exporter *exporter = NULL; + struct fieldstat *instance = NULL; + // input start + const char *exporter_name = "firewall"; + + exporter = fieldstat_exporter_new(exporter_name, NULL, 0); + EXPECT_NE(nullptr, exporter); + + ret = fieldstat_exporter_enable_prometheus_exporter(exporter); + EXPECT_EQ(0, ret); + + ret = fieldstat_exporter_global_enable_prometheus_endpoint(port, "/metrics"); + EXPECT_EQ(0, ret); + + fieldstat_exporter_start(exporter); + + instance = test_new_exporter_MetricTypeHyperloglog(); + + ret = fieldstat_exporter_merge_fieldstat(exporter, &instance, 1); + EXPECT_EQ(0, ret); + + //test function start + sleep(1); + test_pull_metrics_request(port, "/metrics"); + test_analyze_MetricTypeHyperloglog(); + sleep(1); + //test function end + + fieldstat_exporter_free(exporter); + fieldstat_free(instance); + fieldstat_exporter_global_disable_prometheus_endpoint(); +} + + int main(int argc, char *argv[]) { testing::InitGoogleTest(&argc, argv); |
