From: Michael Tremer Date: Wed, 22 Oct 2025 19:26:42 +0000 (+0000) Subject: source: Don't try to commit metrics too soon X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d210a205745e9cdbca41875f50d4249ac31cbb0d;p=telemetry.git source: Don't try to commit metrics too soon Signed-off-by: Michael Tremer --- diff --git a/src/daemon/source.c b/src/daemon/source.c index 0099251..002aa49 100644 --- a/src/daemon/source.c +++ b/src/daemon/source.c @@ -907,12 +907,45 @@ static int td_source_fetch_lastupdate(td_source* self, rrd_info_t* info, time_t* return 0; } +static int td_source_serialize_metrics(td_source* self, char*** samples, + unsigned int num_metrics, td_metrics** metrics, time_t lastupdate) { + const struct timeval* t = NULL; + char sample[4096]; + int r; + + for (unsigned int i = 0; i < num_metrics; i++) { + // Fetch the time of the metric + t = td_metrics_get_time(metrics[i]); + + // RRD throws an error if we try to write more than one sample per second. + // Therefore, we will throw away all metrics that have been collected too soon. + if (lastupdate && t->tv_sec <= lastupdate) { + DEBUG(self->ctx, "Throwing away metric for %s which has been collected too soon\n", + td_source_name(self)); + continue; + } + + // Serialize the metrics + r = td_metrics_serialize(metrics[i], sample); + if (r < 0) + return r; + + // Append it to the array + r = td_strings_append(samples, sample); + if (r < 0) + return r; + } + + return 0; +} + /* - Called to write all collected samples to disk + Called to write all collected metrics to disk */ -static int td_source_commit_samples(td_source* self, - const char* object, unsigned int num_samples, const char** samples) { +int td_source_commit_metrics(td_source* self, const char* object, + unsigned int num_metrics, td_metrics** metrics) { rrd_info_t* info = NULL; + char** samples = NULL; time_t lastupdate = 0; char path[PATH_MAX]; int r; @@ -951,45 +984,26 @@ static int td_source_commit_samples(td_source* self, goto ERROR; } - // Write the samples - r = rrd_update_r(path, NULL, num_samples, samples); - if (r < 0) { - ERROR(self->ctx, "Failed to write to %s: %s\n", path, rrd_get_error()); - rrd_clear_error(); - return -EFAULT; - } - -ERROR: - if (info) - rrd_info_free(info); - - return r; -} - -int td_source_commit_metrics(td_source* self, const char* object, - unsigned int num_metrics, td_metrics** metrics) { - char** samples = NULL; - char sample[4096]; - int r; - - for (unsigned int i = 0; i < num_metrics; i++) { - // Serialize the metrics - r = td_metrics_serialize(metrics[i], sample); - if (r < 0) - goto ERROR; + // Serialize the samples + r = td_source_serialize_metrics(self, &samples, num_metrics, metrics, lastupdate); + if (r < 0) + goto ERROR; - // Append it to the array - r = td_strings_append(&samples, sample); - if (r < 0) - goto ERROR; + // Write the samples + if (samples) { + r = rrd_update_r(path, NULL, td_strings_length(samples), (const char**)samples); + if (r < 0) { + ERROR(self->ctx, "Failed to write to %s: %s\n", path, rrd_get_error()); + rrd_clear_error(); + return -EFAULT; + } } - // Commit the samples - r = td_source_commit_samples(self, object, num_metrics, (const char**)samples); - ERROR: if (samples) td_strings_free(samples); + if (info) + rrd_info_free(info); return r; }