Handle db connection response on the backend

This commit is contained in:
Alexander Zobnin
2021-08-04 18:07:38 +03:00
parent 848ea8a9a0
commit e12b8cbefb
10 changed files with 233 additions and 33 deletions

View File

@@ -3,6 +3,7 @@ package datasource
import (
"encoding/json"
"fmt"
"github.com/alexanderzobnin/grafana-zabbix/pkg/timeseries"
"strconv"
"time"
@@ -44,6 +45,11 @@ type ZabbixDatasourceSettings struct {
DisableReadOnlyUsersAck bool `json:"disableReadOnlyUsersAck"`
}
type DBConnectionPostProcessingRequest struct {
Query QueryModel `json:"query"`
Series []*timeseries.TimeSeriesData `json:"series"`
}
type ZabbixAPIResourceRequest struct {
DatasourceId int64 `json:"datasourceId"`
Method string `json:"method"`

View File

@@ -60,6 +60,47 @@ func (ds *ZabbixDatasource) ZabbixAPIHandler(rw http.ResponseWriter, req *http.R
writeResponse(rw, result)
}
func (ds *ZabbixDatasource) DBConnectionPostProcessingHandler(rw http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPost {
return
}
body, err := ioutil.ReadAll(req.Body)
defer req.Body.Close()
if err != nil || len(body) == 0 {
writeError(rw, http.StatusBadRequest, err)
return
}
var reqData DBConnectionPostProcessingRequest
err = json.Unmarshal(body, &reqData)
if err != nil {
ds.logger.Error("Cannot unmarshal request", "error", err.Error())
writeError(rw, http.StatusInternalServerError, err)
return
}
pluginCxt := httpadapter.PluginConfigFromContext(req.Context())
dsInstance, err := ds.getDSInstance(pluginCxt)
if err != nil {
ds.logger.Error("Error loading datasource", "error", err)
writeError(rw, http.StatusInternalServerError, err)
return
}
frames, err := dsInstance.applyDataProcessing(req.Context(), &reqData.Query, reqData.Series)
resultJson, err := json.Marshal(frames)
if err != nil {
writeError(rw, http.StatusInternalServerError, err)
}
rw.Header().Add("Content-Type", "application/json")
rw.WriteHeader(http.StatusOK)
rw.Write(resultJson)
}
func writeResponse(rw http.ResponseWriter, result *ZabbixAPIResourceResponse) {
resultJson, err := json.Marshal(*result)
if err != nil {

View File

@@ -1,6 +1,7 @@
package datasource
import (
"github.com/alexanderzobnin/grafana-zabbix/pkg/timeseries"
"strings"
"time"
@@ -134,6 +135,43 @@ func (ds *ZabbixDatasourceInstance) queryNumericDataForItems(ctx context.Context
return frames, nil
}
func (ds *ZabbixDatasourceInstance) applyDataProcessing(ctx context.Context, query *QueryModel, series []*timeseries.TimeSeriesData) ([]*data.Frame, error) {
consolidateBy := ds.getConsolidateBy(query)
// Align time series data if possible
useTrend := ds.isUseTrend(query.TimeRange)
if !query.Options.DisableDataAlignment && !ds.Settings.DisableDataAlignment && !useTrend {
for _, s := range series {
if s.Meta.Interval != nil {
s.TS = s.TS.Align(*s.Meta.Interval)
}
}
}
series, err := applyFunctions(series, query.Functions)
if err != nil {
return nil, err
}
for _, s := range series {
if int64(s.Len()) > query.MaxDataPoints && query.Interval > 0 {
downsampleFunc := consolidateBy
if downsampleFunc == "" {
downsampleFunc = "avg"
}
downsampled, err := applyGroupBy(s.TS, query.Interval.String(), downsampleFunc)
if err == nil {
s.TS = downsampled
} else {
ds.logger.Debug("Error downsampling series", "error", err)
}
}
}
frames := convertTimeSeriesToDataFrames(series)
return frames, nil
}
func (ds *ZabbixDatasourceInstance) getTrendValueType(query *QueryModel) string {
trendValue := "avg"

View File

@@ -45,6 +45,7 @@ func Init(logger log.Logger, mux *http.ServeMux) *datasource.ZabbixDatasource {
mux.HandleFunc("/", ds.RootHandler)
mux.HandleFunc("/zabbix-api", ds.ZabbixAPIHandler)
mux.HandleFunc("/db-connection-post", ds.DBConnectionPostProcessingHandler)
// mux.Handle("/scenarios", getScenariosHandler(logger))
return ds

View File

@@ -1,6 +1,7 @@
package timeseries
import (
"encoding/json"
"time"
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
@@ -11,6 +12,22 @@ type TimePoint struct {
Value *float64
}
func (p *TimePoint) UnmarshalJSON(data []byte) error {
point := &struct {
Time int64
Value *float64
}{}
if err := json.Unmarshal(data, &point); err != nil {
return err
}
p.Value = point.Value
p.Time = time.Unix(point.Time, 0)
return nil
}
type TimeSeries []TimePoint
func NewTimeSeries() TimeSeries {