}
static int insert_metrics(metric_family_t *fam, metric_list_t metrics) {
+ int skipped = 0;
for (size_t i = 0; i < metrics.num; i++) {
- if (metric_exists(fam, metrics.ptr + i)) {
- return EEXIST;
+ metric_t const *m = metrics.ptr + i;
+
+ if (metric_exists(fam, m)) {
+#if COLLECT_DEBUG
+ strbuf_t buf = STRBUF_CREATE;
+ metric_identity(&buf, m);
+ DEBUG("resource_metrics: Skipping duplicate of metric %s", buf.ptr);
+ STRBUF_DESTROY(buf);
+#endif
+ skipped++;
+ continue;
}
- }
- int last_err = 0;
- for (size_t i = 0; i < metrics.num; i++) {
- int status = metric_family_metric_append(fam, metrics.ptr[i]);
+ int status = metric_family_metric_append(fam, *m);
if (status != 0) {
ERROR("resource_metrics: metric_family_metric_append failed: %s",
STRERROR(status));
/* DO NOT RETURN: the metric list may be unsorted */
- last_err = status;
+ skipped++;
}
}
- qsort(fam->metric.ptr, fam->metric.num, sizeof(*fam->metric.ptr),
- (void *)compare_metrics);
- return last_err;
+ if (((size_t)skipped) != metrics.num) {
+ qsort(fam->metric.ptr, fam->metric.num, sizeof(*fam->metric.ptr),
+ (void *)compare_metrics);
+ }
+
+ return skipped;
}
int resource_metrics_add(resource_metrics_set_t *set,
metric_family_t const *fam) {
if (set == NULL || fam == NULL) {
- return EINVAL;
+ return -1;
}
resource_metrics_t *rm = lookup_or_insert_resource(set, fam->resource);
} resource_metrics_set_t;
/* resource_metrics_add copies a metric family to the resource metrics set.
- * If any metric within the metric family is already part of the resource
- * metrics set, the function will return EEXIST and rm remains unmodified. */
+ * Identical metrics are skipped and not added to the set. Metrics are
+ * identical, if their resource attributes, metric family name, metric labels,
+ * and time stamp are equal.
+ * Returns the number of metrics that were skipped or -1 on error. That means
+ * that zero indicates complete success, a positive number indicates partial
+ * success, and a negative number indicates an error condition. The number of
+ * skipped entries may be equal to the total number of metrics provided; this is
+ * not indicated as an error. */
int resource_metrics_add(resource_metrics_set_t *rm,
metric_family_t const *fam);
CHECK_ZERO(resource_metrics_add(&set, fam));
EXPECT_EQ_INT(1, set.num);
EXPECT_EQ_INT(1, count_metrics(set));
- /* adding the same familiy twice should return EEXIST. */
- EXPECT_EQ_INT(EEXIST, resource_metrics_add(&set, fam));
+ /* adding the same metric twice should return one skipped metric. */
+ EXPECT_EQ_INT(1, resource_metrics_add(&set, fam));
EXPECT_EQ_INT(1, set.num);
EXPECT_EQ_INT(1, count_metrics(set));
metric_family_free(fam);
- /* adding the same metric (but with a different resource attribute) should
+ /* adding the same metric family with different resource attributes should
* succeed. */
CHECK_NOT_NULL(fam = make_metric_family(2, 1, 1, 1));
CHECK_ZERO(resource_metrics_add(&set, fam));
EXPECT_EQ_INT(2, set.num);
EXPECT_EQ_INT(2, count_metrics(set));
- /* adding the same familiy twice should return EEXIST. */
- EXPECT_EQ_INT(EEXIST, resource_metrics_add(&set, fam));
+ /* adding the same metric twice should return one skipped metric. */
+ EXPECT_EQ_INT(1, resource_metrics_add(&set, fam));
EXPECT_EQ_INT(2, set.num);
EXPECT_EQ_INT(2, count_metrics(set));
metric_family_free(fam);
/* reuses existing resource */
EXPECT_EQ_INT(2, set.num);
EXPECT_EQ_INT(3, count_metrics(set));
- /* adding the same familiy twice should return EEXIST. */
- EXPECT_EQ_INT(EEXIST, resource_metrics_add(&set, fam));
+ /* adding the same metric twice should return one skipped metric. */
+ EXPECT_EQ_INT(1, resource_metrics_add(&set, fam));
EXPECT_EQ_INT(2, set.num);
EXPECT_EQ_INT(3, count_metrics(set));
metric_family_free(fam);
/* reuses existing resource */
EXPECT_EQ_INT(2, set.num);
EXPECT_EQ_INT(4, count_metrics(set));
- /* adding the same familiy twice should return EEXIST. */
- EXPECT_EQ_INT(EEXIST, resource_metrics_add(&set, fam));
+ /* adding the same metric twice should return one skipped metric. */
+ EXPECT_EQ_INT(1, resource_metrics_add(&set, fam));
EXPECT_EQ_INT(2, set.num);
EXPECT_EQ_INT(4, count_metrics(set));
metric_family_free(fam);
/* reuses existing resource */
EXPECT_EQ_INT(2, set.num);
EXPECT_EQ_INT(5, count_metrics(set));
- /* adding the same metric twice should return EEXIST. */
- EXPECT_EQ_INT(EEXIST, resource_metrics_add(&set, fam));
+ /* adding the same metric twice should return one skipped metric. */
+ EXPECT_EQ_INT(1, resource_metrics_add(&set, fam));
EXPECT_EQ_INT(2, set.num);
EXPECT_EQ_INT(5, count_metrics(set));
metric_family_free(fam);