improved alignment of metrics sent to backends for data source average and sum
Costa Tsaousis (ktsaou) committed
Jul 11, 2017 at 19:55 UTC
1d12c069a62758151e3ac4d37ceec2665c484f16
3 files changed
+61
-33
src/backend_prometheus.c
+25
-9
@@ -102,8 +102,15 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
102
if(likely(backends_can_send_rrdset(options, st))) {
103
rrdset_rdlock(st);
104
105
- if(unlikely(help || types))
106
- buffer_strcat(wb, "\n");
105
+ if(unlikely(help))
106
+ buffer_sprintf(wb, "\n# COMMENT chart \"%s\", context \"%s\", family \"%s\", units \"%s\"\n",
107
+ prefix, context,
108
+ (names && st->name) ? st->name : st->id,
109
+ st->context,
110
+ st->family,
111
+ (names && rd->name) ? rd->name : rd->id,
112
+ st->units
113
+ );
114
115
// for each dimension
116
RRDDIM *rd;
@@ -124,7 +131,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
131
}
132
133
if (unlikely(help))
127
- buffer_sprintf(wb, "# COMMENT HELP %s_%s_%s netdata chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n",
134
+ buffer_sprintf(wb, "# COMMENT %s_%s_%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n",
135
prefix, context, dimension,
136
(names && st->name) ? st->name : st->id, st->context,
137
st->family,
@@ -145,18 +152,18 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
152
else {
153
// we need average or sum of the data
154
148
- calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options);
155
+ time_t first_t = after, last_t = before;
156
+ calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options, &first_t, &last_t);
157
158
if(!isnan(value) && !isinf(value)) {
159
prometheus_label_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
160
161
if (unlikely(help))
154
- buffer_sprintf(wb, "# COMMENT HELP %s_%s netdata chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value gives %s (gauge)\n",
162
+ buffer_sprintf(wb, "# COMMENT %s_%s: dimension \"%s\", value is %s, gauge, dt %llu to %llu inclusive\n",
163
prefix, context,
156
- (names && st->name) ? st->name : st->id, st->context,
157
- st->family,
164
(names && rd->name) ? rd->name : rd->id,
159
- st->units
165
+ st->units,
166
+ (unsigned long long)first_t, (unsigned long long)last_t
167
);
168
169
if (unlikely(types))
@@ -165,7 +172,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
172
buffer_sprintf(wb, "%s_%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " CALCULATED_NUMBER_FORMAT " %llu\n",
173
prefix, context,
174
chart, family, dimension, labels,
168
- value, timeval_msec(&rd->last_collected_time)
175
+ value, last_t * MSEC_PER_SEC
176
);
177
}
178
}
@@ -190,6 +197,11 @@ static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, uint32_t
197
first_seen = 1;
198
}
199
200
+ if(after > now) {
201
+ // oops! this should never happen
202
+ after = now - backend_update_every;
203
+ }
204
+
205
if(help) {
206
int show_range = 1;
207
char *mode;
@@ -224,6 +236,8 @@ static inline time_t prometheus_preparation(RRDHOST *host, BUFFER *wb, uint32_t
236
237
void rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, uint32_t options, int help, int types, int names) {
238
time_t before = now_realtime_sec();
239
+
240
+ // we start at the point we had stopped before
241
time_t after = prometheus_preparation(host, wb, options, server, before, help);
242
243
rrd_stats_api_v1_charts_allmetrics_prometheus(host, wb, prefix, options, after, before, 0, help, types, names);
@@ -231,6 +245,8 @@ void rrd_stats_api_v1_charts_allmetrics_prometheus_single_host(RRDHOST *host, BU
245
246
void rrd_stats_api_v1_charts_allmetrics_prometheus_all_hosts(RRDHOST *host, BUFFER *wb, const char *server, const char *prefix, uint32_t options, int help, int types, int names) {
247
time_t before = now_realtime_sec();
248
+
249
+ // we start at the point we had stopped before
250
time_t after = prometheus_preparation(host, wb, options, server, before, help);
251
252
rrd_rdlock();
src/backends.c
+34
-24
@@ -53,22 +53,36 @@ inline calculated_number backend_calculate_value_from_stored_data(
53
, time_t after // the start timestamp
54
, time_t before // the end timestamp
55
, uint32_t options // BACKEND_SOURCE_* bitmap
56
+ , time_t *first_timestamp // the first point of the database used in this response
57
+ , time_t *last_timestamp // the timestamp that should be reported to backend
58
) {
59
// find the edges of the rrd database for this chart
60
time_t first_t = rrdset_first_entry_t(st);
61
time_t last_t = rrdset_last_entry_t(st);
62
time_t update_every = st->update_every;
63
64
+ // step back a little, to make sure we have complete data collection
65
+ // for all metrics
66
+ after -= update_every * 2;
67
+ before -= update_every * 2;
68
+
69
// align the time-frame
63
- // for 'after' also skip the first value by adding update_every
64
- after = after - after % update_every + update_every;
65
- before = before - before % update_every;
66
-
67
- if(unlikely(after = last_t + update_every)) {
68
- // we missed an update, report the last one
69
- after -= update_every;
70
- before -= update_every;
71
- }
70
+ after = after - (after % update_every);
71
+ before = before - (before % update_every);
72
+
73
+ // for before, loose another iteration
74
+ // the latest point will be reported the next time
75
+ before -= update_every;
76
+
77
+ if(unlikely(after > before))
78
+ // this can happen when update_every > before - after
79
+ after = before;
80
+
81
+ if(unlikely(after < first_t))
82
+ after = first_t;
83
+
84
+ if(unlikely(before > last_t))
85
+ before = last_t;
86
87
if(unlikely(before < first_t || after > last_t)) {
88
// the chart has not been updated in the wanted timeframe
@@ -80,15 +94,8 @@ inline calculated_number backend_calculate_value_from_stored_data(
94
return NAN;
95
}
96
83
- if(unlikely(after < first_t))
84
- after = first_t;
85
-
86
- if(unlikely(after > before))
87
- // this can happen when update_every > before - after
88
- before = after;
89
-
90
- if(unlikely(before > last_t))
91
- before = last_t;
97
+ *first_timestamp = after;
98
+ *last_timestamp = before;
99
100
size_t counter = 0;
101
calculated_number sum = 0;
@@ -207,7 +214,8 @@ static inline int format_dimension_stored_graphite_plaintext(
214
backend_name_copy(chart_name, (backend_send_names && st->name)?st->name:st->id, RRD_ID_LENGTH_MAX);
215
backend_name_copy(dimension_name, (backend_send_names && rd->name)?rd->name:rd->id, RRD_ID_LENGTH_MAX);
216
210
- calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options);
217
+ time_t first_t = after, last_t = before;
218
+ calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options, &first_t, &last_t);
219
220
if(!isnan(value)) {
221
@@ -219,7 +227,7 @@ static inline int format_dimension_stored_graphite_plaintext(
227
, chart_name
228
, dimension_name
229
, value
222
- , (uint32_t) before
230
+ , (uint32_t) last_t
231
);
232
233
return 1;
@@ -285,7 +293,8 @@ static inline int format_dimension_stored_opentsdb_telnet(
293
) {
294
(void)host;
295
288
- calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options);
296
+ time_t first_t = after, last_t = before;
297
+ calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options, &first_t, &last_t);
298
299
char chart_name[RRD_ID_LENGTH_MAX + 1];
300
char dimension_name[RRD_ID_LENGTH_MAX + 1];
@@ -300,7 +309,7 @@ static inline int format_dimension_stored_opentsdb_telnet(
309
, prefix
310
, chart_name
311
, dimension_name
303
- , (uint32_t) before
312
+ , (uint32_t) last_t
313
, value
314
, hostname
315
, (host->tags)?" ":""
@@ -385,7 +394,8 @@ static inline int format_dimension_stored_json_plaintext(
394
) {
395
(void)host;
396
388
- calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options);
397
+ time_t first_t = after, last_t = before;
398
+ calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options, &first_t, &last_t);
399
400
if(!isnan(value)) {
401
buffer_sprintf(b, "{"
@@ -418,7 +428,7 @@ static inline int format_dimension_stored_json_plaintext(
428
rd->name,
429
value,
430
421
- (uint32_t)before
431
+ (uint32_t) last_t
432
);
433
434
return 1;
src/backends.h
+2
@@ -23,6 +23,8 @@ extern calculated_number backend_calculate_value_from_stored_data(
23
, time_t after // the start timestamp
24
, time_t before // the end timestamp
25
, uint32_t options // BACKEND_SOURCE_* bitmap
26
+ , time_t *first_timestamp // the timestamp of the first point used in this response
27
+ , time_t *last_timestamp // the timestamp that should be reported to backend
28
);
29
30
#endif /* NETDATA_BACKENDS_H */