Need help with GrafanaJsonDatasource?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

simPod
141 Stars 36 Forks MIT License 281 Commits 6 Opened issues

Description

Grafana datasource to load JSON data over your arbitrary HTTP backend

Services available

!
?

Need anything else?

Contributors list

JSON API Grafana Datasource

Build Marketplace Downloads

The JSON Datasource executes requests against arbitrary backends and parses JSON response into Grafana dataframes.
JSON Datasource is built on top of the Simple JSON Datasource. It has refactored code, additional features and active development.

Contents

Installation

To install this plugin using the

grafana-cli
tool:
 grafana-cli plugins install simpod-json-datasource

See here for more information.

Setup

When adding datasource add your API endpoint to the

URL
field. That's where datasource will make requests to.

Datasource setup

API

An OpenAPI definition is defined at openapi.yaml.

To work with this datasource the backend needs to implement 4 endpoints:

  • GET /
    with 200 status code response. Used for "Test connection" on the datasource config page.
  • POST /search
    returning available metrics when invoked.
  • POST /query
    returning metrics based on input.
  • POST /annotations
    returning annotations.

Those two urls are optional:

  • POST /tag-keys
    returning tag keys for ad hoc filters.
  • POST /tag-values
    returning tag values for ad hoc filters.

/search

POST /search

Grafana issues this request on

  1. Variables > New/Edit page.
    Query
    field value is passed in a body as
{ "target": "query field value" }
  1. Panel > Queries
    page.
    Format As
    and
    Metric
    values are passed in a body as
{ "type": "timeseries", "target": "upper_50" }

The way you handle those values is up to you.

The response body can either contain an array or a map.

Example array response:

["upper_25","upper_50","upper_75","upper_90","upper_95"]

Example map response:

[ { "text": "upper_25", "value": 1}, { "text": "upper_75", "value": 2} ]

/query

POST /query

Example

timeseries
request:
{
  "panelId": 1,
  "range": {
    "from": "2016-10-31T06:33:44.866Z",
    "to": "2016-10-31T12:33:44.866Z",
    "raw": {
      "from": "now-6h",
      "to": "now"
    }
  },
  "rangeRaw": {
    "from": "now-6h",
    "to": "now"
  },
  "interval": "30s",
  "intervalMs": 30000,
  "maxDataPoints": 550,
  "targets": [
     { "target": "Packets", "refId": "A", "type": "timeseries", "data": { "additional": "optional json" } },
     { "target": "Errors", "refId": "B", "type": "timeseries" }
  ],
  "adhocFilters": [{
    "key": "City",
    "operator": "=",
    "value": "Berlin"
  }]
}

Example

timeseries
response (metric value as a float , unixtimestamp in milliseconds):
[
  {
    "target":"pps in",
    "datapoints":[
      [622,1450754160000],
      [365,1450754220000]
    ]
  },
  {
    "target":"pps out",
    "datapoints":[
      [861,1450754160000],
      [767,1450754220000]
    ]
  },
  {
    "target":"errors out",
    "datapoints":[
      [861,1450754160000],
      [767,1450754220000]
    ]
  },
  {
    "target":"errors in",
    "datapoints":[
      [861,1450754160000],
      [767,1450754220000]
    ]
  }
]

The relation between

target
in request and response is 1:n. You can return multiple targets in response for one requested
target
.

Example

table
response to be returned if the metric selected is
"type": "table"
:
[
  {
    "columns":[
      {"text":"Time","type":"time"},
      {"text":"Country","type":"string"},
      {"text":"Number","type":"number"}
    ],
    "rows":[
      [1234567,"SE",123],
      [1234567,"DE",231],
      [1234567,"US",321]
    ],
    "type":"table"
  }
]

Additional data

Additional data input

Sending additional data for each metric is supported via the Additional JSON Data input field that allows you to enter JSON.

For example when

{ "additional": "optional json" }
is entered into Additional JSON Data input, it is attached to the target data under
"data"
key:
{ "target": "upper_50", "refId": "A", "type": "timeseries", "data": { "additional": "optional json" } }

You can also enter variables:

Additional data varible input

/annotations

POST /annotations

The JSON request body looks like this:

{
  "range": {
    "from": "2016-04-15T13:44:39.070Z",
    "to": "2016-04-15T14:44:39.070Z"
  },
  "rangeRaw": {
    "from": "now-1h",
    "to": "now"
  },
  "annotation": {
    "name": "deploy",
    "datasource": "JSON Datasource",
    "iconColor": "rgba(255, 96, 96, 1)",
    "enable": true,
    "query": "#deploy"
  },
   "variables": []
}

Grafana expects a response containing an array of annotation objects.

Field explanation: *

text
- Text for the annotation. (required) *
title
- The title for the annotation tooltip. (optional) *
isRegion
- Whether is region. (optional) (http://docs.grafana.org/reference/annotations/#adding-regions-events) *
time
- Time since UNIX Epoch in milliseconds. (required) *
timeEnd
- Time since UNIX Epoch in milliseconds (required if
isRegion
is true ) *
tags
- Tags for the annotation. (optional)
[
  {
    "text": "text shown in body",
    "title": "Annotation Title",
    "isRegion": true,
    "time": "timestamp",
    "timeEnd": "timestamp",
    "tags": ["tag1"]
  }
]

Note: If the datasource is configured to connect directly to the backend, you also need to implement

OPTIONS /annotations
that responds with the correct CORS headers:
Access-Control-Allow-Headers:accept, content-type
Access-Control-Allow-Methods:POST
Access-Control-Allow-Origin:*

/tag-keys

POST /tag-keys

Example request body

{ }

The tag keys api returns:

[
    {"type":"string","text":"City"},
    {"type":"string","text":"Country"}
]

/tag-values

POST /tag-values

Example request body

{"key": "City"}

The tag values api returns:

[
    {"text": "Eins!"},
    {"text": "Zwei"},
    {"text": "Drei!"}
]

Development Setup

This plugin requires node 6.10.0. Use of Yarn is encouraged to build.

yarn install
yarn run build

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.