Skip to main content

Add a router or multiplexer to query different data types

The QueryData method in your plugin's backend allows you to query one type of data only. To support different kinds of queries (metrics, logs, and traces) you need to implement query router (also known as a multiplexer).

To do so:

  1. Populate the queryType property of your query model client-side, as shown in the DataQuery interface.
  2. With queryType populated in queries and sent to your plugin backend component, use datasource.QueryTypeMux to multiplex or route different query types to separate query handlers.
  3. Each query handler can then json.Unmarshal each query JSON field in DataQuery to a certain Go struct as shown in this example:
package mydatasource

import (
"context"

"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
)

type MyDatasource struct {
queryHandler backend.QueryDataHandler
}

func New() *MyDatasource {
ds := &MyDatasource{}
queryTypeMux := datasource.NewQueryTypeMux()
queryTypeMux.HandleFunc("metrics", ds.handleMetricsQuery)
queryTypeMux.HandleFunc("logs", ds.handleLogsQuery)
queryTypeMux.HandleFunc("traces", ds.handleTracesQuery)
queryTypeMux.HandleFunc("", ds.handleQueryFallback)
ds.queryHandler := queryTypeMux
return ds
}

func (d *MyDatasource) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
return d.queryHandler.QueryData(ctx, req)
}

// handleMetricsQuery handle queries of query type "metrics".
// All queries in backend.QueryDataRequest is guaranteed to only
// include queries with queryType "metrics".
func (d *MyDatasource) handleMetricsQuery(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
// implementation...
}

// handleLogsQuery handle queries of query type "logs".
// All queries in backend.QueryDataRequest is guaranteed to only
// include queries with queryType "logs".
func (d *MyDatasource) handleLogsQuery(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
// implementation...
}

// handleTracesQuery handle queries of query type "logs".
// All queries in backend.QueryDataRequest is guaranteed to only
// include queries with queryType "traces".
func (d *MyDatasource) handleTracesQuery(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
// implementation...
}

// handleQueryFallback handle queries without a matching query type handler registered.
func (d *MyDatasource) handleQueryFallback(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
// implementation...
}

Advanced usage​

You can find an example of using QueryTypeMux in Grafana's built-in TestData data source code: