Skip to content

Commit f6770ef

Browse files
committed
filter: Implement label key-value filtering
Signed-off-by: Hiroshi Hatake <[email protected]>
1 parent f0b16e9 commit f6770ef

File tree

2 files changed

+331
-0
lines changed

2 files changed

+331
-0
lines changed

include/cmetrics/cmt_filter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,8 @@ int cmt_filter(struct cmt *dst, struct cmt *src,
3838
void *compare_ctx, int (*compare)(void *compare_ctx, const char *str, size_t slen),
3939
int flags);
4040

41+
int cmt_filter_with_label_pair(struct cmt *dst, struct cmt *src,
42+
const char *label_key,
43+
const char *label_value);
44+
4145
#endif

src/cmt_filter.c

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,300 @@ static int filter_context_label_key(struct cmt *dst, struct cmt *src,
162162
return CMT_FILTER_SUCCESS;
163163
}
164164

165+
static int filter_get_label_index(struct cmt_map *src, const char *label_key)
166+
{
167+
struct cfl_list *head;
168+
struct cmt_map_label *label;
169+
size_t index = 0;
170+
171+
cfl_list_foreach(head, &src->label_keys) {
172+
label = cfl_list_entry(head, struct cmt_map_label, _head);
173+
if (strcasecmp(label->name, label_key) == 0) {
174+
return index;
175+
}
176+
177+
index++;
178+
}
179+
180+
return -1;
181+
}
182+
183+
int metrics_check_label_value_existence(struct cmt_metric *metric,
184+
size_t label_index,
185+
const char *label_value)
186+
{
187+
struct cfl_list *iterator;
188+
size_t index;
189+
struct cmt_map_label *label = NULL;
190+
191+
index = 0;
192+
193+
cfl_list_foreach(iterator, &metric->labels) {
194+
label = cfl_list_entry(iterator, struct cmt_map_label, _head);
195+
196+
if (label_index == index) {
197+
break;
198+
}
199+
200+
index++;
201+
}
202+
203+
if (label_index != index) {
204+
return CMT_FALSE;
205+
}
206+
207+
if (label == NULL) {
208+
return CMT_FALSE;
209+
}
210+
211+
if (label->name == NULL) {
212+
return CMT_FALSE;
213+
}
214+
215+
if (strncasecmp(label->name, label_value, strlen(label->name)) == 0) {
216+
return CMT_TRUE;
217+
}
218+
219+
return CMT_FALSE;
220+
}
221+
222+
static int metrics_map_drop_label_value_pairs(struct cmt_map *map,
223+
size_t label_index,
224+
const char *label_value)
225+
{
226+
struct cfl_list *head;
227+
struct cmt_metric *metric;
228+
int result;
229+
230+
result = CMT_FALSE;
231+
232+
cfl_list_foreach(head, &map->metrics) {
233+
metric = cfl_list_entry(head, struct cmt_metric, _head);
234+
235+
result = metrics_check_label_value_existence(metric,
236+
label_index,
237+
label_value);
238+
239+
if (result == CMT_TRUE) {
240+
result = CMT_TRUE;
241+
break;
242+
}
243+
}
244+
245+
if (result == CMT_TRUE) {
246+
cmt_map_metric_destroy(metric);
247+
}
248+
249+
return result;
250+
}
251+
252+
static int filter_context_label_key_value(struct cmt *dst, struct cmt *src,
253+
const char *label_key, const char *label_value)
254+
{
255+
int ret;
256+
char **labels = NULL;
257+
struct cfl_list *head;
258+
struct cmt_map *map;
259+
struct cmt_counter *counter;
260+
struct cmt_gauge *gauge;
261+
struct cmt_untyped *untyped;
262+
struct cmt_histogram *histogram;
263+
struct cmt_summary *summary;
264+
size_t index = 0;
265+
266+
/* Counters */
267+
cfl_list_foreach(head, &src->counters) {
268+
counter = cfl_list_entry(head, struct cmt_counter, _head);
269+
270+
ret = cmt_cat_copy_label_keys(counter->map, (char **) &labels);
271+
if (ret == -1) {
272+
return -1;
273+
}
274+
275+
map = cmt_map_create(CMT_COUNTER, &counter->opts,
276+
counter->map->label_count,
277+
labels, (void *) counter);
278+
free(labels);
279+
if (!map) {
280+
cmt_log_error(src, "unable to allocate map for counter");
281+
return -1;
282+
}
283+
284+
ret = cmt_cat_copy_map(&counter->opts, map, counter->map);
285+
if (ret == -1) {
286+
cmt_map_destroy(map);
287+
return -1;
288+
}
289+
290+
index = filter_get_label_index(map, label_key);
291+
if (index != -1) {
292+
metrics_map_drop_label_value_pairs(map, index, label_value);
293+
}
294+
295+
ret = cmt_cat_counter(dst, counter, map);
296+
if (ret == -1) {
297+
cmt_map_destroy(map);
298+
return -1;
299+
}
300+
301+
cmt_map_destroy(map);
302+
}
303+
304+
/* Gauges */
305+
cfl_list_foreach(head, &src->gauges) {
306+
gauge = cfl_list_entry(head, struct cmt_gauge, _head);
307+
308+
ret = cmt_cat_copy_label_keys(gauge->map, (char **) &labels);
309+
if (ret == -1) {
310+
return -1;
311+
}
312+
313+
map = cmt_map_create(CMT_GAUGE, &gauge->opts,
314+
gauge->map->label_count,
315+
labels, (void *) gauge);
316+
free(labels);
317+
if (!map) {
318+
cmt_log_error(src, "unable to allocate map for gauge");
319+
return -1;
320+
}
321+
322+
ret = cmt_cat_copy_map(&gauge->opts, map, gauge->map);
323+
if (ret == -1) {
324+
cmt_map_destroy(map);
325+
return -1;
326+
}
327+
328+
index = filter_get_label_index(map, label_key);
329+
if (index != -1) {
330+
metrics_map_drop_label_value_pairs(map, index, label_value);
331+
}
332+
333+
ret = cmt_cat_gauge(dst, gauge, map);
334+
if (ret == -1) {
335+
cmt_map_destroy(map);
336+
return -1;
337+
}
338+
339+
cmt_map_destroy(map);
340+
}
341+
342+
/* Untyped */
343+
cfl_list_foreach(head, &src->untypeds) {
344+
untyped = cfl_list_entry(head, struct cmt_untyped, _head);
345+
346+
ret = cmt_cat_copy_label_keys(untyped->map, (char **) &labels);
347+
if (ret == -1) {
348+
return -1;
349+
}
350+
351+
map = cmt_map_create(CMT_UNTYPED, &gauge->opts,
352+
untyped->map->label_count,
353+
labels, (void *) untyped);
354+
free(labels);
355+
if (!map) {
356+
cmt_log_error(src, "unable to allocate map for untyped");
357+
return -1;
358+
}
359+
360+
ret = cmt_cat_copy_map(&untyped->opts, map, untyped->map);
361+
if (ret == -1) {
362+
cmt_map_destroy(map);
363+
return -1;
364+
}
365+
366+
index = filter_get_label_index(map, label_key);
367+
if (index != -1) {
368+
metrics_map_drop_label_value_pairs(map, index, label_value);
369+
}
370+
371+
ret = cmt_cat_untyped(dst, untyped, map);
372+
if (ret == -1) {
373+
cmt_map_destroy(map);
374+
return -1;
375+
}
376+
377+
cmt_map_destroy(map);
378+
}
379+
380+
/* Histogram */
381+
cfl_list_foreach(head, &src->histograms) {
382+
histogram = cfl_list_entry(head, struct cmt_histogram, _head);
383+
384+
ret = cmt_cat_copy_label_keys(histogram->map, (char **) &labels);
385+
if (ret == -1) {
386+
return -1;
387+
}
388+
389+
map = cmt_map_create(CMT_HISTOGRAM, &histogram->opts,
390+
histogram->map->label_count,
391+
labels, (void *) histogram);
392+
free(labels);
393+
if (!map) {
394+
cmt_log_error(src, "unable to allocate map for histogram");
395+
return -1;
396+
}
397+
398+
ret = cmt_cat_copy_map(&histogram->opts, map, histogram->map);
399+
if (ret == -1) {
400+
cmt_map_destroy(map);
401+
return -1;
402+
}
403+
404+
index = filter_get_label_index(map, label_key);
405+
if (index != -1) {
406+
metrics_map_drop_label_value_pairs(map, index, label_value);
407+
}
408+
409+
ret = cmt_cat_histogram(dst, histogram, map);
410+
if (ret == -1) {
411+
cmt_map_destroy(map);
412+
return -1;
413+
}
414+
415+
cmt_map_destroy(map);
416+
}
417+
418+
/* Summary */
419+
cfl_list_foreach(head, &src->summaries) {
420+
summary = cfl_list_entry(head, struct cmt_summary, _head);
421+
422+
ret = cmt_cat_copy_label_keys(summary->map, (char **) &labels);
423+
if (ret == -1) {
424+
return -1;
425+
}
426+
427+
map = cmt_map_create(CMT_SUMMARY, &summary->opts,
428+
summary->map->label_count,
429+
labels, (void *) summary);
430+
free(labels);
431+
if (!map) {
432+
cmt_log_error(src, "unable to allocate map for summary");
433+
return -1;
434+
}
435+
436+
ret = cmt_cat_copy_map(&summary->opts, map, summary->map);
437+
if (ret == -1) {
438+
cmt_map_destroy(map);
439+
return -1;
440+
}
441+
442+
index = filter_get_label_index(map, label_key);
443+
if (index != -1) {
444+
metrics_map_drop_label_value_pairs(map, index, label_value);
445+
}
446+
447+
ret = cmt_cat_summary(dst, summary, map);
448+
if (ret == -1) {
449+
cmt_map_destroy(map);
450+
return -1;
451+
}
452+
453+
cmt_map_destroy(map);
454+
}
455+
456+
return CMT_FILTER_SUCCESS;
457+
}
458+
165459
static int compare_fqname(struct cmt_opts *src, const char *fqname,
166460
void *compare_ctx, int (*compare)(void *compare_ctx, const char *str, size_t slen),
167461
int flags)
@@ -287,6 +581,39 @@ static int filter_context_fqname(struct cmt *dst, struct cmt *src,
287581
return CMT_FILTER_SUCCESS;
288582
}
289583

584+
int cmt_filter_with_label_pair(struct cmt *dst, struct cmt *src,
585+
const char *label_key,
586+
const char *label_value)
587+
{
588+
int ret = CMT_FILTER_SUCCESS;
589+
590+
if (!dst) {
591+
return CMT_FILTER_INVALID_ARGUMENT;
592+
}
593+
594+
if (!src) {
595+
return CMT_FILTER_INVALID_ARGUMENT;
596+
}
597+
598+
if (label_key == NULL) {
599+
return CMT_FILTER_INVALID_ARGUMENT;
600+
}
601+
602+
if (label_value == NULL) {
603+
return CMT_FILTER_INVALID_ARGUMENT;
604+
}
605+
606+
if (label_key != NULL && label_value != NULL) {
607+
ret = filter_context_label_key_value(dst, src, label_key, label_value);
608+
}
609+
610+
if (ret != CMT_FILTER_SUCCESS) {
611+
return CMT_FILTER_FAILED_OPERATION;
612+
}
613+
614+
return ret;
615+
}
616+
290617
int cmt_filter(struct cmt *dst, struct cmt *src,
291618
const char *fqname, const char *label_key,
292619
void *compare_ctx, int (*compare)(void *compare_ctx, const char *str, size_t slen),

0 commit comments

Comments
 (0)