diff --git a/lib/cmetrics/CMakeLists.txt b/lib/cmetrics/CMakeLists.txt index 1041f6d295d..68dd66e507c 100644 --- a/lib/cmetrics/CMakeLists.txt +++ b/lib/cmetrics/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # CMetrics Version set(CMT_VERSION_MAJOR 0) set(CMT_VERSION_MINOR 9) -set(CMT_VERSION_PATCH 0) +set(CMT_VERSION_PATCH 1) set(CMT_VERSION_STR "${CMT_VERSION_MAJOR}.${CMT_VERSION_MINOR}.${CMT_VERSION_PATCH}") # Include helpers diff --git a/lib/cmetrics/include/cmetrics/cmt_cat.h b/lib/cmetrics/include/cmetrics/cmt_cat.h index d393baed34e..15d4b9db783 100644 --- a/lib/cmetrics/include/cmetrics/cmt_cat.h +++ b/lib/cmetrics/include/cmetrics/cmt_cat.h @@ -28,11 +28,13 @@ struct cmt_untyped; struct cmt_histogram; struct cmt_summary; -int cmt_cat_counter(struct cmt *cmt, struct cmt_counter *counter); -int cmt_cat_gauge(struct cmt *cmt, struct cmt_gauge *gauge); -int cmt_cat_untyped(struct cmt *cmt, struct cmt_untyped *untyped); -int cmt_cat_histogram(struct cmt *cmt, struct cmt_histogram *histogram); -int cmt_cat_summary(struct cmt *cmt, struct cmt_summary *summary); +int cmt_cat_copy_label_keys(struct cmt_map *map, char **out); +int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map *src); +int cmt_cat_counter(struct cmt *cmt, struct cmt_counter *counter, struct cmt_map *filtered_map); +int cmt_cat_gauge(struct cmt *cmt, struct cmt_gauge *gauge, struct cmt_map *filtered_map); +int cmt_cat_untyped(struct cmt *cmt, struct cmt_untyped *untyped, struct cmt_map *filtered_map); +int cmt_cat_histogram(struct cmt *cmt, struct cmt_histogram *histogram, struct cmt_map *filtered_map); +int cmt_cat_summary(struct cmt *cmt, struct cmt_summary *summary, struct cmt_map *filtered_map); int cmt_cat(struct cmt *dst, struct cmt *src); #endif diff --git a/lib/cmetrics/include/cmetrics/cmt_filter.h b/lib/cmetrics/include/cmetrics/cmt_filter.h index 7676cbf5c3d..0ecf2d2a702 100644 --- a/lib/cmetrics/include/cmetrics/cmt_filter.h +++ b/lib/cmetrics/include/cmetrics/cmt_filter.h @@ -38,4 +38,8 @@ int cmt_filter(struct cmt *dst, struct cmt *src, void *compare_ctx, int (*compare)(void *compare_ctx, const char *str, size_t slen), int flags); +int cmt_filter_with_label_pair(struct cmt *dst, struct cmt *src, + const char *label_key, + const char *label_value); + #endif diff --git a/lib/cmetrics/include/cmetrics/cmt_map.h b/lib/cmetrics/include/cmetrics/cmt_map.h index 33694315cca..f67ee15547b 100644 --- a/lib/cmetrics/include/cmetrics/cmt_map.h +++ b/lib/cmetrics/include/cmetrics/cmt_map.h @@ -55,6 +55,7 @@ struct cmt_metric *cmt_map_metric_get(struct cmt_opts *opts, struct cmt_map *map int cmt_map_metric_get_val(struct cmt_opts *opts, struct cmt_map *map, int labels_count, char **labels_val, double *out_val); +void cmt_map_metric_destroy(struct cmt_metric *metric); void destroy_label_list(struct cfl_list *label_list); diff --git a/lib/cmetrics/src/cmt_cat.c b/lib/cmetrics/src/cmt_cat.c index 5bb09cb2d75..af95dcbd73d 100644 --- a/lib/cmetrics/src/cmt_cat.c +++ b/lib/cmetrics/src/cmt_cat.c @@ -26,7 +26,7 @@ #include #include -static int copy_label_keys(struct cmt_map *map, char **out) +int cmt_cat_copy_label_keys(struct cmt_map *map, char **out) { int i; int s; @@ -96,7 +96,7 @@ static int copy_label_values(struct cmt_metric *metric, char **out) return i; } -static int copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map *src) +int cmt_cat_copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map *src) { int i; int c; @@ -213,7 +213,8 @@ static int copy_map(struct cmt_opts *opts, struct cmt_map *dst, struct cmt_map * } -int cmt_cat_counter(struct cmt *cmt, struct cmt_counter *counter) +int cmt_cat_counter(struct cmt *cmt, struct cmt_counter *counter, + struct cmt_map *filtered_map) { int ret; char **labels = NULL; @@ -224,7 +225,7 @@ int cmt_cat_counter(struct cmt *cmt, struct cmt_counter *counter) map = counter->map; opts = map->opts; - ret = copy_label_keys(map, (char **) &labels); + ret = cmt_cat_copy_label_keys(map, (char **) &labels); if (ret == -1) { return -1; } @@ -240,15 +241,24 @@ int cmt_cat_counter(struct cmt *cmt, struct cmt_counter *counter) return -1; } - ret = copy_map(&c->opts, c->map, map); - if (ret == -1) { - return -1; + if (filtered_map != NULL) { + ret = cmt_cat_copy_map(&c->opts, c->map, filtered_map); + if (ret == -1) { + return -1; + } + } + else { + ret = cmt_cat_copy_map(&c->opts, c->map, map); + if (ret == -1) { + return -1; + } } return 0; } -int cmt_cat_gauge(struct cmt *cmt, struct cmt_gauge *gauge) +int cmt_cat_gauge(struct cmt *cmt, struct cmt_gauge *gauge, + struct cmt_map *filtered_map) { int ret; char **labels = NULL; @@ -259,7 +269,7 @@ int cmt_cat_gauge(struct cmt *cmt, struct cmt_gauge *gauge) map = gauge->map; opts = map->opts; - ret = copy_label_keys(map, (char **) &labels); + ret = cmt_cat_copy_label_keys(map, (char **) &labels); if (ret == -1) { return -1; } @@ -274,15 +284,24 @@ int cmt_cat_gauge(struct cmt *cmt, struct cmt_gauge *gauge) return -1; } - ret = copy_map(&g->opts, g->map, map); - if (ret == -1) { - return -1; + if (filtered_map != NULL) { + ret = cmt_cat_copy_map(&g->opts, g->map, filtered_map); + if (ret == -1) { + return -1; + } + } + else { + ret = cmt_cat_copy_map(&g->opts, g->map, map); + if (ret == -1) { + return -1; + } } return 0; } -int cmt_cat_untyped(struct cmt *cmt, struct cmt_untyped *untyped) +int cmt_cat_untyped(struct cmt *cmt, struct cmt_untyped *untyped, + struct cmt_map *filtered_map) { int ret; char **labels = NULL; @@ -293,7 +312,7 @@ int cmt_cat_untyped(struct cmt *cmt, struct cmt_untyped *untyped) map = untyped->map; opts = map->opts; - ret = copy_label_keys(map, (char **) &labels); + ret = cmt_cat_copy_label_keys(map, (char **) &labels); if (ret == -1) { return -1; } @@ -308,15 +327,24 @@ int cmt_cat_untyped(struct cmt *cmt, struct cmt_untyped *untyped) return -1; } - ret = copy_map(&u->opts, u->map, map); - if (ret == -1) { - return -1; + if (filtered_map != NULL) { + ret = cmt_cat_copy_map(&u->opts, u->map, filtered_map); + if (ret == -1) { + return -1; + } + } + else { + ret = cmt_cat_copy_map(&u->opts, u->map, map); + if (ret == -1) { + return -1; + } } return 0; } -int cmt_cat_histogram(struct cmt *cmt, struct cmt_histogram *histogram) +int cmt_cat_histogram(struct cmt *cmt, struct cmt_histogram *histogram, + struct cmt_map *filtered_map) { int i; double val; @@ -333,7 +361,7 @@ int cmt_cat_histogram(struct cmt *cmt, struct cmt_histogram *histogram) opts = map->opts; timestamp = cmt_metric_get_timestamp(&map->metric); - ret = copy_label_keys(map, (char **) &labels); + ret = cmt_cat_copy_label_keys(map, (char **) &labels); if (ret == -1) { return -1; } @@ -354,15 +382,24 @@ int cmt_cat_histogram(struct cmt *cmt, struct cmt_histogram *histogram) return -1; } - ret = copy_map(&hist->opts, hist->map, map); - if (ret == -1) { - return -1; + if (filtered_map != NULL) { + ret = cmt_cat_copy_map(&hist->opts, hist->map, filtered_map); + if (ret == -1) { + return -1; + } + } + else { + ret = cmt_cat_copy_map(&hist->opts, hist->map, map); + if (ret == -1) { + return -1; + } } return 0; } -int cmt_cat_summary(struct cmt *cmt, struct cmt_summary *summary) +int cmt_cat_summary(struct cmt *cmt, struct cmt_summary *summary, + struct cmt_map *filtered_map) { int i; int ret; @@ -378,7 +415,7 @@ int cmt_cat_summary(struct cmt *cmt, struct cmt_summary *summary) opts = map->opts; timestamp = cmt_metric_get_timestamp(&map->metric); - ret = copy_label_keys(map, (char **) &labels); + ret = cmt_cat_copy_label_keys(map, (char **) &labels); if (ret == -1) { return -1; } @@ -405,9 +442,17 @@ int cmt_cat_summary(struct cmt *cmt, struct cmt_summary *summary) free(labels); free(quantiles); - ret = copy_map(&sum->opts, sum->map, map); - if (ret == -1) { - return -1; + if (filtered_map != NULL) { + ret = cmt_cat_copy_map(&sum->opts, sum->map, filtered_map); + if (ret == -1) { + return -1; + } + } + else { + ret = cmt_cat_copy_map(&sum->opts, sum->map, map); + if (ret == -1) { + return -1; + } } return 0; @@ -426,7 +471,7 @@ static int append_context(struct cmt *dst, struct cmt *src) /* Counters */ cfl_list_foreach(head, &src->counters) { counter = cfl_list_entry(head, struct cmt_counter, _head); - ret = cmt_cat_counter(dst, counter); + ret = cmt_cat_counter(dst, counter, NULL); if (ret == -1) { return -1; } @@ -435,7 +480,7 @@ static int append_context(struct cmt *dst, struct cmt *src) /* Gauges */ cfl_list_foreach(head, &src->gauges) { gauge = cfl_list_entry(head, struct cmt_gauge, _head); - ret = cmt_cat_gauge(dst, gauge); + ret = cmt_cat_gauge(dst, gauge, NULL); if (ret == -1) { return -1; } @@ -444,7 +489,7 @@ static int append_context(struct cmt *dst, struct cmt *src) /* Untyped */ cfl_list_foreach(head, &src->untypeds) { untyped = cfl_list_entry(head, struct cmt_untyped, _head); - ret = cmt_cat_untyped(dst, untyped); + ret = cmt_cat_untyped(dst, untyped, NULL); if (ret == -1) { return -1; } @@ -453,7 +498,7 @@ static int append_context(struct cmt *dst, struct cmt *src) /* Histogram */ cfl_list_foreach(head, &src->histograms) { histogram = cfl_list_entry(head, struct cmt_histogram, _head); - ret = cmt_cat_histogram(dst, histogram); + ret = cmt_cat_histogram(dst, histogram, NULL); if (ret == -1) { return -1; } @@ -462,7 +507,7 @@ static int append_context(struct cmt *dst, struct cmt *src) /* Summary */ cfl_list_foreach(head, &src->summaries) { summary = cfl_list_entry(head, struct cmt_summary, _head); - ret = cmt_cat_summary(dst, summary); + ret = cmt_cat_summary(dst, summary, NULL); if (ret == -1) { return -1; } diff --git a/lib/cmetrics/src/cmt_filter.c b/lib/cmetrics/src/cmt_filter.c index 55bfc07098c..52f7648d9e3 100644 --- a/lib/cmetrics/src/cmt_filter.c +++ b/lib/cmetrics/src/cmt_filter.c @@ -97,7 +97,7 @@ static int filter_context_label_key(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_counter(dst, counter); + ret = cmt_cat_counter(dst, counter, NULL); if (ret == -1) { return -1; } @@ -111,7 +111,7 @@ static int filter_context_label_key(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_gauge(dst, gauge); + ret = cmt_cat_gauge(dst, gauge, NULL); if (ret == -1) { return -1; } @@ -125,7 +125,7 @@ static int filter_context_label_key(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_untyped(dst, untyped); + ret = cmt_cat_untyped(dst, untyped, NULL); if (ret == -1) { return -1; } @@ -139,7 +139,7 @@ static int filter_context_label_key(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_histogram(dst, histogram); + ret = cmt_cat_histogram(dst, histogram, NULL); if (ret == -1) { return -1; } @@ -153,7 +153,7 @@ static int filter_context_label_key(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_summary(dst, summary); + ret = cmt_cat_summary(dst, summary, NULL); if (ret == -1) { return -1; } @@ -162,6 +162,300 @@ static int filter_context_label_key(struct cmt *dst, struct cmt *src, return CMT_FILTER_SUCCESS; } +static int filter_get_label_index(struct cmt_map *src, const char *label_key) +{ + struct cfl_list *head; + struct cmt_map_label *label; + size_t index = 0; + + cfl_list_foreach(head, &src->label_keys) { + label = cfl_list_entry(head, struct cmt_map_label, _head); + if (strncmp(label->name, label_key, strlen(label->name)) == 0) { + return index; + } + + index++; + } + + return -1; +} + +int metrics_check_label_value_existence(struct cmt_metric *metric, + size_t label_index, + const char *label_value) +{ + struct cfl_list *iterator; + size_t index; + struct cmt_map_label *label = NULL; + + index = 0; + + cfl_list_foreach(iterator, &metric->labels) { + label = cfl_list_entry(iterator, struct cmt_map_label, _head); + + if (label_index == index) { + break; + } + + index++; + } + + if (label_index != index) { + return CMT_FALSE; + } + + if (label == NULL) { + return CMT_FALSE; + } + + if (label->name == NULL) { + return CMT_FALSE; + } + + if (strncmp(label->name, label_value, strlen(label->name)) == 0) { + return CMT_TRUE; + } + + return CMT_FALSE; +} + +static int metrics_map_drop_label_value_pairs(struct cmt_map *map, + size_t label_index, + const char *label_value) +{ + struct cfl_list *head; + struct cmt_metric *metric; + int result; + + result = CMT_FALSE; + + cfl_list_foreach(head, &map->metrics) { + metric = cfl_list_entry(head, struct cmt_metric, _head); + + result = metrics_check_label_value_existence(metric, + label_index, + label_value); + + if (result == CMT_TRUE) { + result = CMT_TRUE; + break; + } + } + + if (result == CMT_TRUE) { + cmt_map_metric_destroy(metric); + } + + return result; +} + +static int filter_context_label_key_value(struct cmt *dst, struct cmt *src, + const char *label_key, const char *label_value) +{ + int ret; + char **labels = NULL; + struct cfl_list *head; + struct cmt_map *map; + struct cmt_counter *counter; + struct cmt_gauge *gauge; + struct cmt_untyped *untyped; + struct cmt_histogram *histogram; + struct cmt_summary *summary; + size_t index = 0; + + /* Counters */ + cfl_list_foreach(head, &src->counters) { + counter = cfl_list_entry(head, struct cmt_counter, _head); + + ret = cmt_cat_copy_label_keys(counter->map, (char **) &labels); + if (ret == -1) { + return -1; + } + + map = cmt_map_create(CMT_COUNTER, &counter->opts, + counter->map->label_count, + labels, (void *) counter); + free(labels); + if (!map) { + cmt_log_error(src, "unable to allocate map for counter"); + return -1; + } + + ret = cmt_cat_copy_map(&counter->opts, map, counter->map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + index = filter_get_label_index(map, label_key); + if (index != -1) { + metrics_map_drop_label_value_pairs(map, index, label_value); + } + + ret = cmt_cat_counter(dst, counter, map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + cmt_map_destroy(map); + } + + /* Gauges */ + cfl_list_foreach(head, &src->gauges) { + gauge = cfl_list_entry(head, struct cmt_gauge, _head); + + ret = cmt_cat_copy_label_keys(gauge->map, (char **) &labels); + if (ret == -1) { + return -1; + } + + map = cmt_map_create(CMT_GAUGE, &gauge->opts, + gauge->map->label_count, + labels, (void *) gauge); + free(labels); + if (!map) { + cmt_log_error(src, "unable to allocate map for gauge"); + return -1; + } + + ret = cmt_cat_copy_map(&gauge->opts, map, gauge->map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + index = filter_get_label_index(map, label_key); + if (index != -1) { + metrics_map_drop_label_value_pairs(map, index, label_value); + } + + ret = cmt_cat_gauge(dst, gauge, map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + cmt_map_destroy(map); + } + + /* Untyped */ + cfl_list_foreach(head, &src->untypeds) { + untyped = cfl_list_entry(head, struct cmt_untyped, _head); + + ret = cmt_cat_copy_label_keys(untyped->map, (char **) &labels); + if (ret == -1) { + return -1; + } + + map = cmt_map_create(CMT_UNTYPED, &gauge->opts, + untyped->map->label_count, + labels, (void *) untyped); + free(labels); + if (!map) { + cmt_log_error(src, "unable to allocate map for untyped"); + return -1; + } + + ret = cmt_cat_copy_map(&untyped->opts, map, untyped->map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + index = filter_get_label_index(map, label_key); + if (index != -1) { + metrics_map_drop_label_value_pairs(map, index, label_value); + } + + ret = cmt_cat_untyped(dst, untyped, map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + cmt_map_destroy(map); + } + + /* Histogram */ + cfl_list_foreach(head, &src->histograms) { + histogram = cfl_list_entry(head, struct cmt_histogram, _head); + + ret = cmt_cat_copy_label_keys(histogram->map, (char **) &labels); + if (ret == -1) { + return -1; + } + + map = cmt_map_create(CMT_HISTOGRAM, &histogram->opts, + histogram->map->label_count, + labels, (void *) histogram); + free(labels); + if (!map) { + cmt_log_error(src, "unable to allocate map for histogram"); + return -1; + } + + ret = cmt_cat_copy_map(&histogram->opts, map, histogram->map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + index = filter_get_label_index(map, label_key); + if (index != -1) { + metrics_map_drop_label_value_pairs(map, index, label_value); + } + + ret = cmt_cat_histogram(dst, histogram, map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + cmt_map_destroy(map); + } + + /* Summary */ + cfl_list_foreach(head, &src->summaries) { + summary = cfl_list_entry(head, struct cmt_summary, _head); + + ret = cmt_cat_copy_label_keys(summary->map, (char **) &labels); + if (ret == -1) { + return -1; + } + + map = cmt_map_create(CMT_SUMMARY, &summary->opts, + summary->map->label_count, + labels, (void *) summary); + free(labels); + if (!map) { + cmt_log_error(src, "unable to allocate map for summary"); + return -1; + } + + ret = cmt_cat_copy_map(&summary->opts, map, summary->map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + index = filter_get_label_index(map, label_key); + if (index != -1) { + metrics_map_drop_label_value_pairs(map, index, label_value); + } + + ret = cmt_cat_summary(dst, summary, map); + if (ret == -1) { + cmt_map_destroy(map); + return -1; + } + + cmt_map_destroy(map); + } + + return CMT_FILTER_SUCCESS; +} + static int compare_fqname(struct cmt_opts *src, const char *fqname, void *compare_ctx, int (*compare)(void *compare_ctx, const char *str, size_t slen), int flags) @@ -226,7 +520,7 @@ static int filter_context_fqname(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_counter(dst, counter); + ret = cmt_cat_counter(dst, counter, NULL); if (ret == -1) { return -1; } @@ -239,7 +533,7 @@ static int filter_context_fqname(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_gauge(dst, gauge); + ret = cmt_cat_gauge(dst, gauge, NULL); if (ret == -1) { return -1; } @@ -252,7 +546,7 @@ static int filter_context_fqname(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_untyped(dst, untyped); + ret = cmt_cat_untyped(dst, untyped, NULL); if (ret == -1) { return -1; } @@ -265,7 +559,7 @@ static int filter_context_fqname(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_histogram(dst, histogram); + ret = cmt_cat_histogram(dst, histogram, NULL); if (ret == -1) { return -1; } @@ -278,7 +572,7 @@ static int filter_context_fqname(struct cmt *dst, struct cmt *src, continue; } - ret = cmt_cat_summary(dst, summary); + ret = cmt_cat_summary(dst, summary, NULL); if (ret == -1) { return -1; } @@ -287,6 +581,39 @@ static int filter_context_fqname(struct cmt *dst, struct cmt *src, return CMT_FILTER_SUCCESS; } +int cmt_filter_with_label_pair(struct cmt *dst, struct cmt *src, + const char *label_key, + const char *label_value) +{ + int ret = CMT_FILTER_SUCCESS; + + if (!dst) { + return CMT_FILTER_INVALID_ARGUMENT; + } + + if (!src) { + return CMT_FILTER_INVALID_ARGUMENT; + } + + if (label_key == NULL) { + return CMT_FILTER_INVALID_ARGUMENT; + } + + if (label_value == NULL) { + return CMT_FILTER_INVALID_ARGUMENT; + } + + if (label_key != NULL && label_value != NULL) { + ret = filter_context_label_key_value(dst, src, label_key, label_value); + } + + if (ret != CMT_FILTER_SUCCESS) { + return CMT_FILTER_FAILED_OPERATION; + } + + return ret; +} + int cmt_filter(struct cmt *dst, struct cmt *src, const char *fqname, const char *label_key, void *compare_ctx, int (*compare)(void *compare_ctx, const char *str, size_t slen), diff --git a/lib/cmetrics/src/cmt_map.c b/lib/cmetrics/src/cmt_map.c index ab25bffb809..4639124a832 100644 --- a/lib/cmetrics/src/cmt_map.c +++ b/lib/cmetrics/src/cmt_map.c @@ -136,7 +136,7 @@ static struct cmt_metric *map_metric_create(uint64_t hash, return NULL; } -static void map_metric_destroy(struct cmt_metric *metric) +void cmt_map_metric_destroy(struct cmt_metric *metric) { struct cfl_list *tmp; struct cfl_list *head; @@ -270,7 +270,7 @@ void cmt_map_destroy(struct cmt_map *map) cfl_list_foreach_safe(head, tmp, &map->metrics) { metric = cfl_list_entry(head, struct cmt_metric, _head); - map_metric_destroy(metric); + cmt_map_metric_destroy(metric); } /* histogram and quantile allocation for static metric */ diff --git a/lib/cmetrics/tests/filter.c b/lib/cmetrics/tests/filter.c index aa727884add..45248fe5aa5 100644 --- a/lib/cmetrics/tests/filter.c +++ b/lib/cmetrics/tests/filter.c @@ -97,6 +97,9 @@ struct cmt *generate_filter_test_data() ts = cfl_time_now(); cmt_untyped_set(u, ts, 1.3, 2, (char *[]) {"localhost", "eth0"}); + ts = cfl_time_now(); + cmt_untyped_set(u, ts, 1.8, 2, (char *[]) {"dev", "enp1s0"}); + c = cmt_counter_create(cmt, "cmetrics", "test", "cat_counter", "second counter", 2, (char *[]) {"label1", "label2"}); TEST_CHECK(c != NULL); @@ -129,6 +132,12 @@ struct cmt *generate_filter_test_data() TEST_CHECK(h != NULL); ts = cfl_time_now(); + + for (i = 0; i < sizeof(hist_observe_values)/(sizeof(double)); i++) { + val = hist_observe_values[i]; + cmt_histogram_observe(h, ts, val, 1, (char *[]) {"another_hist"}); + } + for (i = 0; i < sizeof(hist_observe_values)/(sizeof(double)); i++) { val = hist_observe_values[i]; cmt_histogram_observe(h, ts, val, 1, (char *[]) {"my_label"}); @@ -151,7 +160,7 @@ struct cmt *generate_filter_test_data() r[4] = 5; r[5] = 6; - /* Create a gauge metric type */ + /* Create a summary metric type */ s = cmt_summary_create(cmt, "spring", "kafka_listener", "seconds", "Kafka Listener Timer", 6, q, @@ -308,7 +317,144 @@ void test_filter() cmt_destroy(cmt6); } +void test_filter_with_label_key_value_pairs() +{ + int ret; + cfl_sds_t text; + struct cmt *cmt; + struct cmt *cmt2; + struct cmt *cmt3; + struct cmt *cmt4; + struct cmt *cmt5; + struct cmt *cmt6; + char *label_key; + char *label_value; + char *tmp = NULL; + + cmt = generate_filter_test_data(); + + text = cmt_encode_text_create(cmt); + printf("[Not filtered] ====>\n%s\n", text); + + cmt_encode_text_destroy(text); + + cmt2 = cmt_create(); + TEST_CHECK(cmt2 != NULL); + + label_key = "label3"; + label_value = "tyu"; + + /* filter with label key-value */ + ret = cmt_filter_with_label_pair(cmt2, cmt, label_key, label_value); + TEST_CHECK(ret == 0); + /* check output (fqname) */ + text = cmt_encode_text_create(cmt2); + printf("[label matched with label key-value pair: \"%s\", \"%s\" ] ====>\n%s\n", + label_key, label_value, text); + + tmp = strstr(text, "label3=\"tyu\""); + TEST_CHECK(tmp == NULL); + tmp = strstr(text, "label3=\"yyy\""); + TEST_CHECK(tmp != NULL); + + cmt_encode_text_destroy(text); + + cmt3 = cmt_create(); + TEST_CHECK(cmt3 != NULL); + + label_key = "label1"; + label_value = "aaa"; + + /* filter with label key-value */ + ret = cmt_filter_with_label_pair(cmt3, cmt, label_key, label_value); + TEST_CHECK(ret == 0); + /* check output (fqname) */ + text = cmt_encode_text_create(cmt3); + printf("[label matched with label key-value pair: \"%s\", \"%s\" ] ====>\n%s\n", + label_key, label_value, text); + + tmp = strstr(text, "label1=\"aaa\""); + TEST_CHECK(tmp == NULL); + tmp = strstr(text, "label1=\"ccc\""); + TEST_CHECK(tmp != NULL); + + cmt_encode_text_destroy(text); + + cmt4 = cmt_create(); + TEST_CHECK(cmt4 != NULL); + + label_key = "net"; + label_value = "enp1s0"; + + /* filter with label key-value */ + ret = cmt_filter_with_label_pair(cmt4, cmt, label_key, label_value); + TEST_CHECK(ret == 0); + /* check output (fqname) */ + text = cmt_encode_text_create(cmt4); + printf("[label matched with label key-value pair: \"%s\", \"%s\" ] ====>\n%s\n", + label_key, label_value, text); + + tmp = strstr(text, "net=\"enp1s0\""); + TEST_CHECK(tmp == NULL); + tmp = strstr(text, "net=\"eth0\""); + TEST_CHECK(tmp != NULL); + + cmt_encode_text_destroy(text); + + cmt5 = cmt_create(); + TEST_CHECK(cmt5 != NULL); + + label_key = "exception"; + label_value = "none"; + + /* filter with label key-value */ + ret = cmt_filter_with_label_pair(cmt5, cmt, label_key, label_value); + TEST_CHECK(ret == 0); + /* check output (fqname) */ + text = cmt_encode_text_create(cmt5); + printf("[label matched with label key-value pair: \"%s\", \"%s\" ] ====>\n%s\n", + label_key, label_value, text); + + tmp = strstr(text, "exception=\"none\""); + TEST_CHECK(tmp == NULL); + tmp = strstr(text, "net=\"eth0\""); + TEST_CHECK(tmp != NULL); + + cmt_encode_text_destroy(text); + + cmt6 = cmt_create(); + TEST_CHECK(cmt6 != NULL); + + label_key = "my_label"; + label_value = "another_hist"; + + /* filter with label key-value */ + ret = cmt_filter_with_label_pair(cmt6, cmt, label_key, label_value); + TEST_CHECK(ret == 0); + /* check output (fqname) */ + text = cmt_encode_text_create(cmt6); + printf("[label matched with label key-value pair: \"%s\", \"%s\" ] ====>\n%s\n", + label_key, label_value, text); + + tmp = strstr(text, "my_label=\"another_hist\""); + TEST_CHECK(tmp == NULL); + tmp = strstr(text, "my_label=\"my_label\""); + TEST_CHECK(tmp != NULL); + + cmt_encode_text_destroy(text); + + /* destroy contexts */ + cmt_destroy(cmt); + cmt_destroy(cmt2); + cmt_destroy(cmt3); + cmt_destroy(cmt4); + cmt_destroy(cmt5); + cmt_destroy(cmt6); +} + + TEST_LIST = { {"filter", test_filter}, + {"filter_with_label_pair", test_filter_with_label_key_value_pairs}, { 0 } };