add prometheus support to the API; fixes #1497
Costa Tsaousis (ktsaou) committed
Jan 3, 2017 at 21:11 UTC
e756f1e8591c2ba50be8f66dcd3169105c670d49
3 files changed
+90
-1
src/rrd2json.c
+37
@@ -124,6 +124,43 @@ void rrd_stats_api_v1_charts(BUFFER *wb)
124
);
125
}
126
127
+void rrd_stats_api_v1_charts_allmetrics_prometheus(BUFFER *wb)
128
+{
129
+ pthread_rwlock_rdlock(&localhost.rrdset_root_rwlock);
130
+
131
+ // for each chart
132
+ RRDSET *st;
133
+ for(st = localhost.rrdset_root; st ; st = st->next) {
134
+ buffer_strcat(wb, "\n");
135
+ if(st->enabled && st->dimensions) {
136
+ // for each dimension
137
+ RRDDIM *rd;
138
+ for(rd = st->dimensions; rd ; rd = rd->next) {
139
+ if(rd->counter) {
140
+ buffer_sprintf(wb, "# HELP %s.%s %s\n", st->id, rd->id, st->units);
141
+
142
+ switch(rd->algorithm) {
143
+ case RRDDIM_INCREMENTAL:
144
+ case RRDDIM_PCENT_OVER_DIFF_TOTAL:
145
+ buffer_sprintf(wb, "# TYPE %s.%s counter\n", st->id, rd->id);
146
+ break;
147
+
148
+ default:
149
+ buffer_sprintf(wb, "# TYPE %s.%s gauge\n", st->id, rd->id);
150
+ break;
151
+ }
152
+
153
+ calculated_number n = (calculated_number)rd->last_collected_value * (calculated_number)(abs(rd->multiplier)) / (calculated_number)(abs(rd->divisor));
154
+
155
+ buffer_sprintf(wb, "%s.%s " CALCULATED_NUMBER_FORMAT " %llu\n", st->id, rd->id, n,
156
+ (unsigned long long)((rd->last_collected_time.tv_sec * 1000) + (rd->last_collected_time.tv_usec / 1000)));
157
+ }
158
+ }
159
+ }
160
+ }
161
+
162
+ pthread_rwlock_unlock(&localhost.rrdset_root_rwlock);
163
+}
164
165
unsigned long rrd_stats_one_json(RRDSET *st, char *options, BUFFER *wb)
166
{
src/rrd2json.h
+9
@@ -32,6 +32,12 @@ extern char *hostname;
32
#define DATASOURCE_FORMAT_SSV_COMMA "ssvcomma"
33
#define DATASOURCE_FORMAT_CSV_JSON_ARRAY "csvjsonarray"
34
35
+#define RAWMETRICS_FORMAT_BASH "bash"
36
+#define RAWMETRICS_FORMAT_PROMETHEUS "prometheus"
37
+
38
+#define RAWMETRICS_BASH 1
39
+#define RAWMETRICS_PROMETHEUS 2
40
+
41
#define GROUP_UNDEFINED 0
42
#define GROUP_AVERAGE 1
43
#define GROUP_MIN 2
@@ -56,6 +62,9 @@ extern char *hostname;
62
extern void rrd_stats_api_v1_chart(RRDSET *st, BUFFER *wb);
63
extern void rrd_stats_api_v1_charts(BUFFER *wb);
64
65
+// extern void rrd_stats_api_v1_charts_allmetrics_bash(BUFFER *wb);
66
+extern void rrd_stats_api_v1_charts_allmetrics_prometheus(BUFFER *wb);
67
+
68
extern unsigned long rrd_stats_one_json(RRDSET *st, char *options, BUFFER *wb);
69
70
extern void rrd_stats_graph_json(RRDSET *st, char *options, BUFFER *wb);
src/web_client.c
+44
-1
@@ -774,6 +774,45 @@ int web_client_api_request_v1_charts(struct web_client *w, char *url)
774
return 200;
775
}
776
777
+int web_client_api_request_v1_allmetrics(struct web_client *w, char *url)
778
+{
779
+ int format = 0;
780
+
781
+ while(url) {
782
+ char *value = mystrsep(&url, "?&");
783
+ if (!value || !*value) continue;
784
+
785
+ char *name = mystrsep(&value, "=");
786
+ if(!name || !*name) continue;
787
+ if(!value || !*value) continue;
788
+
789
+ if(!strcmp(name, "format")) {
790
+ if(!strcmp(value, RAWMETRICS_FORMAT_BASH))
791
+ format = RAWMETRICS_BASH;
792
+ else if(!strcmp(value, RAWMETRICS_FORMAT_PROMETHEUS))
793
+ format = RAWMETRICS_PROMETHEUS;
794
+ }
795
+ }
796
+
797
+ buffer_flush(w->response.data);
798
+ buffer_no_cacheable(w->response.data);
799
+ w->response.data->contenttype = CT_TEXT_PLAIN;
800
+
801
+ switch(format) {
802
+ //case RAWMETRICS_BASH:
803
+ // rrd_stats_api_v1_charts_allmetrics_bash(w->response.data);
804
+ // return 200;
805
+
806
+ case RAWMETRICS_PROMETHEUS:
807
+ rrd_stats_api_v1_charts_allmetrics_prometheus(w->response.data);
808
+ return 200;
809
+
810
+ default:
811
+ buffer_strcat(w->response.data, "Which format? Only '" RAWMETRICS_FORMAT_PROMETHEUS "' is currently supported.");
812
+ return 400;
813
+ }
814
+}
815
+
816
int web_client_api_request_v1_chart(struct web_client *w, char *url)
817
{
818
return web_client_api_request_single_chart(w, url, rrd_stats_api_v1_chart);
@@ -1377,7 +1416,7 @@ int web_client_api_request_v1_registry(struct web_client *w, char *url)
1416
}
1417
1418
int web_client_api_request_v1(struct web_client *w, char *url) {
1380
- static uint32_t hash_data = 0, hash_chart = 0, hash_charts = 0, hash_registry = 0, hash_badge = 0, hash_alarms = 0, hash_alarm_log = 0, hash_alarm_variables = 0;
1419
+ static uint32_t hash_data = 0, hash_chart = 0, hash_charts = 0, hash_registry = 0, hash_badge = 0, hash_alarms = 0, hash_alarm_log = 0, hash_alarm_variables = 0, hash_raw = 0;
1420
1421
if(unlikely(hash_data == 0)) {
1422
hash_data = simple_hash("data");
@@ -1388,6 +1427,7 @@ int web_client_api_request_v1(struct web_client *w, char *url) {
1427
hash_alarms = simple_hash("alarms");
1428
hash_alarm_log = simple_hash("alarm_log");
1429
hash_alarm_variables = simple_hash("alarm_variables");
1430
+ hash_raw = simple_hash("allmetrics");
1431
}
1432
1433
// get the command
@@ -1420,6 +1460,9 @@ int web_client_api_request_v1(struct web_client *w, char *url) {
1460
else if(hash == hash_alarm_variables && !strcmp(tok, "alarm_variables"))
1461
return web_client_api_request_v1_alarm_variables(w, url);
1462
1463
+ else if(hash == hash_raw && !strcmp(tok, "allmetrics"))
1464
+ return web_client_api_request_v1_allmetrics(w, url);
1465
+
1466
else {
1467
buffer_flush(w->response.data);
1468
buffer_strcat(w->response.data, "Unsupported v1 API command: ");