Prometheus: Introduce prometheus backend library (#83952)

* Move files to prometheus-library

* refactor core prometheus to use prometheus-library

* modify client transport options

* mock

* have a type

* import aliases

* rename

* call the right method

* remove unrelated test from the library

* update codeowners

* go work sync

* update go.work.sum

* make swagger-clean && make openapi3-gen

* add promlib to makefile

* remove clilogger

* Export the function

* update unit test

* add prometheus_test.go

* fix mock type

* use mapUtil from grafana-plugin-sdk-go
This commit is contained in:
ismail simsek
2024-03-11 17:22:33 +01:00
committed by GitHub
parent cfc7ea92da
commit 3fb6319d1b
114 changed files with 672 additions and 340 deletions

108
pkg/promlib/healthcheck.go Normal file
View File

@@ -0,0 +1,108 @@
package promlib
import (
"context"
"encoding/json"
"errors"
"fmt"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/promlib/models"
)
const (
refID = "__healthcheck__"
)
var logger = backend.NewLoggerWith("logger", "tsdb.prometheus")
func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult,
error) {
logger := logger.FromContext(ctx)
ds, err := s.getInstance(ctx, req.PluginContext)
// check that the datasource exists
if err != nil {
return getHealthCheckMessage("error getting datasource info", err)
}
if ds == nil {
return getHealthCheckMessage("", errors.New("invalid datasource info received"))
}
hc, err := healthcheck(ctx, req, ds)
if err != nil {
logger.Warn("Error performing prometheus healthcheck", "err", err.Error())
return nil, err
}
heuristics, err := getHeuristics(ctx, ds)
if err != nil {
logger.Warn("Failed to get prometheus heuristics", "err", err.Error())
} else {
jsonDetails, err := json.Marshal(heuristics)
if err != nil {
logger.Warn("Failed to marshal heuristics", "err", err)
} else {
hc.JSONDetails = jsonDetails
}
}
return hc, nil
}
func healthcheck(ctx context.Context, req *backend.CheckHealthRequest, i *instance) (*backend.CheckHealthResult, error) {
qm := models.QueryModel{
UtcOffsetSec: 0,
CommonQueryProperties: models.CommonQueryProperties{
RefId: refID,
},
PrometheusQueryProperties: models.PrometheusQueryProperties{
Expr: "1+1",
Instant: true,
},
}
b, _ := json.Marshal(&qm)
query := backend.DataQuery{
RefID: refID,
TimeRange: backend.TimeRange{
From: time.Unix(1, 0).UTC(),
To: time.Unix(4, 0).UTC(),
},
JSON: b,
}
resp, err := i.queryData.Execute(ctx, &backend.QueryDataRequest{
PluginContext: req.PluginContext,
Queries: []backend.DataQuery{query},
})
if err != nil {
return getHealthCheckMessage("There was an error returned querying the Prometheus API.", err)
}
if resp.Responses[refID].Error != nil {
return getHealthCheckMessage("There was an error returned querying the Prometheus API.",
errors.New(resp.Responses[refID].Error.Error()))
}
return getHealthCheckMessage("Successfully queried the Prometheus API.", nil)
}
func getHealthCheckMessage(message string, err error) (*backend.CheckHealthResult, error) {
if err == nil {
return &backend.CheckHealthResult{
Status: backend.HealthStatusOk,
Message: message,
}, nil
}
errorMessage := fmt.Sprintf("%s - %s", err.Error(), message)
return &backend.CheckHealthResult{
Status: backend.HealthStatusError,
Message: errorMessage,
}, nil
}