summaryrefslogtreecommitdiffstats
path: root/src/collectors/plugins.d/functions-table.md
blob: 72df0fe3e1748aea3a33137cb286334bd494f025 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
> This document is a work in progress.

Plugin functions can support any kind of responses. However, the UI of Netdata has defined some structures as responses it can parse, understand and visualize.

One of these responses is the `table`. This is used in almost all functions implemented today.

# Functions Tables

Tables are defined when `"type": "table"` is set. The following is the standard header that should be available on all `table` responses: 

```json
{
  "type": "table",
  "status": 200,
  "update_every": 1,
  "help": "help text",
  "hostname": "the hostname of the server sending this response, to appear at the title of the UI.",
  "expires": "UNIX epoch timestamp that the response expires",
  "has_history": "boolean: true when the datetime picker plays a role in the result set",
  // rest of the response
}
```

## Preflight `info` request

The UI, before making the first call to a function, it does a preflight request to understand what the function supports. The plugin receives this request as a FUNCTION call specifying the `info` parameter (possible among others).

The response from the plugin is expected to have the following:

```json
{
  // standard table header - as above
  "accepted_params": [ "a", "b", "c", ...],
  "required_params": [
    {
      "id": "the keyword to use when sending / receiving this parameter",
      "name": "the name to present to users for this parameter",
      "help": "a help string to help users understand this parameter",
      "type": "the type of the parameter, either: 'select' or 'multiselect'",
      "options": [
        {
          "id": "the keyword to use when sending / receiving this option",
          "name": "the name to present to users for this option",
          "pill": "a short text to show next to this option as a pill",
          "info": "a longer text to show on a tooltip when the user is hovering this option"
        },
        // more options for this required parameter
      ]
    },
    // more required parameters
  ]
}
```

If there are no required parameters, `required_params` can be omitted.
If there are no accepted parameters, `accepted_params` can be omitted. `accepted_param` can be sent during normal responses to update the UI with a new set of parameters available, between calls.

If there are `required_params`, the UI by default selects the first option. [](VERIFY_WITH_UI) 

## Table data

To define table data, the UI expects this:

```json
{
  // header
  "columns": {
    "id": {
      "index": "number: the sort order for the columns, lower numbers are first",
      "name": "string: the name of the column as it should be presented to users",
      "unique_key": "boolean: true when the column uniquely identifies the row",
      "visible": "boolean: true when the column should be visible by default",
      "type": "enum: see column types",
      "units": "string: the units of the value, if any - this item can be omitted if the column does not have units [](VERIFY_WITH_UI)",
      "visualization": "enum: see visualization types",
      "value_options": {
        "units": "string: the units of the value  [](VERIFY_WITH_UI)",
        "transform": "enum: see transformation types",
        "decimal_points": "number: the number of fractional digits for the number",
        "default_value": "whatever the value is: when the value is null, show this instead"
      },
      "max": "number: when the column is numeric, this is the max value the data have - this is used when range filtering is set and value bars",
      "pointer_to": "id of another field: this is used when detail-string is set, to point to the column this column is detail of",
      "sort": "enum: sorting order",
      "sortable": "boolean: whether the column is sortable by users",
      "sticky": "boolean: whether the column should always be visible in the UI",
      "summary": "string: ???",
      "filter": "enum: the filtering type for this column",
      "full_width": "boolean: the value is expected to get most of the available column space. When multiple columns are full_width, the available space is given to all of them.",
      "wrap": "boolean: true when the entire value should be shown, even when it occupies a big space.",
      "default_expanded_filter": "boolean: true when the filter of this column should be expanded by default.",
      "dummy": "boolean: when set to true, the column is not to be presented to users."
    },
    // more IDs
  },
  "data": [ // array of rows
    [ // array of columns
      // values for each column linked to their "index" in the columns
    ],
    // next row
  ],
  "default_sort_column": "id: the id of the column that should be sorted by default"
}
```


### Sorting order

- `ascending`
- `descending`

### Transformation types

- `none`, just show the value, without any processing
- `number`, just show a number with its units, respecting `decimal_points`
- `duration`, makes the UI show a human readable duration, of the seconds given
- `datetime`, makes the UI show a human readable datetime of the timestamp in UNIX epoch
- `datetime_usec`, makes the UI show a human readable datetime of the timestamp in USEC UNIX epoch

### Visualization types

- `value`
- `bar`
- `pill`
- `richValue`, this is not used yet, it is supposed to be a structure that will provide a value and options for it
- `rowOptions`, defines options for the entire row - this column is hidden from the UI

### rowOptions

TBD

### Column types

- `none`
- `integer`
- `boolean`
- `string`
- `detail-string`
- `bar-with-integer`
- `duration`
- `timestamp`
- `array`

### Filter types

- `none`, this facet is not selectable by users
- `multiselect`, the user can select any number of the available options
- `facet`, similar to `multiselect`, but it also indicates that the column has been indexed and has values with counters. Columns set to `facet` must appear in the `facets` list.  
- `range`, the user can select a range of values (numeric)

The plugin may send non visible columns with filter type `facet`. This means that the plugin can enable indexing on these columns, but it has not done it. Then the UI may send `facets:{ID1},{ID2},{ID3},...` to enable indexing of the columns specified.

What is the default?

#### Facets

Facets are a special case of `multiselect` fields. They are used to provide additional information about each possible value, including their relative sort order and the number of times each value appears in the result set. Facets are filters handled by the plugin. So, the plugin will receive user selected filter like: `{KEY}:{VALUE1},{VALUE2},...`, where `{KEY}` is the id of the column and `{VALUEX}` is the id the facet option the user selected. 

```json
{
  // header,
  "columns": ...,
  "data": ...,
  "facets": [
    {
      "id": "string: the unique id of the facet",
      "name": "string: the human readable name of the facet",
      "options": [
        {
          "id": "string: the unique id of the facet value",
          "name": "string: the human readable version of the facet value",
          "count": "integer: the number of times this value appears in the result set",
          "order": "integer: the sorting order of this facet value - lower numbers move items above others"
        },
        // next option
      ],
    },
    // next facet
  ]
}
```

## Charts

```json
{
  // header,
  "charts": {
    
  },
  "default_charts": [
    
  ]
}
```


## Histogram

```json
{
  // header,
  "available_histograms": [
    
  ],
  "histogram": {
    
  }
}
```

## Grouping

```json
{
  // header,
  "group_by": {
    
  }
}
```

## Datetime picker

When `has_history: true`, the plugin must accept `after:TIMESTAMP_IN_SECONDS` and `before:TIMESTAMP_IN_SECONDS` parameters.
The plugin can also turn pagination on, so that only a small set of the data are sent to the UI at a time.


## Pagination

The UI supports paginating results when `has_history: true`. So, when the result depends on the datetime picker and it is too big to be sent to the UI in one response, the plugin can enable datetime pagination like this:

```json
{
  // header,
  "columns": ...,
  "data": ...,
  "has_history": true,
  "pagination": {
    "enabled": "boolean: true to enable it",
    "column": "string: the column id that is used for pagination",
    "key": "string: the accepted_param that is used as the pagination anchor",
    "units": "enum: a transformation of the datetime picker to make it compatible with the anchor: timestamp, timestamp_usec"
  }
}
```

Once pagination is enabled, the plugin must support the following parameters:

- `{ANCHOR}:{VALUE}`, `{ANCHOR}` is the `pagination.key`, `{VALUE}` is the point the user wants to see entries at, formatted according to `pagination.units`. 
- `direction:backward` or `direction:forward` to specify if the data to be returned if before are after the anchor. 
- `last:NUMER`, the number of entries the plugin should return in the table data.
- `query:STRING`, the full text search string the user wants to search for.
- `if_modified_since:TIMESTAMP_USEC` and `tail:true`, used in PLAY mode, to indicate that the UI wants data newer than the specified timestamp. If there are no new data, the plugin must respond with 304 (Not Modified).

### Incremental Responses

- `delta:true` or `delta:false`, when the plugin supports incremental queries, it can accept the parameter `delta`. When set to true, the response of the plugin will be "added" to the previous response already available. This is used in combination with `if_modified_since` to optimize the amount of work the plugin has to do to respond.


### Other

- `slice:BOOLEAN` [](VERIFY_WITH_UI)
- `sampling:NUMBER`