Plugins 〉Wild GraphQL Data Source
Wild GraphQL Data Source
Wild GraphQL Data Source
This is a Grafana data source that aims to make requesting time series data via a GraphQL endpoint easy. The query editor uses GraphiQL to provide an intuitive editor with autocompletion. Requests are made in the backend allowing support for alerting.
Please report issues on our issues page: wild-graphql-datasource/issues
Features
- Complex GraphQL responses can be turned into timeseries data, or a simple table
- Includes GraphiQL query editor. Autocompletion and documentation for the GraphQL schema available inside Grafana!
- Documentation explorer can be opened from the query editor
- Prettify the query with the click of a button
from
andto
variables are given to the query via native GraphQL variables- Variables section of the query editor supports interpolation of string values using Grafana variables. (*not supported in alerting or other backend-only queries)
- Multiple parsing options are supported allowing for a single GraphQL query to return many different data points with different formats.
- Each parsing option has its own labels, which can be populated by a field in the response. These labels are used to group the response into different data frames.
- Labels can be used to change the display name by using
${__field.labels["displayName"]}
under Standard options > Display name.
- This is a backend plugin, so alerting is supported
- Annotation support
Query Editor
Query
Your GraphQL query goes inside the upper half of the GraphiQL editor pane
Variables
Variables may be edited within the GraphiQL editor window. These variables are specified using JSON and work like variables in any regular GraphQL query. This section is optional, but if you wish to provide constant variables for your query or simplify the specification of input types, you may do so.
Provided Variables
Certain variables are provided to every query. These include:
Variable | Type | Description | Grafana counterpart | Execute Button Support |
---|---|---|---|---|
from | Number | Epoch milliseconds of the "from" time | $__from | Yes |
to | Number | Epoch milliseconds of the "to" time | $__to | Yes |
interval_ms | Number | The suggested duration between time points in a time series query | $__interval_ms | No |
maxDataPoints | Number | Maximum number of data points that should be returned from a time series query | N/A | No |
refId | String | Unique identifier of the query, set by the frontend call | N/A | No |
An example usage is shown in the most basic query:
query ($from: Long!, $to: Long!) {
queryStatus(from: $from, to: $to) {
# ...
}
}
In the above example, the query asks for two Longs, $from
and $to
.
The value is provided by the provided variables as seen in the above table.
Notice that while interval_ms
is provided, we do not use it or define it anywhere in our query.
One thing to keep in mind for your own queries is the type accepted by the GraphQL server for a given variable.
In the case of that specific schema, the type of a Long
is allowed to be a number or a string.
If your schema does not have a Long
type, you may consider changing the declaration of the query to use Float
or String
,
which are both types built into GraphQL.
If you run into any issues using the from
and to
variables for your specific schema,
please raise and issue.
Alternatively, if you are making a query on the frontend (any query besides alerting queries),
you may consider reading the next section to define your own from and to variables and assigning their values to
a global variable.
Grafana variable interpolation
The variables section is the most useful for variable interpolation. Any value inside a string, whether that string is nested inside an object, or a top-most value of the variables object, can be interpolated. Please note that interpolation does not work for alerting queries. You may use any configuration of variables you see fit. An example is this:
query ($sourceId: String!, $from: Long!, $to: Long!) {
queryStatus(sourceId: $sourceId, from: $from, to: $to) {
# ...
}
}
{
"sourceId": "$sourceId"
}
Here, $sourceId
inside of the variables section will be interpolated with a value defined in your Grafana dashboard.
$sourceId
inside of the GraphQL query pane is a regular variable that is passed to the query.
NOTE: If you need to pass a variable as a number you must use "Advanced Variable Interpolation", shown in the next section.
REMEMBER: Variable interpolation does not work for alerting queries, or any query that is executed without the frontend component.
Advanced Variable Interpolation
If you need to incorporate numeric variables in the variables passed to your query, you cannot use the default variables editor, you must instead use Advanced Variables JSON. Click the checkbox to define it. Once you do, you can write JSON that is not valid until AFTER it is interpolated. For instance:
{
"age": $age
}
The above example is valid assuming that $age
evaluates to a number that causes the resulting JSON to be valid.
You can use both advanced variables JSON and the regular variables as described above. Just realize that advanced variables JSON will take precedence for any variables defined twice.
WARNING: Only use advanced variables JSON if it is required to. If any part of the resulting JSON is invalid, no part of the advanced variable interpolation will be passed to the query.
Documentation Explorer
GraphiQL provides a documentation explorer and can be opened on the left side of the GraphiQL editor by clicking the button in the upper left of the GraphiQL editor.
GraphiQL Query Execution
The right side of the GraphiQL editor is reserved for the results of the query. This is useful only for debugging to see what the resulting JSON is of the query.
To run a query and see its raw JSON, press the "Execute query" button, which is in the top center of the GraphiQL editor. The results you see in here are separate from allowing Grafana to query the data source.
Operation Name
The operation name is displayed right below the GraphiQL editor. The operation name should be automatically determined by Wild GraphQL Data Source. If you define multiple queries in the query pane, you may have to manually specify this. This is also automatically updated after running a query using the "Execute query" button.
Parsing Options
The query editor allows you to configure one or many parsing options. Each additional parsing option results in at least one additional data frame, which can be seen in "Table View" of the Edit panel page on in the query inspector.
Data path and time path
The data path is a dot-delimited path to the array of data, or to the data object in the response JSON.
The time path is a dot-delimited path to the time field, or blank if there is no time field.
Take this query for example:
query ($from: Long!, $to: Long!) {
temperatures(from: $from, to: $to) {
epochTimeMillis
temperatureCelsius
}
}
- Data path:
temperatures
- Time path:
epochTimeMillis
Notice that time path is relative to the data path.
Labels
Each query option may specify labels that will be present in the resulting dataframe. You may create a new label by typing in the "Label to add" text box and pressing enter. This will add a label with the given name to each parsing option.
Field Labels
The value of a field label is the dot-delimited path to the desired field present in the response JSON, similar to how the "Time Path" works.
The use of a field label will partition the data by that field's value, which results in multiple data frames, which in turn results in multiple keys on the legend of your graph.
Constant Labels
A constant label defines a label for the given parsing option. A constant label can be useful to identify the different parsing options, or to provide a particular display name for a single parsing option.
Using a label as a display name
If you want to partition the data by a certain field, you should use a field label as described above.
With that field label created, there's a good chance you want to use that same field as the display name, so the legend of your graph shows a readable display name.
On the right hand side of the panel editor, navigate to Standard Options > Display Name.
Now, change the display name to ${__field.labels["displayName"]}
, where displayName
is the name of your label.
Alternatively, assuming your label's name is a valid identifier,
you may instead set the Display Name
to ${__field.labels.displayName}
.
The use of multiple parsing options
Multiple parsing options are a good alternative to multiple queries in a single panel. Since a single GraphQL query can return lots of data, sometimes you may need to parse individual parts of it. For instance, here's a simple example with 2 parsing options:
query ($from: Long!, $to: Long!) {
temperature(from: $from, to: $to) {
epochTimeMillis
sensorName
temperatureCelsius
}
deviceCpuTemperature(from: $from, to: $to) {
dateMillis
temperature
}
}
- Parsing option 1
- Data path:
temperatures
- Time path:
epochTimeMillis
- Labels
- "displayName": (Field)
sensorName
- "displayName": (Field)
- Data path:
- Parsing option 2
- Data path:
deviceCpuTemperatures
- Time path:
dateMillis
- Labels
- "displayName": (Constant)
CPU
- "displayName": (Constant)
- Data path:
What could have taken two queries, you now have done in a single query!
Using Grafana Transformations
It's worth documenting that it's entirely possible to not use the labels feature of Wild GraphQL Data Source, and use Grafana transformations for some of the same functionality.
If you have data that needs to be "grouped by" or "partitioned by", you first need to add "Partition by values"
as a transform and select your.field.for.displayName
.
Once you do that, you can go into the "Standard options" and find "Display name" and set it to
${__field.labels["your.field.for.displayName"]}
.
References:
- documentation for Display name under standard options.
- partition by values
- Note: Partition by values was added in 9.3 (blog)
Remember that Grafana transformations are not the preferred way of doing this, and you should prefer to use the label functionality provided.
FAQ
- Can I use variable interpolation within the GraphQL query itself?
- No, but you may use variable interpolation inside the string values of the variables passed to the query
- Is this a drop-in replacement for fifemon-graphql-datasource?
- No, but both data sources have similar goals and can be ported between with little effort.
Alerting Specific Errors
Failed to evaluate queries and expressions: input data must be a wide series but got type long (input refid)
- This error indicates that the query returns more fields than just the time and the datapoint.
- For alerts, the response from the GraphQL query cannot contain more than the time and datapoint. At this time, you cannot use other attributes from the result to filter the data.
Failed to evaluate queries and expressions: failed to execute conditions: input data must be a wide series but got type not (input refid)
- This may occur if you don't have any numeric data in your response (https://github.com/grafana/grafana/issues/46429)
- This error also occurs when you include labels and your response includes multiple data frames.
- To fix this, don't use labels in alerting queries. Alerting queries support the long data frame format, so it will automatically assume non-numeric fields are labels.
- This has the drawback that if your query returns data across a period of time, you cannot easily partition data by fields AND choose to only use the most recent data.
Known Issues
- Alerting queries and annotation queries can only use fields provided in the response data.
- We plan to mitigate this in the future by allowing custom fields to be added to the response
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Grafana Cloud Free
.h4 . .mb-0 }
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Grafana Cloud Free
- Free tier: Limited to 3 users
- Paid plans: $55 / user / month above included usage
- Access to all Enterprise Plugins
- Fully managed service (not available to self-manage)
Self-hosted Grafana Enterprise
- Access to all Enterprise plugins
- All Grafana Enterprise features
- Self-manage on your own infrastructure
Installing Wild GraphQL Data Source on Grafana Cloud:
Installing plugins on a Grafana Cloud instance is a one-click install; same with updates. Cool, right?
Note that it could take up to 1 minute to see the plugin show up in your Grafana.
Installing plugins on a Grafana Cloud instance is a one-click install; same with updates. Cool, right?
Note that it could take up to 1 minute to see the plugin show up in your Grafana.
Installing plugins on a Grafana Cloud instance is a one-click install; same with updates. Cool, right?
Note that it could take up to 1 minute to see the plugin show up in your Grafana.
Installing plugins on a Grafana Cloud instance is a one-click install; same with updates. Cool, right?
Note that it could take up to 1 minute to see the plugin show up in your Grafana.
Installing plugins on a Grafana Cloud instance is a one-click install; same with updates. Cool, right?
Note that it could take up to 1 minute to see the plugin show up in your Grafana.
Installing plugins on a Grafana Cloud instance is a one-click install; same with updates. Cool, right?
Note that it could take up to 1 minute to see the plugin show up in your Grafana.
Installing plugins on a Grafana Cloud instance is a one-click install; same with updates. Cool, right?
Note that it could take up to 1 minute to see the plugin show up in your Grafana.
For more information, visit the docs on plugin installation.
Installing on a local Grafana:
For local instances, plugins are installed and updated via a simple CLI command. Plugins are not updated automatically, however you will be notified when updates are available right within your Grafana.
1. Install the Data Source
Use the grafana-cli tool to install Wild GraphQL Data Source from the commandline:
grafana-cli plugins install
The plugin will be installed into your grafana plugins directory; the default is /var/lib/grafana/plugins. More information on the cli tool.
Alternatively, you can manually download the .zip file for your architecture below and unpack it into your grafana plugins directory.
Alternatively, you can manually download the .zip file and unpack it into your grafana plugins directory.
2. Configure the Data Source
Accessed from the Grafana main menu, newly installed data sources can be added immediately within the Data Sources section.
Next, click the Add data source button in the upper right. The data source will be available for selection in the Type select box.
To see a list of installed data sources, click the Plugins item in the main menu. Both core data sources and installed data sources will appear.
Changelog
1.3.1
Fixed #9 which was a bug where arrays used inside the variables section would incorrectly get turned into an object before being passed to the backend. Additionally, there are many internal dependency upgrades to fix a security vulnerability that prevented 1.3.0 from officially being released.
1.3.0
Merged #8 which passes a request's HTTP headers to the GraphQL server. This change should respect the checkboxes under the "Auth" section of the data source's configuration so that OAuth and cookie headers are only sent if you toggle their setting.
Additionally, these headers are now always passed to the GraphQL server for most queries:
X-Datasource-Uid
X-Grafana-Org-Id
X-Panel-Id
X-Dashboard-Uid
1.2.1
Updated LICENSE link in README.
1.2.0
Merged #5
which updates the internal libraries for better HTTP header support that can be configured within the data source itself.
Additionally, all GraphQL requests will include a Accept: application/json
header in every request.
This additional header matches the GraphQL over HTTP spec for better compatibility with GraphQL servers.
1.1.1
No new features or fixes.
Stability
- First release that is officially signed
1.1.0
New Features
- Added "Advanced Variables JSON" to define a variables JSON object that has interpolation performed on the JSON string itself, rather than strings within the JSON
- This is added functionality and is not meant to replace or change the existing functionality. Using the variables configuration from the GraphiQL editor and advanced variables JSON at the same time is supported.
Stability
- Resources are properly closed
- Panics are no longer used and better logging is done in the backend
- Unnecessary
console.log()
calls moved to existingconsole.error()
calls
1.0.1
Fixes
- Numeric values are now exported as
float64
values, which allows alerting queries to work correctly - An undefined variables object used to cause an error to be logged. Null/undefined
variables
field defined via provisioned queries now cause no error message to be logged.
1.0.0
Initial release.