grafana/grafana
Datasource plugins
This page describes the shape of a datasource plugin — what files it has, what classes it implements, how it interacts with the rest of Grafana. For descriptions of individual built-in datasources see Built-in datasources tour.
What a datasource plugin provides
| Capability | Required? |
|---|---|
| Query editor (UI) | Yes |
| Config editor (settings UI) | Yes |
| Variable query editor (template var support) | Optional |
| Annotation query editor | Optional |
Backend QueryData handler (Go) |
Optional but typical for production datasources |
Health check (CheckHealth) |
Optional but recommended |
Streaming (SubscribeStream) |
Optional (Loki tail, etc.) |
Resources (CallResource) |
Optional (e.g. label autocomplete, schema browser) |
Frontend layout
public/app/plugins/datasource/<id>/
├── plugin.json # Metadata (id, name, version, dependencies)
├── module.ts # Builds and exports GrafanaPlugin
├── datasource.ts # DataSource class
├── components/
│ ├── QueryEditor/
│ ├── ConfigEditor/
│ └── VariableQueryEditor/ # If supported
├── querybuilder/ # Visual query builder (Prometheus, Loki, …)
├── language/ # Monaco editor language definition (PromQL, LogQL, …)
├── types.ts # Query/option types (often CUE-generated)
├── tests/
└── README.mdThe DataSource class extends DataSourceApi<TQuery, TOptions> from @grafana/data and implements:
class MyDataSource extends DataSourceApi<MyQuery, MyOptions> {
query(request: DataQueryRequest<MyQuery>): Observable<DataQueryResponse> {
/* ... */
}
testDatasource(): Promise<TestDataSourceResponse> {
/* ... */
}
metricFindQuery(query: string): Promise<MetricFindValue[]> {
/* if it supports template variables */
}
}Backend layout
pkg/tsdb/<id>/
├── plugin.go # Plugin registration
├── service.go # ProvideService(...) for Wire
├── querydata.go # QueryData implementation
├── healthcheck.go # CheckHealth
├── resource.go # CallResource (optional)
└── *_test.goBackend datasources implement backend.QueryDataHandler from grafana-plugin-sdk-go. The SDK handles gRPC plumbing; the plugin only writes domain logic.
Communication
graph LR
Panel[Panel<br/>frontend] --> DSAPI[DataSource.query]
DSAPI --> BSrv[backendSrv POST /api/ds/query]
BSrv --> Server[Grafana server]
Server --> Plug[Plugin host]
Plug --> TSDB[pkg/tsdb/<id>/]
TSDB --> Up[Upstream API]
Up --> TSDB
TSDB --> Plug
Plug --> Server
Server --> BSrv
BSrv --> DSAPI
DSAPI --> PanelFor datasources without a backend, the frontend DataSource.query method talks to the upstream API directly via the proxy (pkg/services/datasourceproxy/) — the proxy injects credentials and applies permissions before forwarding.
Macros and variables
Most datasources expose macros — small placeholders that expand at query time. SQL datasources use ${date}, ${interval}, ${user}, etc. Macros are expanded before the query reaches the upstream system; the frontend uses getTemplateSrv().replace(query, ...) to expand ${var} references.
Health checks
The "Save & test" button on the settings page calls /api/datasources/uid/<uid>/health, which dispatches to the plugin's CheckHealth. Implement this to catch credential/network errors at config time rather than first query.
See also
- Backend / TSDB — list of built-in backends.
- Backend / Datasources & queries — orchestration above this layer.
- Backend / Plugin host — how plugins are loaded.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.