@cryptotaxi247 / netdata-1 / commits / fdd6bb81a

adapted prometheus formatting based on #2436

Costa Tsaousis (ktsaou) committed Jul 13, 2017 at 22:19 UTC fdd6bb81af362b2bcf563f61e62124f8dfc8e843
4 files changed +188 -33
src/backend_prometheus.c
+150 -32
@@ -67,6 +67,38 @@ static inline size_t prometheus_label_copy(char *d, const char *s, size_t usable
67 return n;
68 }
69
70 +static inline char *prometheus_units_copy(char *d, const char *s, size_t usable) {
71 + const char *sorig = s;
72 + char *ret = d;
73 + size_t n;
74 +
75 + *d++ = '_';
76 + for(n = 1; *s && n < usable ; d++, s++, n++) {
77 + register char c = *s;
78 +
79 + if(!isalnum(c)) *d = '_';
80 + else *d = c;
81 + }
82 +
83 + if(n == 2 && sorig[0] == '%') {
84 + n = 0;
85 + d = ret;
86 + s = "_percent";
87 + for( ; *s && n < usable ; n++) *d++ = *s++;
88 + }
89 + else if(n > 3 && sorig[n-3] == '/' && sorig[n-2] == 's') {
90 + n = n - 2;
91 + d -= 2;
92 + s = "_persec";
93 + for( ; *s && n < usable ; n++) *d++ = *s++;
94 + }
95 +
96 + *d = '\0';
97 +
98 + return ret;
99 +}
100 +
101 +
102 #define PROMETHEUS_ELEMENT_MAX 256
103 #define PROMETHEUS_LABELS_MAX 1024
104
@@ -94,6 +126,7 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
126 char chart[PROMETHEUS_ELEMENT_MAX + 1];
127 char context[PROMETHEUS_ELEMENT_MAX + 1];
128 char family[PROMETHEUS_ELEMENT_MAX + 1];
129 + char units[PROMETHEUS_ELEMENT_MAX + 1] = "";
130
131 prometheus_label_copy(chart, (names && st->name)?st->name:st->id, PROMETHEUS_ELEMENT_MAX);
132 prometheus_label_copy(family, st->family, PROMETHEUS_ELEMENT_MAX);
@@ -102,8 +135,23 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
135 if(likely(backends_can_send_rrdset(options, st))) {
136 rrdset_rdlock(st);
137
138 + int as_collected = ((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AS_COLLECTED);
139 + int homogeneus = 1;
140 + if(as_collected) {
141 + if(rrdset_flag_check(st, RRDSET_FLAG_HOMEGENEOUS_CHECK))
142 + rrdset_update_heterogeneous_flag(st);
143 +
144 + if(rrdset_flag_check(st, RRDSET_FLAG_HETEROGENEOUS))
145 + homogeneus = 0;
146 + }
147 + else {
148 + if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AVERAGE)
149 + prometheus_units_copy(units, st->units, PROMETHEUS_ELEMENT_MAX);
150 + }
151 +
152 if(unlikely(help))
106 - buffer_sprintf(wb, "\n# COMMENT chart \"%s\", context \"%s\", family \"%s\", units \"%s\"\n"
153 + buffer_sprintf(wb, "\n# COMMENT %s chart \"%s\", context \"%s\", family \"%s\", units \"%s\"\n"
154 + , (homogeneus)?"homogeneus":"heterogeneous"
155 , (names && st->name) ? st->name : st->id
156 , st->context
157 , st->family
@@ -115,54 +163,109 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
163 rrddim_foreach_read(rd, st) {
164 if(rd->collections_counter) {
165 char dimension[PROMETHEUS_ELEMENT_MAX + 1];
166 + char *suffix = "";
167
119 - if ((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AS_COLLECTED) {
168 + if (as_collected) {
169 // we need as-collected / raw data
170
122 - prometheus_name_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
123 -
171 const char *t = "gauge", *h = "gives";
172 if(rd->algorithm == RRD_ALGORITHM_INCREMENTAL ||
173 rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL) {
174 t = "counter";
175 h = "delta gives";
176 + suffix = "_total";
177 }
178
131 - if(unlikely(help))
179 + if(homogeneus) {
180 + // all the dimensions of the chart, has the same algorithm, multiplier and divisor
181 + // we add all dimensions as labels
182 +
183 + prometheus_label_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
184 +
185 + if(unlikely(help))
186 + buffer_sprintf(wb
187 + , "# COMMENT %s_%s%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n"
188 + , prefix
189 + , context
190 + , suffix
191 + , (names && st->name) ? st->name : st->id
192 + , st->context
193 + , st->family
194 + , (names && rd->name) ? rd->name : rd->id
195 + , rd->multiplier
196 + , rd->divisor
197 + , h
198 + , st->units
199 + , t
200 + );
201 +
202 + if(unlikely(types))
203 + buffer_sprintf(wb, "# COMMENT TYPE %s_%s%s %s\n"
204 + , prefix
205 + , context
206 + , suffix
207 + , t
208 + );
209 +
210 buffer_sprintf(wb
133 - , "# COMMENT %s_%s_%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n"
211 + , "%s_%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n"
212 , prefix
213 , context
214 + , suffix
215 + , chart
216 + , family
217 , dimension
137 - , (names && st->name) ? st->name : st->id
138 - , st->context
139 - , st->family
140 - , (names && rd->name) ? rd->name : rd->id
141 - , rd->multiplier
142 - , rd->divisor
143 - , h
144 - , st->units
145 - , t
218 + , labels
219 + , rd->last_collected_value
220 + , timeval_msec(&rd->last_collected_time)
221 );
222 + }
223 + else {
224 + // the dimensions of the chart, do not have the same algorithm, multiplier or divisor
225 + // we create a metric per dimension
226 +
227 + prometheus_name_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
228 +
229 + if(unlikely(help))
230 + buffer_sprintf(wb
231 + , "# COMMENT %s_%s_%s%s: chart \"%s\", context \"%s\", family \"%s\", dimension \"%s\", value * " COLLECTED_NUMBER_FORMAT " / " COLLECTED_NUMBER_FORMAT " %s %s (%s)\n"
232 + , prefix
233 + , context
234 + , dimension
235 + , suffix
236 + , (names && st->name) ? st->name : st->id
237 + , st->context
238 + , st->family
239 + , (names && rd->name) ? rd->name : rd->id
240 + , rd->multiplier
241 + , rd->divisor
242 + , h
243 + , st->units
244 + , t
245 + );
246
148 - if(unlikely(types))
149 - buffer_sprintf(wb, "# COMMENT TYPE %s_%s_%s %s\n"
247 + if(unlikely(types))
248 + buffer_sprintf(wb, "# COMMENT TYPE %s_%s_%s%s %s\n"
249 + , prefix
250 + , context
251 + , dimension
252 + , suffix
253 + , t
254 + );
255 +
256 + buffer_sprintf(wb
257 + , "%s_%s_%s%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n"
258 , prefix
259 , context
260 , dimension
153 - , t
261 + , suffix
262 + , chart
263 + , family
264 + , labels
265 + , rd->last_collected_value
266 + , timeval_msec(&rd->last_collected_time)
267 );
155 -
156 - buffer_sprintf(wb, "%s_%s_%s{chart=\"%s\",family=\"%s\"%s} " COLLECTED_NUMBER_FORMAT " %llu\n"
157 - , prefix
158 - , context
159 - , dimension
160 - , chart
161 - , family
162 - , labels
163 - , rd->last_collected_value
164 - , timeval_msec(&rd->last_collected_time)
165 - );
268 + }
269 }
270 else {
271 // we need average or sum of the data
@@ -171,12 +274,20 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
274 calculated_number value = backend_calculate_value_from_stored_data(st, rd, after, before, options, &first_t, &last_t);
275
276 if(!isnan(value) && !isinf(value)) {
277 +
278 + if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_AVERAGE)
279 + suffix = "_average";
280 + else if((options & BACKEND_SOURCE_BITS) == BACKEND_SOURCE_DATA_SUM)
281 + suffix = "_sum";
282 +
283 prometheus_label_copy(dimension, (names && rd->name) ? rd->name : rd->id, PROMETHEUS_ELEMENT_MAX);
284
285 if (unlikely(help))
177 - buffer_sprintf(wb, "# COMMENT %s_%s: dimension \"%s\", value is %s, gauge, dt %llu to %llu inclusive\n"
286 + buffer_sprintf(wb, "# COMMENT %s_%s%s%s: dimension \"%s\", value is %s, gauge, dt %llu to %llu inclusive\n"
287 , prefix
288 , context
289 + , units
290 + , suffix
291 , (names && rd->name) ? rd->name : rd->id
292 , st->units
293 , (unsigned long long)first_t
@@ -184,11 +295,18 @@ static void rrd_stats_api_v1_charts_allmetrics_prometheus(RRDHOST *host, BUFFER
295 );
296
297 if (unlikely(types))
187 - buffer_sprintf(wb, "# COMMENT TYPE %s_%s gauge\n", prefix, context);
298 + buffer_sprintf(wb, "# COMMENT TYPE %s_%s%s%s gauge\n"
299 + , prefix
300 + , context
301 + , units
302 + , suffix
303 + );
304
189 - buffer_sprintf(wb, "%s_%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " CALCULATED_NUMBER_FORMAT " %llu\n"
305 + buffer_sprintf(wb, "%s_%s%s%s{chart=\"%s\",family=\"%s\",dimension=\"%s\"%s} " CALCULATED_NUMBER_FORMAT " %llu\n"
306 , prefix
307 , context
308 + , units
309 + , suffix
310 , chart
311 , family
312 , dimension
src/rrd.h
+4 -1
@@ -227,7 +227,8 @@ typedef enum rrdset_flags {
227 RRDSET_FLAG_BACKEND_IGNORE = 1 << 5, // if set, this chart should not be sent to backends
228 RRDSET_FLAG_EXPOSED_UPSTREAM = 1 << 6, // if set, we have sent this chart to netdata master (streaming)
229 RRDSET_FLAG_STORE_FIRST = 1 << 7, // if set, do not eliminate the first collection during interpolation
230 - RRDSET_FLAG_HETEROGENEOUS = 1 << 8 // if set, the chart is not homogeneus (dimensions in it have multiple algorithms, multipliers or dividers)
230 + RRDSET_FLAG_HETEROGENEOUS = 1 << 8, // if set, the chart is not homogeneous (dimensions in it have multiple algorithms, multipliers or dividers)
231 + RRDSET_FLAG_HOMEGENEOUS_CHECK= 1 << 9 // if set, the chart should be checked to determine if the dimensions as homogeneous
232 } RRDSET_FLAGS;
233
234 #ifdef HAVE_C___ATOMIC
@@ -596,6 +597,8 @@ extern void rrdhost_free(RRDHOST *host);
597 extern void rrdhost_save(RRDHOST *host);
598 extern void rrdhost_delete(RRDHOST *host);
599
600 +extern void rrdset_update_heterogeneous_flag(RRDSET *st);
601 +
602 extern RRDSET *rrdset_find(RRDHOST *host, const char *id);
603 #define rrdset_find_localhost(id) rrdset_find(localhost, id)
604
src/rrddim.c
+3
@@ -57,6 +57,7 @@ inline int rrddim_set_algorithm(RRDSET *st, RRDDIM *rd, RRD_ALGORITHM algorithm)
57 debug(D_RRD_CALLS, "Updating algorithm of dimension '%s/%s' from %s to %s", st->id, rd->name, rrd_algorithm_name(rd->algorithm), rrd_algorithm_name(algorithm));
58 rd->algorithm = algorithm;
59 rd->exposed = 0;
60 + rrdset_flag_set(st, RRDSET_FLAG_HOMEGENEOUS_CHECK);
61 return 1;
62 }
63
@@ -67,6 +68,7 @@ inline int rrddim_set_multiplier(RRDSET *st, RRDDIM *rd, collected_number multip
68 debug(D_RRD_CALLS, "Updating multiplier of dimension '%s/%s' from " COLLECTED_NUMBER_FORMAT " to " COLLECTED_NUMBER_FORMAT, st->id, rd->name, rd->multiplier, multiplier);
69 rd->multiplier = multiplier;
70 rd->exposed = 0;
71 + rrdset_flag_set(st, RRDSET_FLAG_HOMEGENEOUS_CHECK);
72 return 1;
73 }
74
@@ -77,6 +79,7 @@ inline int rrddim_set_divisor(RRDSET *st, RRDDIM *rd, collected_number divisor)
79 debug(D_RRD_CALLS, "Updating divisor of dimension '%s/%s' from " COLLECTED_NUMBER_FORMAT " to " COLLECTED_NUMBER_FORMAT, st->id, rd->name, rd->divisor, divisor);
80 rd->divisor = divisor;
81 rd->exposed = 0;
82 + rrdset_flag_set(st, RRDSET_FLAG_HOMEGENEOUS_CHECK);
83 return 1;
84 }
85
src/rrdset.c
+31
@@ -190,6 +190,37 @@ inline void rrdset_isnot_obsolete(RRDSET *st) {
190 }
191 }
192
193 +inline void rrdset_update_heterogeneous_flag(RRDSET *st) {
194 + RRDDIM *rd;
195 +
196 + rrdset_flag_clear(st, RRDSET_FLAG_HOMEGENEOUS_CHECK);
197 +
198 + RRD_ALGORITHM algorithm = st->dimensions->algorithm;
199 + collected_number multiplier = abs(st->dimensions->multiplier);
200 + collected_number divisor = abs(st->dimensions->divisor);
201 +
202 + rrddim_foreach_read(rd, st) {
203 + if(algorithm != rd->algorithm || multiplier != abs(rd->multiplier) || divisor != abs(rd->divisor)) {
204 + if(!rrdset_flag_check(st, RRDSET_FLAG_HETEROGENEOUS)) {
205 + #ifdef NETDATA_INTERNAL_CHECKS
206 + info("Dimension '%s' added on chart '%s' of host '%s' is not homogeneous to other dimensions already present (algorithm is '%s' vs '%s', multiplier is " COLLECTED_NUMBER_FORMAT " vs " COLLECTED_NUMBER_FORMAT ", divisor is " COLLECTED_NUMBER_FORMAT " vs " COLLECTED_NUMBER_FORMAT ").",
207 + rd->name,
208 + st->name,
209 + st->rrdhost->hostname,
210 + rrd_algorithm_name(rd->algorithm), rrd_algorithm_name(algorithm),
211 + rd->multiplier, multiplier,
212 + rd->divisor, divisor
213 + );
214 + #endif
215 + rrdset_flag_set(st, RRDSET_FLAG_HETEROGENEOUS);
216 + }
217 + return;
218 + }
219 + }
220 +
221 + rrdset_flag_clear(st, RRDSET_FLAG_HETEROGENEOUS);
222 +}
223 +
224 // ----------------------------------------------------------------------------
225 // RRDSET - reset a chart
226