updated swagger and unified a few parameter names
Costa Tsaousis (ktsaou) committed
Dec 20, 2015 at 21:25 UTC
28b3e1ce923146b7e913ac5461dce21788df445f
6 files changed
+254
-35
README.md
+3
@@ -144,6 +144,9 @@ Out of the box, it comes with plugins for data collection about system informati
144
```
145
146
The above will give you the last 300 seconds of traffic for eth0, aggregated in 120 points, grouped as averages, in json format.
147
+
148
+ Check [Netdata Swagger UI](http://netdata.firehol.org/swagger/) for more information about the API.
149
+
150
151
2. If you need to embed a **netdata** chart on your web page, you can add a few javascript lines and a `div` for every graph you need. Check [this example](http://netdata.firehol.org/dashboard.html) (open it in a new tab and view its source to get the idea).
152
src/rrd2json.c
+3
-3
@@ -472,8 +472,8 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, uint32_t opti
472
" %sname%s: %s%s%s,\n"
473
" %sview_update_every%s: %d,\n"
474
" %supdate_every%s: %d,\n"
475
- " %sfirst_entry_t%s: %u,\n"
476
- " %slast_entry_t%s: %u,\n"
475
+ " %sfirst_entry%s: %u,\n"
476
+ " %slast_entry%s: %u,\n"
477
" %smin%s: "
478
, kq, kq
479
, kq, kq, sq, r->st->id, sq
@@ -560,7 +560,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb, uint32_t format, uint32_t opti
560
}
561
562
buffer_sprintf(wb, "],\n"
563
- " %sresult_latest_values%s: ["
563
+ " %sview_latest_values%s: ["
564
, kq, kq);
565
566
i = 0;
src/web_client.c
+34
-11
@@ -568,8 +568,8 @@ int web_client_api_request_v1_data(struct web_client *w, char *url)
568
*google_reqId = "0",
569
*google_sig = "0",
570
*google_out = "json",
571
- *google_responseHandler = "google.visualization.Query.setResponse",
572
- *google_outFileName = NULL;
571
+ *responseHandler = NULL,
572
+ *outFileName = NULL;
573
574
time_t last_timestamp_in_data = 0, google_timestamp = 0;
575
@@ -614,6 +614,12 @@ int web_client_api_request_v1_data(struct web_client *w, char *url)
614
else if(!strcmp(name, "options")) {
615
options |= web_client_api_request_v1_data_options(value);
616
}
617
+ else if(!strcmp(name, "callback")) {
618
+ responseHandler = value;
619
+ }
620
+ else if(!strcmp(name, "filename")) {
621
+ outFileName = value;
622
+ }
623
else if(!strcmp(name, "tqx")) {
624
// parse Google Visualization API options
625
// https://developers.google.com/chart/interactive/docs/dev/implementing_data_source
@@ -640,9 +646,9 @@ int web_client_api_request_v1_data(struct web_client *w, char *url)
646
format = web_client_api_request_v1_data_google_format(google_out);
647
}
648
else if(!strcmp(tqx_name, "responseHandler"))
643
- google_responseHandler = tqx_value;
649
+ responseHandler = tqx_value;
650
else if(!strcmp(tqx_name, "outFileName"))
645
- google_outFileName = tqx_value;
651
+ outFileName = tqx_value;
652
}
653
}
654
}
@@ -676,19 +682,29 @@ int web_client_api_request_v1_data(struct web_client *w, char *url)
682
, options
683
);
684
679
- if(google_outFileName && *google_outFileName) {
680
- buffer_sprintf(w->response.header, "Content-Disposition: attachment; filename=\"%s\"\r\n", google_outFileName);
681
- error("generating outfilename header: '%s'", google_outFileName);
685
+ if(outFileName && *outFileName) {
686
+ buffer_sprintf(w->response.header, "Content-Disposition: attachment; filename=\"%s\"\r\n", outFileName);
687
+ error("generating outfilename header: '%s'", outFileName);
688
}
689
690
if(format == DATASOURCE_DATATABLE_JSONP) {
691
+ if(responseHandler == NULL)
692
+ responseHandler = "google.visualization.Query.setResponse";
693
+
694
debug(D_WEB_CLIENT_ACCESS, "%llu: GOOGLE JSON/JSONP: version = '%s', reqId = '%s', sig = '%s', out = '%s', responseHandler = '%s', outFileName = '%s'",
686
- w->id, google_version, google_reqId, google_sig, google_out, google_responseHandler, google_outFileName
695
+ w->id, google_version, google_reqId, google_sig, google_out, responseHandler, outFileName
696
);
697
698
buffer_sprintf(w->response.data,
699
"%s({version:'%s',reqId:'%s',status:'ok',sig:'%lu',table:",
691
- google_responseHandler, google_version, google_reqId, st->last_updated.tv_sec);
700
+ responseHandler, google_version, google_reqId, st->last_updated.tv_sec);
701
+ }
702
+ else if(format == DATASOURCE_JSONP) {
703
+ if(responseHandler == NULL)
704
+ responseHandler = "callback";
705
+
706
+ buffer_strcat(w->response.data, responseHandler);
707
+ buffer_strcat(w->response.data, "(");
708
}
709
710
ret = rrd2format(st, w->response.data, dimensions, format, points, after, before, group, options, &last_timestamp_in_data);
@@ -702,9 +718,11 @@ int web_client_api_request_v1_data(struct web_client *w, char *url)
718
buffer_flush(w->response.data);
719
buffer_sprintf(w->response.data,
720
"%s({version:'%s',reqId:'%s',status:'error',errors:[{reason:'not_modified',message:'Data not modified'}]});",
705
- google_responseHandler, google_version, google_reqId);
721
+ responseHandler, google_version, google_reqId);
722
}
723
}
724
+ else if(format == DATASOURCE_JSONP)
725
+ buffer_strcat(w->response.data, ");");
726
727
cleanup:
728
if(dimensions) buffer_free(dimensions);
@@ -1257,6 +1275,8 @@ void web_client_process(struct web_client *w) {
1275
"Server: NetData Embedded HTTP Server\r\n"
1276
"Content-Type: %s\r\n"
1277
"Access-Control-Allow-Origin: *\r\n"
1278
+ "Access-Control-Allow-Methods: GET\r\n"
1279
+ "Access-Control-Allow-Headers: x-requested-with\r\n"
1280
"Date: %s\r\n"
1281
, code, code_msg
1282
, w->keepalive?"keep-alive":"close"
@@ -1271,10 +1291,13 @@ void web_client_process(struct web_client *w) {
1291
buffer_sprintf(w->response.header_output,
1292
"Expires: %s\r\n"
1293
"Cache-Control: no-cache\r\n"
1294
+ "Access-Control-Max-Age: 0\r\n"
1295
, date);
1296
}
1276
- else
1297
+ else {
1298
buffer_strcat(w->response.header_output, "Cache-Control: public\r\n");
1299
+ buffer_strcat(w->response.header_output, "Access-Control-Max-Age: 3600\r\n");
1300
+ }
1301
1302
// if we know the content length, put it
1303
if(!w->response.zoutput && (w->response.data->len || w->response.rlen))
web/dashboard.js
+11
-11
@@ -981,7 +981,7 @@
981
}
982
983
var show_undefined = true;
984
- if(Math.abs(this.current.data.last_entry_t - this.current.data.before) <= this.current.data.view_update_every)
984
+ if(Math.abs(this.current.data.last_entry - this.current.data.before) <= this.current.data.view_update_every)
985
show_undefined = false;
986
987
if(show_undefined)
@@ -1000,7 +1000,7 @@
1000
if(show_undefined)
1001
this.legendSetLabelValue(label, null);
1002
else
1003
- this.legendSetLabelValue(label, this.current.data.result_latest_values[i]);
1003
+ this.legendSetLabelValue(label, this.current.data.view_latest_values[i]);
1004
}
1005
}
1006
@@ -1089,7 +1089,7 @@
1089
1090
// do we have to update the current values?
1091
// we do this, only when the visible chart is current
1092
- if(Math.abs(this.current.data.last_entry_t - this.current.data.before) <= this.current.data.view_update_every) {
1092
+ if(Math.abs(this.current.data.last_entry - this.current.data.before) <= this.current.data.view_update_every) {
1093
if(this.debug === true)
1094
this.log('chart in running... updating values on legend...');
1095
@@ -1427,11 +1427,11 @@
1427
if(typeof data.before !== 'undefined')
1428
this.current.before_ms = data.before * 1000;
1429
1430
- if(typeof data.first_entry_t !== 'undefined')
1431
- this.current.first_entry_ms = data.first_entry_t * 1000;
1430
+ if(typeof data.first_entry !== 'undefined')
1431
+ this.current.first_entry_ms = data.first_entry * 1000;
1432
1433
- if(typeof data.last_entry_t !== 'undefined')
1434
- this.current.last_entry_ms = data.last_entry_t * 1000;
1433
+ if(typeof data.last_entry !== 'undefined')
1434
+ this.current.last_entry_ms = data.last_entry * 1000;
1435
1436
if(typeof data.points !== 'undefined')
1437
this.current.points = data.points;
@@ -2808,8 +2808,8 @@
2808
if(NETDATA.options.debug.dygraph === true)
2809
state.log('dygraphDrawCallback()');
2810
2811
- var first = state.current.data.first_entry_t * 1000;
2812
- var last = state.current.data.last_entry_t * 1000;
2811
+ var first = state.current.data.first_entry * 1000;
2812
+ var last = state.current.data.last_entry * 1000;
2813
2814
var x_range = dygraph.xAxisRange();
2815
var after = Math.round(x_range[0]);
@@ -3029,8 +3029,8 @@
3029
var after = new_x_range[0];
3030
var before = new_x_range[1];
3031
3032
- var first = (state.current.data.first_entry_t + state.current.data.view_update_every) * 1000;
3033
- var last = (state.current.data.last_entry_t + state.current.data.view_update_every) * 1000;
3032
+ var first = (state.current.data.first_entry + state.current.data.view_update_every) * 1000;
3033
+ var last = (state.current.data.last_entry + state.current.data.view_update_every) * 1000;
3034
3035
if(before > last) {
3036
after -= (before - last);
web/netdata-swagger.json
+117
-6
@@ -5,6 +5,7 @@
5
"description": "Real time monitoring for linux, over the web!",
6
"version": "1.0.0"
7
},
8
+ "host": "195.97.5.206:19999",
9
"schemes": [
10
"http"
11
],
@@ -41,7 +42,8 @@
42
"description": "The id of the chart as returned by the /charts call.",
43
"required": true,
44
"type": "string",
44
- "format": "as returned by /charts"
45
+ "format": "as returned by /charts",
46
+ "default": "system.cpu"
47
}
48
],
49
"responses": {
@@ -69,7 +71,8 @@
71
"required": true,
72
"type": "string",
73
"format": "as returned by /charts",
72
- "allowEmptyValue": false
74
+ "allowEmptyValue": false,
75
+ "default": "system.cpu"
76
},
77
{
78
"name": "dimension",
@@ -112,7 +115,7 @@
115
"type": "number",
116
"format": "integer",
117
"allowEmptyValue": false,
115
- "default": 100
118
+ "default": 20
119
},
120
{
121
"name": "group",
@@ -124,7 +127,7 @@
127
"max",
128
"average"
129
],
127
- "default": "max",
130
+ "default": "average",
131
"allowEmptyValue": false
132
},
133
{
@@ -174,15 +177,31 @@
177
"collectionFormat": "pipes",
178
"format": ""
179
},
180
+ "default": "seconds|jsonwrap",
181
"allowEmptyValue": false
182
},
183
{
180
- "name": "tqx",
184
+ "name": "callback",
185
"in": "query",
182
- "description": "[Google Visualization API](https://developers.google.com/chart/interactive/docs/dev/implementing_data_source?hl=en) formatted parameter.",
186
+ "description": "For JSONP responses, the callback function name.",
187
"required": false,
188
"type": "string",
189
"allowEmptyValue": false
190
+ },
191
+ {
192
+ "name": "filename",
193
+ "in": "query",
194
+ "description": "Add Content-Disposition: attachment; filename=<filename> header to the response, that will instruct the browser to save the response with the given filename.",
195
+ "required": false,
196
+ "type": "string",
197
+ "allowEmptyValue": false
198
+ },
199
+ {
200
+ "name": "tqx",
201
+ "in": "query",
202
+ "description": "[Google Visualization API](https://developers.google.com/chart/interactive/docs/dev/implementing_data_source?hl=en) formatted parameter.",
203
+ "required": false,
204
+ "type": "string"
205
}
206
],
207
"responses": {
@@ -311,6 +330,98 @@
330
"description": "The name of the dimension"
331
}
332
}
333
+ },
334
+ "json_wrap": {
335
+ "type": "object",
336
+ "properties": {
337
+ "api": {
338
+ "type": "number",
339
+ "description": "The API version this conforms to, currently 1"
340
+ },
341
+ "id": {
342
+ "type": "string",
343
+ "description": "The unique id of the chart"
344
+ },
345
+ "name": {
346
+ "type": "string",
347
+ "description": "The name of the chart"
348
+ },
349
+ "update_every": {
350
+ "type": "number",
351
+ "description": "The update frequency of this chart, in seconds. One value every this amount of time is kept in the round robin database (indepedently of the current view)."
352
+ },
353
+ "view_update_every": {
354
+ "type": "number",
355
+ "description": "The current view appropriate update frequency of this chart, in seconds. There is no point to request chart refreshes, using the same settings, more frequently than this."
356
+ },
357
+ "first_entry": {
358
+ "type": "number",
359
+ "description": "The UNIX timestamp of the first entry (the oldest) in the round robin database (indepedently of the current view)."
360
+ },
361
+ "last_entry": {
362
+ "type": "number",
363
+ "description": "The UNIX timestamp of the latest entry in the round robin database (indepedently of the current view)."
364
+ },
365
+ "after": {
366
+ "type": "number",
367
+ "description": "The UNIX timestamp of the first entry (the oldest) returned in this response."
368
+ },
369
+ "before": {
370
+ "type": "number",
371
+ "description": "The UNIX timestamp of the latest entry returned in this response."
372
+ },
373
+ "min": {
374
+ "type": "number",
375
+ "description": "The minimum value returned in the current view. This can be used to size the y-series of the chart."
376
+ },
377
+ "max": {
378
+ "type": "number",
379
+ "description": "The maximum value returned in the current view. This can be used to size the y-series of the chart."
380
+ },
381
+ "dimension_names": {
382
+ "description": "The dimension names of the chart as returned in the current view.",
383
+ "type": "array",
384
+ "items": {
385
+ "type": "string"
386
+ }
387
+ },
388
+ "dimension_ids": {
389
+ "description": "The dimension IDs of the chart as returned in the current view.",
390
+ "type": "array",
391
+ "items": {
392
+ "type": "string"
393
+ }
394
+ },
395
+ "latest_values": {
396
+ "description": "The latest values collected for the chart (indepedently of the current view).",
397
+ "type": "array",
398
+ "items": {
399
+ "type": "string"
400
+ }
401
+ },
402
+ "view_latest_values": {
403
+ "description": "The latest values returned with this response.",
404
+ "type": "array",
405
+ "items": {
406
+ "type": "string"
407
+ }
408
+ },
409
+ "dimensions": {
410
+ "type": "number",
411
+ "description": "The number of dimensions returned."
412
+ },
413
+ "points": {
414
+ "type": "number",
415
+ "description": "The number of rows / points returned."
416
+ },
417
+ "format": {
418
+ "type": "string",
419
+ "description": "The format of the result returned."
420
+ },
421
+ "result": {
422
+ "description": "The result requested, in the format requested."
423
+ }
424
+ }
425
}
426
}
427
}
\ No newline at end of file
web/netdata-swagger.yaml
+86
-4
@@ -3,6 +3,7 @@ info:
3
title: NetData API
4
description: 'Real time monitoring for linux, over the web!'
5
version: 1.0.0
6
+host: 195.97.5.206:19999
7
schemes:
8
- http
9
basePath: /api/v1
@@ -31,6 +32,7 @@ paths:
32
required: true
33
type: string
34
format: 'as returned by /charts'
35
+ default: 'system.cpu'
36
responses:
37
'200':
38
description: 'A javascript object with detailed information about the chart.'
@@ -51,6 +53,7 @@ paths:
53
type: string
54
format: 'as returned by /charts'
55
allowEmptyValue: false
56
+ default: system.cpu
57
- name: dimension
58
in: query
59
description: 'zero, one or more dimension ids, as returned by the /chart call.'
@@ -84,14 +87,14 @@ paths:
87
type: number
88
format: integer
89
allowEmptyValue: false
87
- default: 100
90
+ default: 20
91
- name: group
92
in: query
93
description: 'The grouping method. If multiple collected values are to be grouped in order to return fewer points, this parameters defines the method of grouping. Two methods are supported, "max" and "average". "max" is actually calculated on the absolute value collected (so it works for both positive and negative dimesions to return the most extreme value in either direction).'
94
required: true
95
type: string
96
enum: [ 'max', 'average' ]
94
- default: 'max'
97
+ default: 'average'
98
allowEmptyValue: false
99
- name: format
100
in: query
@@ -111,13 +114,25 @@ paths:
114
enum: [ 'nonzero', 'flip', 'jsonwrap', 'min2max', 'seconds', 'milliseconds', 'abs', 'absolute', 'absolute-sum', 'null2zero', 'objectrows', 'google_json' ]
115
collectionFormat: pipes
116
format: ''
117
+ default: seconds|jsonwrap
118
+ allowEmptyValue: false
119
+ - name: callback
120
+ in: query
121
+ description: 'For JSONP responses, the callback function name.'
122
+ required: false
123
+ type: string
124
+ allowEmptyValue: false
125
+ - name: filename
126
+ in: query
127
+ description: 'Add Content-Disposition: attachment; filename=<filename> header to the response, that will instruct the browser to save the response with the given filename.'
128
+ required: false
129
+ type: string
130
allowEmptyValue: false
131
- name: tqx
132
in: query
133
description: '[Google Visualization API](https://developers.google.com/chart/interactive/docs/dev/implementing_data_source?hl=en) formatted parameter.'
134
required: false
135
type: string
120
- allowEmptyValue: false
136
responses:
137
'200':
138
description: 'The call was successful. The response should include the data.'
@@ -204,4 +219,71 @@ definitions:
219
name:
220
type: string
221
description: 'The name of the dimension'
207
-
222
+
223
+ json_wrap:
224
+ type: object
225
+ properties:
226
+ api:
227
+ type: number
228
+ description: 'The API version this conforms to, currently 1'
229
+ id:
230
+ type: string
231
+ description: 'The unique id of the chart'
232
+ name:
233
+ type: string
234
+ description: 'The name of the chart'
235
+ update_every:
236
+ type: number
237
+ description: 'The update frequency of this chart, in seconds. One value every this amount of time is kept in the round robin database (indepedently of the current view).'
238
+ view_update_every:
239
+ type: number
240
+ description: 'The current view appropriate update frequency of this chart, in seconds. There is no point to request chart refreshes, using the same settings, more frequently than this.'
241
+ first_entry:
242
+ type: number
243
+ description: 'The UNIX timestamp of the first entry (the oldest) in the round robin database (indepedently of the current view).'
244
+ last_entry:
245
+ type: number
246
+ description: 'The UNIX timestamp of the latest entry in the round robin database (indepedently of the current view).'
247
+ after:
248
+ type: number
249
+ description: 'The UNIX timestamp of the first entry (the oldest) returned in this response.'
250
+ before:
251
+ type: number
252
+ description: 'The UNIX timestamp of the latest entry returned in this response.'
253
+ min:
254
+ type: number
255
+ description: 'The minimum value returned in the current view. This can be used to size the y-series of the chart.'
256
+ max:
257
+ type: number
258
+ description: 'The maximum value returned in the current view. This can be used to size the y-series of the chart.'
259
+ dimension_names:
260
+ description: 'The dimension names of the chart as returned in the current view.'
261
+ type: array
262
+ items:
263
+ type: string
264
+ dimension_ids:
265
+ description: 'The dimension IDs of the chart as returned in the current view.'
266
+ type: array
267
+ items:
268
+ type: string
269
+ latest_values:
270
+ description: 'The latest values collected for the chart (indepedently of the current view).'
271
+ type: array
272
+ items:
273
+ type: string
274
+ view_latest_values:
275
+ description: 'The latest values returned with this response.'
276
+ type: array
277
+ items:
278
+ type: string
279
+ dimensions:
280
+ type: number
281
+ description: 'The number of dimensions returned.'
282
+ points:
283
+ type: number
284
+ description: 'The number of rows / points returned.'
285
+ format:
286
+ type: string
287
+ description: 'The format of the result returned.'
288
+ result:
289
+ description: 'The result requested, in the format requested.'