|
|
|
@@ -15,22 +15,19 @@ import (
|
|
|
|
|
|
|
|
|
|
"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/httpclient"
|
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
|
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
|
|
|
|
|
"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/setting"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var logger = log.New("tsdb.opentsdb")
|
|
|
|
|
var logger = backend.NewLoggerWith("tsdb.opentsdb")
|
|
|
|
|
|
|
|
|
|
type Service struct {
|
|
|
|
|
im instancemgmt.InstanceManager
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ProvideService(httpClientProvider httpclient.Provider) *Service {
|
|
|
|
|
func ProvideService(httpClientProvider *httpclient.Provider) *Service {
|
|
|
|
|
return &Service{
|
|
|
|
|
im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)),
|
|
|
|
|
}
|
|
|
|
@@ -52,7 +49,22 @@ type JSONData struct {
|
|
|
|
|
LookupLimit int32 `json:"lookupLimit"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc {
|
|
|
|
|
type QueryModel struct {
|
|
|
|
|
Metric string `json:"metric"`
|
|
|
|
|
Aggregator string `json:"aggregator"`
|
|
|
|
|
DownsampleInterval string `json:"downsampleInterval"`
|
|
|
|
|
DownsampleAggregator string `json:"downsampleAggregator"`
|
|
|
|
|
DownsampleFillPolicy string `json:"downsampleFillPolicy"`
|
|
|
|
|
DisableDownsampling bool `json:"disableDownsampling"`
|
|
|
|
|
Filters []any `json:"filters"`
|
|
|
|
|
Tags map[string]interface{} `json:"tags"`
|
|
|
|
|
ShouldComputeRate bool `json:"shouldComputeRate"`
|
|
|
|
|
IsCounter bool `json:"isCounter"`
|
|
|
|
|
CounterMax float64 `json:"counterMax"`
|
|
|
|
|
CounterResetValue float64 `json:"counterResetValue"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newInstanceSettings(httpClientProvider *httpclient.Provider) datasource.InstanceFactoryFunc {
|
|
|
|
|
return func(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
|
|
|
|
|
opts, err := settings.HTTPClientOptions(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
@@ -102,10 +114,6 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest)
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if setting.Env == setting.Dev {
|
|
|
|
|
logger.Debug("OpenTsdb request", "refId", query.RefID, "params", tsdbQuery)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
httpReq, err := s.createRequest(ctx, logger, dsInfo, tsdbQuery)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
@@ -274,47 +282,44 @@ func (s *Service) parseResponse(logger log.Logger, res *http.Response, refID str
|
|
|
|
|
func (s *Service) buildMetric(query backend.DataQuery) map[string]any {
|
|
|
|
|
metric := make(map[string]any)
|
|
|
|
|
|
|
|
|
|
model, err := simplejson.NewJson(query.JSON)
|
|
|
|
|
if err != nil {
|
|
|
|
|
var model QueryModel
|
|
|
|
|
if err := json.Unmarshal(query.JSON, &model); err != nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setting metric and aggregator
|
|
|
|
|
metric["metric"] = model.Get("metric").MustString()
|
|
|
|
|
metric["aggregator"] = model.Get("aggregator").MustString()
|
|
|
|
|
metric["metric"] = model.Metric
|
|
|
|
|
metric["aggregator"] = model.Aggregator
|
|
|
|
|
|
|
|
|
|
// Setting downsampling options
|
|
|
|
|
disableDownsampling := model.Get("disableDownsampling").MustBool()
|
|
|
|
|
if !disableDownsampling {
|
|
|
|
|
downsampleInterval := model.Get("downsampleInterval").MustString()
|
|
|
|
|
if !model.DisableDownsampling {
|
|
|
|
|
downsampleInterval := model.DownsampleInterval
|
|
|
|
|
if downsampleInterval == "" {
|
|
|
|
|
downsampleInterval = "1m" // default value for blank
|
|
|
|
|
}
|
|
|
|
|
downsample := downsampleInterval + "-" + model.Get("downsampleAggregator").MustString()
|
|
|
|
|
if model.Get("downsampleFillPolicy").MustString() != "none" {
|
|
|
|
|
metric["downsample"] = downsample + "-" + model.Get("downsampleFillPolicy").MustString()
|
|
|
|
|
downsample := downsampleInterval + "-" + model.DownsampleAggregator
|
|
|
|
|
if model.DownsampleFillPolicy != "none" {
|
|
|
|
|
metric["downsample"] = downsample + "-" + model.DownsampleFillPolicy
|
|
|
|
|
} else {
|
|
|
|
|
metric["downsample"] = downsample
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setting rate options
|
|
|
|
|
if model.Get("shouldComputeRate").MustBool() {
|
|
|
|
|
if model.ShouldComputeRate {
|
|
|
|
|
metric["rate"] = true
|
|
|
|
|
rateOptions := make(map[string]any)
|
|
|
|
|
rateOptions["counter"] = model.Get("isCounter").MustBool()
|
|
|
|
|
rateOptions["counter"] = model.IsCounter
|
|
|
|
|
|
|
|
|
|
counterMax, counterMaxCheck := model.CheckGet("counterMax")
|
|
|
|
|
if counterMaxCheck {
|
|
|
|
|
rateOptions["counterMax"] = counterMax.MustFloat64()
|
|
|
|
|
if model.CounterMax != 0 {
|
|
|
|
|
rateOptions["counterMax"] = model.CounterMax
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resetValue, resetValueCheck := model.CheckGet("counterResetValue")
|
|
|
|
|
if resetValueCheck {
|
|
|
|
|
rateOptions["resetValue"] = resetValue.MustFloat64()
|
|
|
|
|
if model.CounterResetValue != 0 {
|
|
|
|
|
rateOptions["resetValue"] = model.CounterResetValue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !counterMaxCheck && (!resetValueCheck || resetValue.MustFloat64() == 0) {
|
|
|
|
|
if model.CounterMax == 0 && (model.CounterResetValue == 0) {
|
|
|
|
|
rateOptions["dropResets"] = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -322,15 +327,13 @@ func (s *Service) buildMetric(query backend.DataQuery) map[string]any {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setting tags
|
|
|
|
|
tags, tagsCheck := model.CheckGet("tags")
|
|
|
|
|
if tagsCheck && len(tags.MustMap()) > 0 {
|
|
|
|
|
metric["tags"] = tags.MustMap()
|
|
|
|
|
if len(model.Tags) > 0 {
|
|
|
|
|
metric["tags"] = model.Tags
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setting filters
|
|
|
|
|
filters, filtersCheck := model.CheckGet("filters")
|
|
|
|
|
if filtersCheck && len(filters.MustArray()) > 0 {
|
|
|
|
|
metric["filters"] = filters.MustArray()
|
|
|
|
|
if len(model.Filters) > 0 {
|
|
|
|
|
metric["filters"] = model.Filters
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return metric
|
|
|
|
|