mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
Chore: Refactor OpenTSDB using backend SDK (#35815)
* Refactor OpenTSDB using backend SDK * Adjust tests to the SDK refactor * Remove openTSDB from service * Rename OpenTASDB service to Service, use AuthPassword from DecryptedSecureJson * Devenv: Add opentsdb v2.3 data source and dashboard * Letting http client provider to set basic auth, renaming, casting datasource direclty to pointer * Update pkg/tsdb/opentsdb/opentsdb.go Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com> * Update pkg/tsdb/opentsdb/opentsdb.go Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com> * Format struct Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
This commit is contained in:
parent
a690d0f803
commit
7231eba6a5
@ -84,6 +84,14 @@ datasources:
|
||||
tsdbResolution: 1
|
||||
tsdbVersion: 1
|
||||
|
||||
- name: gdev-opentsdb-v2.3
|
||||
type: opentsdb
|
||||
access: proxy
|
||||
url: http://localhost:4242
|
||||
jsonData:
|
||||
tsdbResolution: 1
|
||||
tsdbVersion: 3
|
||||
|
||||
- name: gdev-elasticsearch-v2-metrics
|
||||
type: elasticsearch
|
||||
access: proxy
|
||||
|
258
devenv/dev-dashboards/datasource-opentsdb/opentsdb_v2.3.json
Normal file
258
devenv/dev-dashboards/datasource-opentsdb/opentsdb_v2.3.json
Normal file
@ -0,0 +1,258 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 3151,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-opentsdb-v2.3",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 2,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "8.1.0-pre",
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"aggregator": "sum",
|
||||
"alias": "$tag_hostname",
|
||||
"currentFilterGroupBy": false,
|
||||
"currentFilterKey": "",
|
||||
"currentFilterType": "literal_or",
|
||||
"currentFilterValue": "",
|
||||
"disableDownsampling": false,
|
||||
"downsampleAggregator": "avg",
|
||||
"downsampleFillPolicy": "none",
|
||||
"explicitTags": false,
|
||||
"filters": [
|
||||
{
|
||||
"filter": "*",
|
||||
"groupBy": true,
|
||||
"tagk": "hostname",
|
||||
"type": "wildcard"
|
||||
}
|
||||
],
|
||||
"metric": "cpu",
|
||||
"refId": "A",
|
||||
"shouldComputeRate": false
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "CPU per host",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "gdev-opentsdb-v2.3",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 4,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "8.1.0-pre",
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"aggregator": "sum",
|
||||
"alias": "$tag_hostname",
|
||||
"currentFilterGroupBy": false,
|
||||
"currentFilterKey": "",
|
||||
"currentFilterType": "literal_or",
|
||||
"currentFilterValue": "",
|
||||
"downsampleAggregator": "avg",
|
||||
"downsampleFillPolicy": "none",
|
||||
"filters": [
|
||||
{
|
||||
"filter": "*",
|
||||
"groupBy": true,
|
||||
"tagk": "hostname",
|
||||
"type": "wildcard"
|
||||
}
|
||||
],
|
||||
"metric": "logins.count",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Login Count per host",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"schemaVersion": 30,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "Datasource tests - OpenTSDB v2.3",
|
||||
"uid": "rZRUGik7k",
|
||||
"version": 3
|
||||
}
|
@ -3,37 +3,81 @@ package opentsdb
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"golang.org/x/net/context/ctxhttp"
|
||||
)
|
||||
|
||||
type OpenTsdbExecutor struct {
|
||||
httpClientProvider httpclient.Provider
|
||||
type Service struct {
|
||||
HTTPClientProvider httpclient.Provider `inject:""`
|
||||
Cfg *setting.Cfg `inject:""`
|
||||
BackendPluginManager backendplugin.Manager `inject:""`
|
||||
|
||||
im instancemgmt.InstanceManager
|
||||
}
|
||||
|
||||
//nolint: staticcheck // plugins.DataPlugin deprecated
|
||||
func New(httpClientProvider httpclient.Provider) func(*models.DataSource) (plugins.DataPlugin, error) {
|
||||
//nolint: staticcheck // plugins.DataPlugin deprecated
|
||||
return func(*models.DataSource) (plugins.DataPlugin, error) {
|
||||
return &OpenTsdbExecutor{
|
||||
httpClientProvider: httpClientProvider,
|
||||
}, nil
|
||||
type datasourceInfo struct {
|
||||
HTTPClient *http.Client
|
||||
URL string
|
||||
}
|
||||
|
||||
type DsAccess string
|
||||
|
||||
func init() {
|
||||
registry.Register(®istry.Descriptor{Instance: &Service{}})
|
||||
}
|
||||
|
||||
func (s *Service) Init() error {
|
||||
s.im = datasource.NewInstanceManager(newInstanceSettings(s.HTTPClientProvider))
|
||||
|
||||
factory := coreplugin.New(backend.ServeOpts{
|
||||
QueryDataHandler: s,
|
||||
})
|
||||
|
||||
if err := s.BackendPluginManager.Register("opentsdb", factory); err != nil {
|
||||
plog.Error("Failed to register plugin", "error", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc {
|
||||
return func(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
|
||||
opts, err := settings.HTTPClientOptions()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client, err := httpClientProvider.New(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
model := &datasourceInfo{
|
||||
HTTPClient: client,
|
||||
URL: settings.URL,
|
||||
}
|
||||
|
||||
return model, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,16 +85,16 @@ var (
|
||||
plog = log.New("tsdb.opentsdb")
|
||||
)
|
||||
|
||||
// nolint:staticcheck // plugins.DataQueryResult deprecated
|
||||
func (e *OpenTsdbExecutor) DataQuery(ctx context.Context, dsInfo *models.DataSource,
|
||||
queryContext plugins.DataQuery) (plugins.DataResponse, error) {
|
||||
func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
var tsdbQuery OpenTsdbQuery
|
||||
|
||||
tsdbQuery.Start = queryContext.TimeRange.GetFromAsMsEpoch()
|
||||
tsdbQuery.End = queryContext.TimeRange.GetToAsMsEpoch()
|
||||
q := req.Queries[0]
|
||||
|
||||
for _, query := range queryContext.Queries {
|
||||
metric := e.buildMetric(query)
|
||||
tsdbQuery.Start = q.TimeRange.From.UnixNano() / int64(time.Millisecond)
|
||||
tsdbQuery.End = q.TimeRange.To.UnixNano() / int64(time.Millisecond)
|
||||
|
||||
for _, query := range req.Queries {
|
||||
metric := s.buildMetric(query)
|
||||
tsdbQuery.Queries = append(tsdbQuery.Queries, metric)
|
||||
}
|
||||
|
||||
@ -59,33 +103,31 @@ func (e *OpenTsdbExecutor) DataQuery(ctx context.Context, dsInfo *models.DataSou
|
||||
plog.Debug("OpenTsdb request", "params", tsdbQuery)
|
||||
}
|
||||
|
||||
req, err := e.createRequest(dsInfo, tsdbQuery)
|
||||
dsInfo, err := s.getDSInfo(req.PluginContext)
|
||||
if err != nil {
|
||||
return plugins.DataResponse{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
httpClient, err := dsInfo.GetHTTPClient(e.httpClientProvider)
|
||||
request, err := s.createRequest(dsInfo, tsdbQuery)
|
||||
if err != nil {
|
||||
return plugins.DataResponse{}, err
|
||||
return &backend.QueryDataResponse{}, err
|
||||
}
|
||||
|
||||
res, err := ctxhttp.Do(ctx, httpClient, req)
|
||||
res, err := ctxhttp.Do(ctx, dsInfo.HTTPClient, request)
|
||||
if err != nil {
|
||||
return plugins.DataResponse{}, err
|
||||
return &backend.QueryDataResponse{}, err
|
||||
}
|
||||
|
||||
queryResult, err := e.parseResponse(tsdbQuery, res)
|
||||
result, err := s.parseResponse(res)
|
||||
if err != nil {
|
||||
return plugins.DataResponse{}, err
|
||||
return &backend.QueryDataResponse{}, err
|
||||
}
|
||||
|
||||
return plugins.DataResponse{
|
||||
Results: queryResult,
|
||||
}, nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (e *OpenTsdbExecutor) createRequest(dsInfo *models.DataSource, data OpenTsdbQuery) (*http.Request, error) {
|
||||
u, err := url.Parse(dsInfo.Url)
|
||||
func (s *Service) createRequest(dsInfo *datasourceInfo, data OpenTsdbQuery) (*http.Request, error) {
|
||||
u, err := url.Parse(dsInfo.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -104,17 +146,11 @@ func (e *OpenTsdbExecutor) createRequest(dsInfo *models.DataSource, data OpenTsd
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if dsInfo.BasicAuth {
|
||||
req.SetBasicAuth(dsInfo.BasicAuthUser, dsInfo.DecryptedBasicAuthPassword())
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// nolint:staticcheck // plugins.DataQueryResult deprecated
|
||||
func (e *OpenTsdbExecutor) parseResponse(query OpenTsdbQuery, res *http.Response) (map[string]plugins.DataQueryResult, error) {
|
||||
queryResults := make(map[string]plugins.DataQueryResult)
|
||||
queryRes := plugins.DataQueryResult{}
|
||||
func (s *Service) parseResponse(res *http.Response) (*backend.QueryDataResponse, error) {
|
||||
resp := backend.NewQueryDataResponse()
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
@ -157,45 +193,51 @@ func (e *OpenTsdbExecutor) parseResponse(query OpenTsdbQuery, res *http.Response
|
||||
data.NewField("time", nil, timeVector),
|
||||
data.NewField("value", nil, values)))
|
||||
}
|
||||
queryRes.Dataframes = plugins.NewDecodedDataFrames(frames)
|
||||
queryResults["A"] = queryRes
|
||||
return queryResults, nil
|
||||
result := resp.Responses["A"]
|
||||
result.Frames = frames
|
||||
resp.Responses["A"] = result
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (e *OpenTsdbExecutor) buildMetric(query plugins.DataSubQuery) map[string]interface{} {
|
||||
func (s *Service) buildMetric(query backend.DataQuery) map[string]interface{} {
|
||||
metric := make(map[string]interface{})
|
||||
|
||||
model, err := simplejson.NewJson(query.JSON)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setting metric and aggregator
|
||||
metric["metric"] = query.Model.Get("metric").MustString()
|
||||
metric["aggregator"] = query.Model.Get("aggregator").MustString()
|
||||
metric["metric"] = model.Get("metric").MustString()
|
||||
metric["aggregator"] = model.Get("aggregator").MustString()
|
||||
|
||||
// Setting downsampling options
|
||||
disableDownsampling := query.Model.Get("disableDownsampling").MustBool()
|
||||
disableDownsampling := model.Get("disableDownsampling").MustBool()
|
||||
if !disableDownsampling {
|
||||
downsampleInterval := query.Model.Get("downsampleInterval").MustString()
|
||||
downsampleInterval := model.Get("downsampleInterval").MustString()
|
||||
if downsampleInterval == "" {
|
||||
downsampleInterval = "1m" // default value for blank
|
||||
}
|
||||
downsample := downsampleInterval + "-" + query.Model.Get("downsampleAggregator").MustString()
|
||||
if query.Model.Get("downsampleFillPolicy").MustString() != "none" {
|
||||
metric["downsample"] = downsample + "-" + query.Model.Get("downsampleFillPolicy").MustString()
|
||||
downsample := downsampleInterval + "-" + model.Get("downsampleAggregator").MustString()
|
||||
if model.Get("downsampleFillPolicy").MustString() != "none" {
|
||||
metric["downsample"] = downsample + "-" + model.Get("downsampleFillPolicy").MustString()
|
||||
} else {
|
||||
metric["downsample"] = downsample
|
||||
}
|
||||
}
|
||||
|
||||
// Setting rate options
|
||||
if query.Model.Get("shouldComputeRate").MustBool() {
|
||||
if model.Get("shouldComputeRate").MustBool() {
|
||||
metric["rate"] = true
|
||||
rateOptions := make(map[string]interface{})
|
||||
rateOptions["counter"] = query.Model.Get("isCounter").MustBool()
|
||||
rateOptions["counter"] = model.Get("isCounter").MustBool()
|
||||
|
||||
counterMax, counterMaxCheck := query.Model.CheckGet("counterMax")
|
||||
counterMax, counterMaxCheck := model.CheckGet("counterMax")
|
||||
if counterMaxCheck {
|
||||
rateOptions["counterMax"] = counterMax.MustFloat64()
|
||||
}
|
||||
|
||||
resetValue, resetValueCheck := query.Model.CheckGet("counterResetValue")
|
||||
resetValue, resetValueCheck := model.CheckGet("counterResetValue")
|
||||
if resetValueCheck {
|
||||
rateOptions["resetValue"] = resetValue.MustFloat64()
|
||||
}
|
||||
@ -208,16 +250,30 @@ func (e *OpenTsdbExecutor) buildMetric(query plugins.DataSubQuery) map[string]in
|
||||
}
|
||||
|
||||
// Setting tags
|
||||
tags, tagsCheck := query.Model.CheckGet("tags")
|
||||
tags, tagsCheck := model.CheckGet("tags")
|
||||
if tagsCheck && len(tags.MustMap()) > 0 {
|
||||
metric["tags"] = tags.MustMap()
|
||||
}
|
||||
|
||||
// Setting filters
|
||||
filters, filtersCheck := query.Model.CheckGet("filters")
|
||||
filters, filtersCheck := model.CheckGet("filters")
|
||||
if filtersCheck && len(filters.MustArray()) > 0 {
|
||||
metric["filters"] = filters.MustArray()
|
||||
}
|
||||
|
||||
return metric
|
||||
}
|
||||
|
||||
func (s *Service) getDSInfo(pluginCtx backend.PluginContext) (*datasourceInfo, error) {
|
||||
i, err := s.im.Get(pluginCtx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
instance, ok := i.(*datasourceInfo)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to cast datsource info")
|
||||
}
|
||||
|
||||
return instance, nil
|
||||
}
|
||||
|
@ -8,19 +8,17 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestOpenTsdbExecutor(t *testing.T) {
|
||||
exec := &OpenTsdbExecutor{}
|
||||
service := &Service{}
|
||||
|
||||
t.Run("create request", func(t *testing.T) {
|
||||
req, err := exec.createRequest(&models.DataSource{}, OpenTsdbQuery{})
|
||||
req, err := service.createRequest(&datasourceInfo{}, OpenTsdbQuery{})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, "POST", req.Method)
|
||||
@ -34,10 +32,8 @@ func TestOpenTsdbExecutor(t *testing.T) {
|
||||
t.Run("Parse response should handle invalid JSON", func(t *testing.T) {
|
||||
response := `{ invalid }`
|
||||
|
||||
query := OpenTsdbQuery{}
|
||||
|
||||
result, err := exec.parseResponse(query, &http.Response{Body: ioutil.NopCloser(strings.NewReader(response))})
|
||||
require.Nil(t, result["A"].Dataframes)
|
||||
result, err := service.parseResponse(&http.Response{Body: ioutil.NopCloser(strings.NewReader(response))})
|
||||
require.Nil(t, result)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
@ -60,37 +56,33 @@ func TestOpenTsdbExecutor(t *testing.T) {
|
||||
50}),
|
||||
)
|
||||
|
||||
query := OpenTsdbQuery{}
|
||||
|
||||
resp := http.Response{Body: ioutil.NopCloser(strings.NewReader(response))}
|
||||
resp.StatusCode = 200
|
||||
result, err := exec.parseResponse(query, &resp)
|
||||
result, err := service.parseResponse(&resp)
|
||||
require.NoError(t, err)
|
||||
|
||||
decoded, err := result["A"].Dataframes.Decoded()
|
||||
require.NoError(t, err)
|
||||
require.Len(t, decoded, 1)
|
||||
frame := result.Responses["A"]
|
||||
|
||||
frame := decoded[0]
|
||||
|
||||
if diff := cmp.Diff(testFrame, frame, data.FrameTestCompareOptions()...); diff != "" {
|
||||
if diff := cmp.Diff(testFrame, frame.Frames[0], data.FrameTestCompareOptions()...); diff != "" {
|
||||
t.Errorf("Result mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Build metric with downsampling enabled", func(t *testing.T) {
|
||||
query := plugins.DataSubQuery{
|
||||
Model: simplejson.New(),
|
||||
query := backend.DataQuery{
|
||||
JSON: []byte(`
|
||||
{
|
||||
"metric": "cpu.average.percent",
|
||||
"aggregator": "avg",
|
||||
"disableDownsampling": false,
|
||||
"downsampleInterval": "",
|
||||
"downsampleAggregator": "avg",
|
||||
"downsampleFillPolicy": "none"
|
||||
}`,
|
||||
),
|
||||
}
|
||||
|
||||
query.Model.Set("metric", "cpu.average.percent")
|
||||
query.Model.Set("aggregator", "avg")
|
||||
query.Model.Set("disableDownsampling", false)
|
||||
query.Model.Set("downsampleInterval", "")
|
||||
query.Model.Set("downsampleAggregator", "avg")
|
||||
query.Model.Set("downsampleFillPolicy", "none")
|
||||
|
||||
metric := exec.buildMetric(query)
|
||||
metric := service.buildMetric(query)
|
||||
|
||||
require.Len(t, metric, 3)
|
||||
require.Equal(t, "cpu.average.percent", metric["metric"])
|
||||
@ -99,18 +91,20 @@ func TestOpenTsdbExecutor(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Build metric with downsampling disabled", func(t *testing.T) {
|
||||
query := plugins.DataSubQuery{
|
||||
Model: simplejson.New(),
|
||||
query := backend.DataQuery{
|
||||
JSON: []byte(`
|
||||
{
|
||||
"metric": "cpu.average.percent",
|
||||
"aggregator": "avg",
|
||||
"disableDownsampling": true,
|
||||
"downsampleInterval": "",
|
||||
"downsampleAggregator": "avg",
|
||||
"downsampleFillPolicy": "none"
|
||||
}`,
|
||||
),
|
||||
}
|
||||
|
||||
query.Model.Set("metric", "cpu.average.percent")
|
||||
query.Model.Set("aggregator", "avg")
|
||||
query.Model.Set("disableDownsampling", true)
|
||||
query.Model.Set("downsampleInterval", "")
|
||||
query.Model.Set("downsampleAggregator", "avg")
|
||||
query.Model.Set("downsampleFillPolicy", "none")
|
||||
|
||||
metric := exec.buildMetric(query)
|
||||
metric := service.buildMetric(query)
|
||||
|
||||
require.Len(t, metric, 2)
|
||||
require.Equal(t, "cpu.average.percent", metric["metric"])
|
||||
@ -118,18 +112,20 @@ func TestOpenTsdbExecutor(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Build metric with downsampling enabled with params", func(t *testing.T) {
|
||||
query := plugins.DataSubQuery{
|
||||
Model: simplejson.New(),
|
||||
query := backend.DataQuery{
|
||||
JSON: []byte(`
|
||||
{
|
||||
"metric": "cpu.average.percent",
|
||||
"aggregator": "avg",
|
||||
"disableDownsampling": false,
|
||||
"downsampleInterval": "5m",
|
||||
"downsampleAggregator": "sum",
|
||||
"downsampleFillPolicy": "null"
|
||||
}`,
|
||||
),
|
||||
}
|
||||
|
||||
query.Model.Set("metric", "cpu.average.percent")
|
||||
query.Model.Set("aggregator", "avg")
|
||||
query.Model.Set("disableDownsampling", false)
|
||||
query.Model.Set("downsampleInterval", "5m")
|
||||
query.Model.Set("downsampleAggregator", "sum")
|
||||
query.Model.Set("downsampleFillPolicy", "null")
|
||||
|
||||
metric := exec.buildMetric(query)
|
||||
metric := service.buildMetric(query)
|
||||
|
||||
require.Len(t, metric, 3)
|
||||
require.Equal(t, "cpu.average.percent", metric["metric"])
|
||||
@ -138,23 +134,24 @@ func TestOpenTsdbExecutor(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Build metric with tags with downsampling disabled", func(t *testing.T) {
|
||||
query := plugins.DataSubQuery{
|
||||
Model: simplejson.New(),
|
||||
query := backend.DataQuery{
|
||||
JSON: []byte(`
|
||||
{
|
||||
"metric": "cpu.average.percent",
|
||||
"aggregator": "avg",
|
||||
"disableDownsampling": true,
|
||||
"downsampleInterval": "5m",
|
||||
"downsampleAggregator": "sum",
|
||||
"downsampleFillPolicy": "null",
|
||||
"tags": {
|
||||
"env": "prod",
|
||||
"app": "grafana"
|
||||
}
|
||||
}`,
|
||||
),
|
||||
}
|
||||
|
||||
query.Model.Set("metric", "cpu.average.percent")
|
||||
query.Model.Set("aggregator", "avg")
|
||||
query.Model.Set("disableDownsampling", true)
|
||||
query.Model.Set("downsampleInterval", "5m")
|
||||
query.Model.Set("downsampleAggregator", "sum")
|
||||
query.Model.Set("downsampleFillPolicy", "null")
|
||||
|
||||
tags := simplejson.New()
|
||||
tags.Set("env", "prod")
|
||||
tags.Set("app", "grafana")
|
||||
query.Model.Set("tags", tags.MustMap())
|
||||
|
||||
metric := exec.buildMetric(query)
|
||||
metric := service.buildMetric(query)
|
||||
|
||||
require.Len(t, metric, 3)
|
||||
require.Equal(t, "cpu.average.percent", metric["metric"])
|
||||
@ -169,22 +166,23 @@ func TestOpenTsdbExecutor(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Build metric with rate enabled but counter disabled", func(t *testing.T) {
|
||||
query := plugins.DataSubQuery{
|
||||
Model: simplejson.New(),
|
||||
query := backend.DataQuery{
|
||||
JSON: []byte(`
|
||||
{
|
||||
"metric": "cpu.average.percent",
|
||||
"aggregator": "avg",
|
||||
"disableDownsampling": true,
|
||||
"shouldComputeRate": true,
|
||||
"isCounter": false,
|
||||
"tags": {
|
||||
"env": "prod",
|
||||
"app": "grafana"
|
||||
}
|
||||
}`,
|
||||
),
|
||||
}
|
||||
|
||||
query.Model.Set("metric", "cpu.average.percent")
|
||||
query.Model.Set("aggregator", "avg")
|
||||
query.Model.Set("disableDownsampling", true)
|
||||
query.Model.Set("shouldComputeRate", true)
|
||||
query.Model.Set("isCounter", false)
|
||||
|
||||
tags := simplejson.New()
|
||||
tags.Set("env", "prod")
|
||||
tags.Set("app", "grafana")
|
||||
query.Model.Set("tags", tags.MustMap())
|
||||
|
||||
metric := exec.buildMetric(query)
|
||||
metric := service.buildMetric(query)
|
||||
|
||||
require.Len(t, metric, 5)
|
||||
require.Equal(t, "cpu.average.percent", metric["metric"])
|
||||
@ -201,24 +199,25 @@ func TestOpenTsdbExecutor(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Build metric with rate and counter enabled", func(t *testing.T) {
|
||||
query := plugins.DataSubQuery{
|
||||
Model: simplejson.New(),
|
||||
query := backend.DataQuery{
|
||||
JSON: []byte(`
|
||||
{
|
||||
"metric": "cpu.average.percent",
|
||||
"aggregator": "avg",
|
||||
"disableDownsampling": true,
|
||||
"shouldComputeRate": true,
|
||||
"isCounter": true,
|
||||
"counterMax": 45,
|
||||
"counterResetValue": 60,
|
||||
"tags": {
|
||||
"env": "prod",
|
||||
"app": "grafana"
|
||||
}
|
||||
}`,
|
||||
),
|
||||
}
|
||||
|
||||
query.Model.Set("metric", "cpu.average.percent")
|
||||
query.Model.Set("aggregator", "avg")
|
||||
query.Model.Set("disableDownsampling", true)
|
||||
query.Model.Set("shouldComputeRate", true)
|
||||
query.Model.Set("isCounter", true)
|
||||
query.Model.Set("counterMax", 45)
|
||||
query.Model.Set("counterResetValue", 60)
|
||||
|
||||
tags := simplejson.New()
|
||||
tags.Set("env", "prod")
|
||||
tags.Set("app", "grafana")
|
||||
query.Model.Set("tags", tags.MustMap())
|
||||
|
||||
metric := exec.buildMetric(query)
|
||||
metric := service.buildMetric(query)
|
||||
|
||||
require.Len(t, metric, 5)
|
||||
require.Equal(t, "cpu.average.percent", metric["metric"])
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/tsdb/loki"
|
||||
"github.com/grafana/grafana/pkg/tsdb/mssql"
|
||||
"github.com/grafana/grafana/pkg/tsdb/mysql"
|
||||
"github.com/grafana/grafana/pkg/tsdb/opentsdb"
|
||||
"github.com/grafana/grafana/pkg/tsdb/postgres"
|
||||
"github.com/grafana/grafana/pkg/tsdb/prometheus"
|
||||
"github.com/grafana/grafana/pkg/tsdb/tempo"
|
||||
@ -57,7 +56,6 @@ type Service struct {
|
||||
// Init initialises the service.
|
||||
func (s *Service) Init() error {
|
||||
s.registry["graphite"] = graphite.New(s.HTTPClientProvider)
|
||||
s.registry["opentsdb"] = opentsdb.New(s.HTTPClientProvider)
|
||||
s.registry["prometheus"] = prometheus.New(s.HTTPClientProvider)
|
||||
s.registry["influxdb"] = influxdb.New(s.HTTPClientProvider)
|
||||
s.registry["mssql"] = mssql.NewExecutor
|
||||
|
Loading…
Reference in New Issue
Block a user