diff options
Diffstat (limited to '')
-rw-r--r-- | src/web/api/formatters/README.md | 82 | ||||
-rw-r--r-- | src/web/api/formatters/charts2json.c (renamed from web/api/formatters/charts2json.c) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/charts2json.h (renamed from web/api/formatters/charts2json.h) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/csv/README.md | 148 | ||||
-rw-r--r-- | src/web/api/formatters/csv/csv.c (renamed from web/api/formatters/csv/csv.c) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/csv/csv.h (renamed from web/api/formatters/csv/csv.h) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/json/README.md | 160 | ||||
-rw-r--r-- | src/web/api/formatters/json/json.c (renamed from web/api/formatters/json/json.c) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/json/json.h (renamed from web/api/formatters/json/json.h) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/json_wrapper.c (renamed from web/api/formatters/json_wrapper.c) | 24 | ||||
-rw-r--r-- | src/web/api/formatters/json_wrapper.h (renamed from web/api/formatters/json_wrapper.h) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/rrd2json.c (renamed from web/api/formatters/rrd2json.c) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/rrd2json.h (renamed from web/api/formatters/rrd2json.h) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/rrdset2json.c (renamed from web/api/formatters/rrdset2json.c) | 4 | ||||
-rw-r--r-- | src/web/api/formatters/rrdset2json.h (renamed from web/api/formatters/rrdset2json.h) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/ssv/README.md | 63 | ||||
-rw-r--r-- | src/web/api/formatters/ssv/ssv.c (renamed from web/api/formatters/ssv/ssv.c) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/ssv/ssv.h (renamed from web/api/formatters/ssv/ssv.h) | 0 | ||||
-rw-r--r-- | src/web/api/formatters/value/README.md | 28 | ||||
-rw-r--r-- | src/web/api/formatters/value/value.c (renamed from web/api/formatters/value/value.c) | 68 | ||||
-rw-r--r-- | src/web/api/formatters/value/value.h (renamed from web/api/formatters/value/value.h) | 0 |
21 files changed, 530 insertions, 47 deletions
diff --git a/src/web/api/formatters/README.md b/src/web/api/formatters/README.md new file mode 100644 index 000000000..df1ae7867 --- /dev/null +++ b/src/web/api/formatters/README.md @@ -0,0 +1,82 @@ +<!-- +title: "Query formatting" +custom_edit_url: https://github.com/netdata/netdata/edit/master/src/web/api/formatters/README.md +sidebar_label: "Query formatting" +learn_status: "Published" +learn_topic_type: "References" +learn_rel_path: "Developers/Web/Api/Formatters" +--> + +# Query formatting + +API data queries need to be formatted before returned to the caller. +Using API parameters, the caller may define the format he/she wishes to get back. + +The following formats are supported: + +| format|module|content type|description| +|:----:|:----:|:----------:|:----------| +| `array`|[ssv](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/ssv/README.md)|application/json|a JSON array| +| `csv`|[csv](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/csv/README.md)|text/plain|a text table, comma separated, with a header line (dimension names) and `\r\n` at the end of the lines| +| `csvjsonarray`|[csv](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/csv/README.md)|application/json|a JSON array, with each row as another array (the first row has the dimension names)| +| `datasource`|[json](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/json/README.md)|application/json|a Google Visualization Provider `datasource` javascript callback| +| `datatable`|[json](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/json/README.md)|application/json|a Google `datatable`| +| `html`|[csv](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/csv/README.md)|text/html|an html table| +| `json`|[json](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/json/README.md)|application/json|a JSON object| +| `jsonp`|[json](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/json/README.md)|application/json|a JSONP javascript callback| +| `markdown`|[csv](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/csv/README.md)|text/plain|a markdown table| +| `ssv`|[ssv](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/ssv/README.md)|text/plain|a space separated list of values| +| `ssvcomma`|[ssv](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/ssv/README.md)|text/plain|a comma separated list of values| +| `tsv`|[csv](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/csv/README.md)|text/plain|a TAB delimited `csv` (MS Excel flavor)| + +For examples of each format, check the relative module documentation. + +## Metadata with the `jsonwrap` option + +All data queries can be encapsulated to JSON object having metadata about the query and the results. + +This is done by adding the `options=jsonwrap` to the API URL (if there are other `options` append +`,jsonwrap` to the existing ones). + +This is such an object: + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=system.cpu&after=-3600&points=6&group=average&format=csv&options=nonzero,jsonwrap' +{ + "api": 1, + "id": "system.cpu", + "name": "system.cpu", + "view_update_every": 600, + "update_every": 1, + "first_entry": 1540387074, + "last_entry": 1540647070, + "before": 1540647000, + "after": 1540644000, + "dimension_names": ["steal", "softirq", "user", "system", "iowait"], + "dimension_ids": ["steal", "softirq", "user", "system", "iowait"], + "latest_values": [0, 0.2493766, 1.745636, 0.4987531, 0], + "view_latest_values": [0.0158314, 0.0516506, 0.866549, 0.7196127, 0.0050002], + "dimensions": 5, + "points": 6, + "format": "csv", + "result": "time,steal,softirq,user,system,iowait\n2018-10-27 13:30:00,0.0158314,0.0516506,0.866549,0.7196127,0.0050002\n2018-10-27 13:20:00,0.0149856,0.0529183,0.8673155,0.7121144,0.0049979\n2018-10-27 13:10:00,0.0137501,0.053315,0.8578097,0.7197613,0.0054209\n2018-10-27 13:00:00,0.0154252,0.0554688,0.899432,0.7200638,0.0067252\n2018-10-27 12:50:00,0.0145866,0.0495922,0.8404341,0.7011141,0.0041688\n2018-10-27 12:40:00,0.0162366,0.0595954,0.8827475,0.7020573,0.0041636\n", + "min": 0, + "max": 0 +} +``` + +## Downloading data query result files + +Following the [Google Visualization Provider guidelines](https://developers.google.com/chart/interactive/docs/dev/implementing_data_source), +Netdata supports parsing `tqx` options. + +Using these options, any Netdata data query can instruct the web browser to download +the result and save it under a given filename. + +For example, to download a CSV file with CPU utilization of the last hour, +[click here](https://registry.my-netdata.io/api/v1/data?chart=system.cpu&after=-3600&format=csv&options=nonzero&tqx=outFileName:system+cpu+utilization+of+the+last_hour.csv). + +This is done by appending `&tqx=outFileName:FILENAME` to any data query. +The output will be in the format given with `&format=`. + + diff --git a/web/api/formatters/charts2json.c b/src/web/api/formatters/charts2json.c index cab4debae..cab4debae 100644 --- a/web/api/formatters/charts2json.c +++ b/src/web/api/formatters/charts2json.c diff --git a/web/api/formatters/charts2json.h b/src/web/api/formatters/charts2json.h index 7b07af5a0..7b07af5a0 100644 --- a/web/api/formatters/charts2json.h +++ b/src/web/api/formatters/charts2json.h diff --git a/src/web/api/formatters/csv/README.md b/src/web/api/formatters/csv/README.md new file mode 100644 index 000000000..ee5e3666f --- /dev/null +++ b/src/web/api/formatters/csv/README.md @@ -0,0 +1,148 @@ +<!-- +title: "CSV formatter" +custom_edit_url: https://github.com/netdata/netdata/edit/master/src/web/api/formatters/csv/README.md +sidebar_label: "CSV formatter" +learn_status: "Published" +learn_topic_type: "References" +learn_rel_path: "Developers/Web/Api/Formatters" +--> + +# CSV formatter + +The CSV formatter presents [results of database queries](https://github.com/netdata/netdata/blob/master/src/web/api/queries/README.md) in the following formats: + +| format|content type|description| +| :----:|:----------:|:----------| +| `csv`|text/plain|a text table, comma separated, with a header line (dimension names) and `\r\n` at the end of the lines| +| `csvjsonarray`|application/json|a JSON array, with each row as another array (the first row has the dimension names)| +| `tsv`|text/plain|like `csv` but TAB is used instead of comma to separate values (MS Excel flavor)| +| `html`|text/html|an html table| +| `markdown`|text/plain|markdown table| + +In all formats the date and time is the first column. + +The CSV formatter respects the following API `&options=`: + +| option|supported|description| +|:----:|:-------:|:----------| +| `nonzero`|yes|to return only the dimensions that have at least a non-zero value| +| `flip`|yes|to return the rows older to newer (the default is newer to older)| +| `seconds`|yes|to return the date and time in unix timestamp| +| `ms`|yes|to return the date and time in unit timestamp as milliseconds| +| `percent`|yes|to replace all values with their percentage over the row total| +| `abs`|yes|to turn all values positive| +| `null2zero`|yes|to replace gaps with zeros (the default prints the string `null`| + +## Examples + +Get the system total bandwidth for all physical network interfaces, over the last hour, +in 6 rows (one for every 10 minutes), in `csv` format: + +Netdata always returns bandwidth in `kilobits`. + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=system.net&format=csv&after=-3600&group=sum&points=6&options=abs' +time,received,sent +2018-10-26 23:50:00,90214.67847,215137.79762 +2018-10-26 23:40:00,90126.32286,238587.57522 +2018-10-26 23:30:00,86061.22688,213389.23526 +2018-10-26 23:20:00,85590.75164,206129.01608 +2018-10-26 23:10:00,83163.30691,194311.77384 +2018-10-26 23:00:00,85167.29657,197538.07773 +``` + +--- + +Get the max RAM used by the SQL server and any cron jobs, over the last hour, in 2 rows (one for every 30 +minutes), in `tsv` format, and format the date and time as unix timestamp: + +Netdata always returns memory in `MB`. + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=apps.mem&format=tsv&after=-3600&group=max&points=2&options=nonzero,seconds&dimensions=sql,cron' +time sql cron +1540598400 61.95703 0.25 +1540596600 61.95703 0.25 +``` + +--- + +Get an HTML table of the last 4 values (4 seconds) of system CPU utilization: + +Netdata always returns CPU utilization as `%`. + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=system.cpu&format=html&after=-4&options=nonzero' +<html> +<center> +<table border="0" cellpadding="5" cellspacing="5"> +<tr><td>time</td><td>softirq</td><td>user</td><td>system</td></tr> +<tr><td>2018-10-27 00:16:07</td><td>0.25</td><td>1</td><td>0.75</td></tr> +<tr><td>2018-10-27 00:16:06</td><td>0</td><td>1.0025063</td><td>0.5012531</td></tr> +<tr><td>2018-10-27 00:16:05</td><td>0</td><td>1</td><td>0.75</td></tr> +<tr><td>2018-10-27 00:16:04</td><td>0</td><td>1.0025063</td><td>0.7518797</td></tr> +</table> +</center> +</html> +``` + +This is how it looks when rendered by a web browser: + +![image](https://user-images.githubusercontent.com/2662304/47597887-bafbf480-d99c-11e8-864a-d880bb8d2e5b.png) + +--- + +Get a JSON array with the average bandwidth rate of the mysql server, over the last hour, in 6 values +(one every 10 minutes), and return the date and time in milliseconds: + +Netdata always returns bandwidth rates in `kilobits/s`. + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=mysql_local.net&format=csvjsonarray&after=-3600&points=6&group=average&options=abs,ms' +[ +["time","in","out"], +[1540599600000,0.7499986,120.2810185], +[1540599000000,0.7500019,120.2815509], +[1540598400000,0.7499999,120.2812319], +[1540597800000,0.7500044,120.2819634], +[1540597200000,0.7499968,120.2807337], +[1540596600000,0.7499988,120.2810527] +] +``` + +--- + +Get the number of processes started per minute, for the last 10 minutes, in `markdown` format: + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=system.forks&format=markdown&after=-600&points=10&group=sum' +time | started +:---: |:---: +2018-10-27 03:52:00| 245.1706149 +2018-10-27 03:51:00| 152.6654636 +2018-10-27 03:50:00| 163.1755789 +2018-10-27 03:49:00| 176.1574766 +2018-10-27 03:48:00| 178.0137076 +2018-10-27 03:47:00| 183.8306543 +2018-10-27 03:46:00| 264.1635621 +2018-10-27 03:45:00| 205.001551 +2018-10-27 03:44:00| 7026.9852167 +2018-10-27 03:43:00| 205.9904794 +``` + +And this is how it looks when formatted: + +| time | started | +|:--:|:-----:| +| 2018-10-27 03:52:00 | 245.1706149 | +| 2018-10-27 03:51:00 | 152.6654636 | +| 2018-10-27 03:50:00 | 163.1755789 | +| 2018-10-27 03:49:00 | 176.1574766 | +| 2018-10-27 03:48:00 | 178.0137076 | +| 2018-10-27 03:47:00 | 183.8306543 | +| 2018-10-27 03:46:00 | 264.1635621 | +| 2018-10-27 03:45:00 | 205.001551 | +| 2018-10-27 03:44:00 | 7026.9852167 | +| 2018-10-27 03:43:00 | 205.9904794 | + + diff --git a/web/api/formatters/csv/csv.c b/src/web/api/formatters/csv/csv.c index d81ddb34e..d81ddb34e 100644 --- a/web/api/formatters/csv/csv.c +++ b/src/web/api/formatters/csv/csv.c diff --git a/web/api/formatters/csv/csv.h b/src/web/api/formatters/csv/csv.h index 666d4c660..666d4c660 100644 --- a/web/api/formatters/csv/csv.h +++ b/src/web/api/formatters/csv/csv.h diff --git a/src/web/api/formatters/json/README.md b/src/web/api/formatters/json/README.md new file mode 100644 index 000000000..b0037cb2e --- /dev/null +++ b/src/web/api/formatters/json/README.md @@ -0,0 +1,160 @@ +<!-- +title: "JSON formatter" +custom_edit_url: https://github.com/netdata/netdata/edit/master/src/web/api/formatters/json/README.md +sidebar_label: "JSON formatter" +learn_status: "Published" +learn_topic_type: "References" +learn_rel_path: "Developers/Web/Api/Formatters" +--> + +# JSON formatter + +The CSV formatter presents [results of database queries](https://github.com/netdata/netdata/blob/master/src/web/api/queries/README.md) in the following formats: + +| format | content type | description| +|:----:|:----------:|:----------| +| `json` | application/json | return the query result as a json object| +| `jsonp` | application/json | return the query result as a JSONP javascript callback| +| `datatable` | application/json | return the query result as a Google `datatable`| +| `datasource` | application/json | return the query result as a Google Visualization Provider `datasource` javascript callback| + +The CSV formatter respects the following API `&options=`: + +| option | supported | description| +|:----:|:-------:|:----------| +| `google_json` | yes | enable the Google flavor of JSON (using double quotes for strings and `Date()` function for dates| +| `objectrows` | yes | return each row as an object, instead of an array| +| `nonzero` | yes | to return only the dimensions that have at least a non-zero value| +| `flip` | yes | to return the rows older to newer (the default is newer to older)| +| `seconds` | yes | to return the date and time in unix timestamp| +| `ms` | yes | to return the date and time in unit timestamp as milliseconds| +| `percent` | yes | to replace all values with their percentage over the row total| +| `abs` | yes | to turn all values positive| +| `null2zero` | yes | to replace gaps with zeros (the default prints the string `null`| + +## Examples + +To show the differences between each format, in the following examples we query the same +chart (having just one dimension called `active`), changing only the query `format` and its `options`. + +> Using `format=json` and `options=` + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&after=-3600&points=6&group=average&format=json&options=' +{ + "labels": ["time", "active"], + "data": + [ + [ 1540644600, 224.2516667], + [ 1540644000, 229.29], + [ 1540643400, 222.41], + [ 1540642800, 226.6816667], + [ 1540642200, 246.4083333], + [ 1540641600, 241.0966667] + ] +} +``` + +> Using `format=json` and `options=objectrows` + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&after=-3600&points=6&group=average&format=json&options=objectrows' +{ + "labels": ["time", "active"], + "data": + [ + { "time": 1540644600, "active": 224.2516667}, + { "time": 1540644000, "active": 229.29}, + { "time": 1540643400, "active": 222.41}, + { "time": 1540642800, "active": 226.6816667}, + { "time": 1540642200, "active": 246.4083333}, + { "time": 1540641600, "active": 241.0966667} + ] +} +``` + +> Using `format=json` and `options=objectrows,google_json` + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&after=-3600&points=6&group=average&formatjson&options=objectrows,google_json' +{ + "labels": ["time", "active"], + "data": + [ + { "time": new Date(2018,9,27,12,50,0), "active": 224.2516667}, + { "time": new Date(2018,9,27,12,40,0), "active": 229.29}, + { "time": new Date(2018,9,27,12,30,0), "active": 222.41}, + { "time": new Date(2018,9,27,12,20,0), "active": 226.6816667}, + { "time": new Date(2018,9,27,12,10,0), "active": 246.4083333}, + { "time": new Date(2018,9,27,12,0,0), "active": 241.0966667} + ] +} +``` + +> Using `format=jsonp` and `options=` + +```bash +curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&after=-3600&points=6&group=average&formjsonp&options=' +callback({ + "labels": ["time", "active"], + "data": + [ + [ 1540645200, 235.885], + [ 1540644600, 224.2516667], + [ 1540644000, 229.29], + [ 1540643400, 222.41], + [ 1540642800, 226.6816667], + [ 1540642200, 246.4083333] + ] +}); +``` + +> Using `format=datatable` and `options=` + +```bash +curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&after=-3600&points=6&group=average&formdatatable&options=' +{ + "cols": + [ + {"id":"","label":"time","pattern":"","type":"datetime"}, + {"id":"","label":"","pattern":"","type":"string","p":{"role":"annotation"}}, + {"id":"","label":"","pattern":"","type":"string","p":{"role":"annotationText"}}, + {"id":"","label":"active","pattern":"","type":"number"} + ], + "rows": + [ + {"c":[{"v":"Date(2018,9,27,13,0,0)"},{"v":null},{"v":null},{"v":235.885}]}, + {"c":[{"v":"Date(2018,9,27,12,50,0)"},{"v":null},{"v":null},{"v":224.2516667}]}, + {"c":[{"v":"Date(2018,9,27,12,40,0)"},{"v":null},{"v":null},{"v":229.29}]}, + {"c":[{"v":"Date(2018,9,27,12,30,0)"},{"v":null},{"v":null},{"v":222.41}]}, + {"c":[{"v":"Date(2018,9,27,12,20,0)"},{"v":null},{"v":null},{"v":226.6816667}]}, + {"c":[{"v":"Date(2018,9,27,12,10,0)"},{"v":null},{"v":null},{"v":246.4083333}]} + ] +} +``` + +> Using `format=datasource` and `options=` + +```bash +curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&after=-3600&points=6&group=average&format=datasource&options=' +google.visualization.Query.setResponse({version:'0.6',reqId:'0',status:'ok',sig:'1540645368',table:{ + "cols": + [ + {"id":"","label":"time","pattern":"","type":"datetime"}, + {"id":"","label":"","pattern":"","type":"string","p":{"role":"annotation"}}, + {"id":"","label":"","pattern":"","type":"string","p":{"role":"annotationText"}}, + {"id":"","label":"active","pattern":"","type":"number"} + ], + "rows": + [ + {"c":[{"v":"Date(2018,9,27,13,0,0)"},{"v":null},{"v":null},{"v":235.885}]}, + {"c":[{"v":"Date(2018,9,27,12,50,0)"},{"v":null},{"v":null},{"v":224.2516667}]}, + {"c":[{"v":"Date(2018,9,27,12,40,0)"},{"v":null},{"v":null},{"v":229.29}]}, + {"c":[{"v":"Date(2018,9,27,12,30,0)"},{"v":null},{"v":null},{"v":222.41}]}, + {"c":[{"v":"Date(2018,9,27,12,20,0)"},{"v":null},{"v":null},{"v":226.6816667}]}, + {"c":[{"v":"Date(2018,9,27,12,10,0)"},{"v":null},{"v":null},{"v":246.4083333}]} + ] +}}); +``` + + diff --git a/web/api/formatters/json/json.c b/src/web/api/formatters/json/json.c index 7e3f400e9..7e3f400e9 100644 --- a/web/api/formatters/json/json.c +++ b/src/web/api/formatters/json/json.c diff --git a/web/api/formatters/json/json.h b/src/web/api/formatters/json/json.h index d1ab4f901..d1ab4f901 100644 --- a/web/api/formatters/json/json.h +++ b/src/web/api/formatters/json/json.h diff --git a/web/api/formatters/json_wrapper.c b/src/web/api/formatters/json_wrapper.c index 708a0f1f1..fca5a0b83 100644 --- a/web/api/formatters/json_wrapper.c +++ b/src/web/api/formatters/json_wrapper.c @@ -435,23 +435,23 @@ static void query_target_summary_dimensions_v12(BUFFER *wb, QUERY_TARGET *qt, co qm = tqm; } - const char *key, *id, *name; + const char *k, *id, *name; if(v2) { - key = rrdmetric_acquired_name(rma); - id = key; - name = key; + k = rrdmetric_acquired_name(rma); + id = k; + name = k; } else { snprintfz(buf, RRD_ID_LENGTH_MAX * 2 + 1, "%s:%s", rrdmetric_acquired_id(rma), rrdmetric_acquired_name(rma)); - key = buf; + k = buf; id = rrdmetric_acquired_id(rma); name = rrdmetric_acquired_name(rma); } - z = dictionary_set(dict, key, NULL, sizeof(*z)); + z = dictionary_set(dict, k, NULL, sizeof(*z)); if(!z->id) { z->id = id; z->name = name; @@ -618,7 +618,7 @@ static void query_target_summary_alerts_v2(BUFFER *wb, QUERY_TARGET *qt, const c rw_spinlock_read_lock(&st->alerts.spinlock); if (st->alerts.base) { for (RRDCALC *rc = st->alerts.base; rc; rc = rc->next) { - z = dictionary_set(dict, string2str(rc->name), NULL, sizeof(*z)); + z = dictionary_set(dict, string2str(rc->config.name), NULL, sizeof(*z)); switch(rc->status) { case RRDCALC_STATUS_CLEAR: @@ -887,7 +887,7 @@ void rrdr_json_wrapper_begin(RRDR *r, BUFFER *wb) { buffer_json_member_add_time_t(wb, "after", r->view.after); buffer_json_member_add_time_t(wb, "before", r->view.before); buffer_json_member_add_string(wb, "group", time_grouping_tostring(qt->request.time_group_method)); - web_client_api_request_v1_data_options_to_buffer_json_array(wb, "options", options); + rrdr_options_to_buffer_json_array(wb, "options", options); if(!rrdr_dimension_names(wb, "dimension_names", r, options)) rows = 0; @@ -939,10 +939,10 @@ static void rrdset_rrdcalc_entries_v2(BUFFER *wb, RRDINSTANCE_ACQUIRED *ria) { if(rc->status < RRDCALC_STATUS_CLEAR) continue; - buffer_json_member_add_object(wb, string2str(rc->name)); + buffer_json_member_add_object(wb, string2str(rc->config.name)); buffer_json_member_add_string(wb, "st", rrdcalc_status2string(rc->status)); buffer_json_member_add_double(wb, "vl", rc->value); - buffer_json_member_add_string(wb, "un", string2str(rc->units)); + buffer_json_member_add_string(wb, "un", string2str(rc->config.units)); buffer_json_object_close(wb); } buffer_json_object_close(wb); @@ -1299,7 +1299,7 @@ void rrdr_json_wrapper_begin2(RRDR *r, BUFFER *wb) { buffer_json_member_add_object(wb, "request"); { buffer_json_member_add_string(wb, "format", rrdr_format_to_string(qt->request.format)); - web_client_api_request_v1_data_options_to_buffer_json_array(wb, "options", qt->request.options); + rrdr_options_to_buffer_json_array(wb, "options", qt->request.options); buffer_json_member_add_object(wb, "scope"); buffer_json_member_add_string(wb, "scope_nodes", qt->request.scope_nodes); @@ -1538,7 +1538,7 @@ void rrdr_json_wrapper_end2(RRDR *r, BUFFER *wb) { if(options & RRDR_OPTION_DEBUG) { buffer_json_member_add_string(wb, "format", rrdr_format_to_string(format)); - web_client_api_request_v1_data_options_to_buffer_json_array(wb, "options", options); + rrdr_options_to_buffer_json_array(wb, "options", options); buffer_json_member_add_string(wb, "time_group", time_grouping_tostring(qt->request.time_group_method)); } diff --git a/web/api/formatters/json_wrapper.h b/src/web/api/formatters/json_wrapper.h index a702f3a5c..a702f3a5c 100644 --- a/web/api/formatters/json_wrapper.h +++ b/src/web/api/formatters/json_wrapper.h diff --git a/web/api/formatters/rrd2json.c b/src/web/api/formatters/rrd2json.c index 81c9ad5c7..81c9ad5c7 100644 --- a/web/api/formatters/rrd2json.c +++ b/src/web/api/formatters/rrd2json.c diff --git a/web/api/formatters/rrd2json.h b/src/web/api/formatters/rrd2json.h index f0c0c39ba..f0c0c39ba 100644 --- a/web/api/formatters/rrd2json.h +++ b/src/web/api/formatters/rrd2json.h diff --git a/web/api/formatters/rrdset2json.c b/src/web/api/formatters/rrdset2json.c index 9ada35336..542178b25 100644 --- a/web/api/formatters/rrdset2json.c +++ b/src/web/api/formatters/rrdset2json.c @@ -2,7 +2,7 @@ #include "rrdset2json.h" -static int process_label_callback(const char *name, const char *value, RRDLABEL_SRC ls, void *data) { +static int process_label_callback(const char *name, const char *value, RRDLABEL_SRC ls __maybe_unused, void *data) { BUFFER *wb = data; buffer_json_member_add_string_or_empty(wb, name, value); return 1; @@ -88,7 +88,7 @@ void rrdset2json(RRDSET *st, BUFFER *wb, size_t *dimensions_count, size_t *memor buffer_json_member_add_string_or_empty(wb, "id", rrdcalc_name(rc)); buffer_json_member_add_string_or_empty(wb, "status", rrdcalc_status2string(rc->status)); buffer_json_member_add_string_or_empty(wb, "units", rrdcalc_units(rc)); - buffer_json_member_add_int64(wb, "duration", (int64_t)rc->update_every); + buffer_json_member_add_int64(wb, "duration", (int64_t)rc->config.update_every); buffer_json_object_close(wb); } } diff --git a/web/api/formatters/rrdset2json.h b/src/web/api/formatters/rrdset2json.h index 8b325c65d..8b325c65d 100644 --- a/web/api/formatters/rrdset2json.h +++ b/src/web/api/formatters/rrdset2json.h diff --git a/src/web/api/formatters/ssv/README.md b/src/web/api/formatters/ssv/README.md new file mode 100644 index 000000000..2e9dd3886 --- /dev/null +++ b/src/web/api/formatters/ssv/README.md @@ -0,0 +1,63 @@ +<!-- +title: "SSV formatter" +custom_edit_url: https://github.com/netdata/netdata/edit/master/src/web/api/formatters/ssv/README.md +sidebar_label: "SSV formatter" +learn_status: "Published" +learn_topic_type: "References" +learn_rel_path: "Developers/Web/Api/Formatters" +--> + +# SSV formatter + +The SSV formatter sums all dimensions in [results of database queries](https://github.com/netdata/netdata/blob/master/src/web/api/queries/README.md) +to a single value and returns a list of such values showing how it changes through time. + +It supports the following formats: + +| format | content type | description | +|:----:|:----------:|:----------| +| `ssv` | text/plain | a space separated list of values | +| `ssvcomma` | text/plain | a comma separated list of values | +| `array` | application/json | a JSON array | + +The SSV formatter respects the following API `&options=`: + +| option | supported | description | +| :----:|:-------:|:----------| +| `nonzero` | yes | to return only the dimensions that have at least a non-zero value | +| `flip` | yes | to return the numbers older to newer (the default is newer to older) | +| `percent` | yes | to replace all values with their percentage over the row total | +| `abs` | yes | to turn all values positive, before using them | +| `min2max` | yes | to return the delta from the minimum value to the maximum value (across dimensions) | + +## Examples + +Get the average system CPU utilization of the last hour, in 6 values (one every 10 minutes): + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=system.cpu&format=ssv&after=-3600&points=6&group=average' +1.741352 1.6800467 1.769411 1.6761112 1.629862 1.6807968 +``` + +--- + +Get the total mysql bandwidth (in + out) for the last hour, in 6 values (one every 10 minutes): + +Netdata returns bandwidth in `kilobits`. + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=mysql_local.net&format=ssvcomma&after=-3600&points=6&group=sum&options=abs' +72618.7936215,72618.778889,72618.788084,72618.9195918,72618.7760612,72618.6712421 +``` + +--- + +Get the web server max connections for the last hour, in 12 values (one every 5 minutes) +in a JSON array: + +```bash +# curl -Ss 'https://registry.my-netdata.io/api/v1/data?chart=nginx_local.connections&format=array&after=-3600&points=12&group=max' +[278,258,268,239,259,260,243,266,278,318,264,258] +``` + + diff --git a/web/api/formatters/ssv/ssv.c b/src/web/api/formatters/ssv/ssv.c index 2eb26b459..2eb26b459 100644 --- a/web/api/formatters/ssv/ssv.c +++ b/src/web/api/formatters/ssv/ssv.c diff --git a/web/api/formatters/ssv/ssv.h b/src/web/api/formatters/ssv/ssv.h index f7d4a9548..f7d4a9548 100644 --- a/web/api/formatters/ssv/ssv.h +++ b/src/web/api/formatters/ssv/ssv.h diff --git a/src/web/api/formatters/value/README.md b/src/web/api/formatters/value/README.md new file mode 100644 index 000000000..3599a836e --- /dev/null +++ b/src/web/api/formatters/value/README.md @@ -0,0 +1,28 @@ +<!-- +title: "Value formatter" +custom_edit_url: https://github.com/netdata/netdata/edit/master/src/web/api/formatters/value/README.md +sidebar_label: "Value formatter" +learn_status: "Published" +learn_topic_type: "References" +learn_rel_path: "Developers/Web/Api/Formatters" +--> + +# Value formatter + +The Value formatter presents [results of database queries](https://github.com/netdata/netdata/blob/master/src/web/api/queries/README.md) as a single value. + +To calculate the single value to be returned, it sums the values of all dimensions. + +The Value formatter respects the following API `&options=`: + +| option | supported | description | +|:----: |:-------: |:---------- | +| `percent` | yes | to replace all values with their percentage over the row total| +| `abs` | yes | to turn all values positive, before using them | +| `min2max` | yes | to return the delta from the minimum value to the maximum value (across dimensions)| + +The Value formatter is not exposed by the API by itself. +Instead it is used by the [`ssv`](https://github.com/netdata/netdata/blob/master/src/web/api/formatters/ssv/README.md) formatter +and [health monitoring queries](https://github.com/netdata/netdata/blob/master/src/health/README.md). + + diff --git a/web/api/formatters/value/value.c b/src/web/api/formatters/value/value.c index 1d07f62f6..0ec1b1265 100644 --- a/web/api/formatters/value/value.c +++ b/src/web/api/formatters/value/value.c @@ -2,7 +2,6 @@ #include "value.h" - inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null, NETDATA_DOUBLE *anomaly_rate) { size_t c; @@ -10,61 +9,64 @@ inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ]; NETDATA_DOUBLE *ar = &r->ar[ i * r->d ]; - NETDATA_DOUBLE sum = 0, min = 0, max = 0, v; - int all_null = 1, init = 1; + NETDATA_DOUBLE sum = 0, min = NAN, max = NAN, v = NAN; + size_t dims = 0; NETDATA_DOUBLE total_anomaly_rate = 0; // for each dimension for (c = 0; c < r->d ; c++) { - if(!rrdr_dimension_should_be_exposed(r->od[c], options)) + if(unlikely(!rrdr_dimension_should_be_exposed(r->od[c], options))) + continue; + + if(unlikely((co[c] & RRDR_VALUE_EMPTY))) continue; NETDATA_DOUBLE n = cn[c]; - if(unlikely(init)) { - if(n > 0) { - min = 0; - max = n; - } - else { - min = n; - max = 0; - } - init = 0; - } + if(unlikely(!dims)) + min = max = n; - if(likely(!(co[c] & RRDR_VALUE_EMPTY))) { - all_null = 0; - sum += n; - } + sum += n; - if(n < min) min = n; - if(n > max) max = n; + if (n < min) min = n; + if (n > max) max = n; total_anomaly_rate += ar[c]; - } - if(anomaly_rate) { - if(!r->d) *anomaly_rate = 0; - else *anomaly_rate = total_anomaly_rate / (NETDATA_DOUBLE)r->d; + dims++; } - if(unlikely(all_null)) { - if(likely(all_values_are_null)) + if(!dims) { + if(anomaly_rate) + *anomaly_rate = 0; + + if(all_values_are_null) *all_values_are_null = 1; - return 0; - } - else { - if(likely(all_values_are_null)) - *all_values_are_null = 0; + + return (options & RRDR_OPTION_NULL2ZERO) ? 0 : NAN; } - if(options & RRDR_OPTION_MIN2MAX) + if(anomaly_rate) + *anomaly_rate = total_anomaly_rate / (NETDATA_DOUBLE)dims; + + if(all_values_are_null) + *all_values_are_null = 0; + + if(options & RRDR_OPTION_DIMS_MIN2MAX) v = max - min; + else if(options & RRDR_OPTION_DIMS_AVERAGE) + v = sum / (NETDATA_DOUBLE)dims; + else if(options & RRDR_OPTION_DIMS_MIN) + v = min; + else if(options & RRDR_OPTION_DIMS_MAX) + v = max; else v = sum; + if((options & RRDR_OPTION_NULL2ZERO) && (isnan(v) || isinf(v))) + v = 0; + return v; } diff --git a/web/api/formatters/value/value.h b/src/web/api/formatters/value/value.h index 072ca14f8..072ca14f8 100644 --- a/web/api/formatters/value/value.h +++ b/src/web/api/formatters/value/value.h |