Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/cmetrics/cmetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,6 @@ struct cmt *cmt_create();
void cmt_destroy(struct cmt *cmt);
int cmt_label_add(struct cmt *cmt, char *key, char *val);
char *cmt_version();
void cmt_expire(struct cmt *cmt, uint64_t expiration);

#endif
3 changes: 3 additions & 0 deletions include/cmetrics/cmt_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ int cmt_map_metric_get_val(struct cmt_opts *opts, struct cmt_map *map,
double *out_val);
void cmt_map_metric_destroy(struct cmt_metric *metric);

int cmt_map_metrics_expire(struct cmt_map *, uint64_t);

void destroy_label_list(struct cfl_list *label_list);


#endif
37 changes: 37 additions & 0 deletions src/cmetrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <cmetrics/cmt_atomic.h>
#include <cmetrics/cmt_compat.h>
#include <cmetrics/cmt_label.h>
#include <cmetrics/cmt_map.h>
#include <cmetrics/cmt_version.h>

#include <cfl/cfl_kvlist.h>
Expand Down Expand Up @@ -136,6 +137,42 @@ void cmt_destroy(struct cmt *cmt)
free(cmt);
}

void cmt_expire(struct cmt *cmt, uint64_t expiration)
{
struct cfl_list *tmp;
struct cfl_list *head;
struct cmt_counter *c;
struct cmt_gauge *g;
struct cmt_summary *s;
struct cmt_histogram *h;
struct cmt_untyped *u;

cfl_list_foreach_safe(head, tmp, &cmt->counters) {
c = cfl_list_entry(head, struct cmt_counter, _head);
cmt_map_metrics_expire(c->map, expiration);
}

cfl_list_foreach_safe(head, tmp, &cmt->gauges) {
g = cfl_list_entry(head, struct cmt_gauge, _head);
cmt_map_metrics_expire(g->map, expiration);
}

cfl_list_foreach_safe(head, tmp, &cmt->summaries) {
s = cfl_list_entry(head, struct cmt_summary, _head);
cmt_map_metrics_expire(s->map, expiration);
}

cfl_list_foreach_safe(head, tmp, &cmt->histograms) {
h = cfl_list_entry(head, struct cmt_histogram, _head);
cmt_map_metrics_expire(h->map, expiration);
}

cfl_list_foreach_safe(head, tmp, &cmt->untypeds) {
u = cfl_list_entry(head, struct cmt_untyped, _head);
cmt_map_metrics_expire(u->map, expiration);
}
}

int cmt_label_add(struct cmt *cmt, char *key, char *val)
{
return cmt_labels_add_kv(cmt->static_labels, key, val);
Expand Down
16 changes: 16 additions & 0 deletions src/cmt_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,3 +316,19 @@ void destroy_label_list(struct cfl_list *label_list)
}
}

/* This function can be used to expire untouched metrics.
*/
int cmt_map_metrics_expire(struct cmt_map *map, uint64_t expiration)
{
struct cfl_list *tmp;
struct cfl_list *head;
struct cmt_metric *metric;

cfl_list_foreach_safe(head, tmp, &map->metrics) {
metric = cfl_list_entry(head, struct cmt_metric, _head);
if (metric->timestamp <= expiration) {
cmt_map_metric_destroy(metric);
}
}
return 0;
}
14 changes: 10 additions & 4 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(UNIT_TESTS_FILES
issues.c
null_label.c
filter.c
expire.c
)

if (CMT_BUILD_PROMETHEUS_TEXT_DECODER)
Expand Down Expand Up @@ -39,11 +40,16 @@ foreach(source_file ${UNIT_TESTS_FILES})
encode_output.c
)

target_link_libraries(${source_file_we} cmetrics-static cfl-static fluent-otel-proto)
target_link_libraries(${source_file_we} cmetrics-static fluent-otel-proto)
if (CMT_HAVE_CFL)
target_link_libraries(${source_file_we} cfl)
else()
target_link_libraries(${source_file_we} cfl-static)
endif()

if(NOT CMT_SYSTEM_WINDOWS)
target_link_libraries(${source_file_we} pthread)
endif()
if(NOT CMT_SYSTEM_WINDOWS)
target_link_libraries(${source_file_we} pthread)
endif()

add_test(NAME ${source_file_we}
COMMAND ${CMAKE_BINARY_DIR}/tests/${source_file_we}
Expand Down
185 changes: 185 additions & 0 deletions tests/expire.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/* CMetrics
* ========
* Copyright 2021-2022 The CMetrics Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <cmetrics/cmetrics.h>
#include <cmetrics/cmt_counter.h>
#include <cmetrics/cmt_gauge.h>
#include <cmetrics/cmt_histogram.h>
#include <cmetrics/cmt_summary.h>
#include <cmetrics/cmt_map.h>
#include <cmetrics/cmt_encode_prometheus.h>

#include "cmt_tests.h"

void test_expire_counter()
{
uint64_t ts;
struct cmt *cmt;
struct cmt_counter *c;

cmt_initialize();

cmt = cmt_create();
TEST_CHECK(cmt != NULL);

/* Create a counter metric type */
c = cmt_counter_create(cmt, "k8s", "network", "uptime", "Network Uptime", 1, (char *[]) {"host"});
TEST_CHECK(c != NULL);

/* Timestamp */
ts = cfl_time_now();

cmt_counter_inc(c, ts, 1, (char *[]){"valid"});
cmt_counter_inc(c, ts-10, 1, (char *[]){"expire"});

TEST_CHECK(cfl_list_size(&c->map->metrics) == 2);
cmt_expire(cmt, ts-1);
TEST_CHECK(cfl_list_size(&c->map->metrics) == 1);

cmt_destroy(cmt);
}

void test_expire_gauge()
{
uint64_t ts;
struct cmt *cmt;
struct cmt_gauge *g;

cmt_initialize();

cmt = cmt_create();
TEST_CHECK(cmt != NULL);

/* Create a gauge metric type */
g = cmt_gauge_create(cmt, "k8s", "network", "load", "Network load", 1, (char *[]) {"host"});
TEST_CHECK(g != NULL);

/* Timestamp */
ts = cfl_time_now();

cmt_gauge_set(g, ts, 50, 1, (char *[]){"valid"});
cmt_gauge_set(g, ts-10, 50, 1, (char *[]){"expire"});

TEST_CHECK(cfl_list_size(&g->map->metrics) == 2);
cmt_expire(cmt, ts-1);
TEST_CHECK(cfl_list_size(&g->map->metrics) == 1);

cmt_destroy(cmt);
}

void test_expire_histogram()
{
uint64_t ts;
struct cmt *cmt;
struct cmt_histogram *h;
struct cmt_histogram_buckets *buckets;

cmt_initialize();

cmt = cmt_create();
TEST_CHECK(cmt != NULL);

/* Create buckets */
buckets = cmt_histogram_buckets_create(11,
0.005, 0.01, 0.025, 0.05,
0.1, 0.25, 0.5, 1.0, 2.5,
5.0, 10.0);
TEST_CHECK(buckets != NULL);

/* Create a histogram metric type */
h = cmt_histogram_create(cmt,
"k8s", "network", "uptime", "Network Uptime",
buckets,
1, (char *[]) {"host"});
TEST_CHECK(h != NULL);

/* Timestamp */
ts = cfl_time_now();

cmt_histogram_observe(h, ts, 1.0, 1, (char *[]){"valid"});
cmt_histogram_observe(h, ts-10, 1.0, 1, (char *[]){"expire"});

TEST_CHECK(cfl_list_size(&h->map->metrics) == 2);
cmt_expire(cmt, ts-1);
TEST_CHECK(cfl_list_size(&h->map->metrics) == 1);

cmt_destroy(cmt);
}

void test_expire_summary()
{
uint64_t ts;
struct cmt *cmt;
struct cmt_summary *s;
double quantiles[6];
double revised[6];
double sum;
uint64_t count;

/* set quantiles, no labels */
quantiles[0] = 0.1;
quantiles[1] = 0.2;
quantiles[2] = 0.3;
quantiles[3] = 0.4;
quantiles[4] = 0.5;
quantiles[5] = 1.0;

revised[0] = 1.0;
revised[1] = 2.0;
revised[2] = 3.0;
revised[3] = 4.0;
revised[4] = 5.0;
revised[5] = 6.0;

count = 10;
sum = 51.612894511314444;

cmt_initialize();

cmt = cmt_create();
TEST_CHECK(cmt != NULL);

/* Create a summary metric type */
s = cmt_summary_create(cmt,
"k8s", "network", "uptime", "Network Uptime",
6,
quantiles,
1, (char *[]) {"host"});
TEST_CHECK(s != NULL);

/* Timestamp */
ts = cfl_time_now();

cmt_summary_set_default(s, ts, revised, sum, count, 1, (char *[]){"valid"});
cmt_summary_set_default(s, ts-10, revised, sum, count, 1, (char *[]){"expire"});

TEST_CHECK(cfl_list_size(&s->map->metrics) == 2);
cmt_expire(cmt, ts-1);
TEST_CHECK(cfl_list_size(&s->map->metrics) == 1);

cmt_destroy(cmt);
}

TEST_LIST = {
{"expire_counter" , test_expire_counter},
{"expire_gauge" , test_expire_gauge},
{"expire_histogram" , test_expire_histogram},
{"expire_summary", test_expire_summary},
{ 0 }
};
Loading