Refactor history/trend queries
This commit is contained in:
@@ -2,6 +2,7 @@ package datasource
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
||||||
@@ -9,7 +10,7 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertHistoryToDataFrame(history History, items zabbix.Items) *data.Frame {
|
func convertHistoryToDataFrame(history zabbix.History, items zabbix.Items) *data.Frame {
|
||||||
timeFileld := data.NewFieldFromFieldType(data.FieldTypeTime, 0)
|
timeFileld := data.NewFieldFromFieldType(data.FieldTypeTime, 0)
|
||||||
timeFileld.Name = "time"
|
timeFileld.Name = "time"
|
||||||
frame := data.NewFrame("History", timeFileld)
|
frame := data.NewFrame("History", timeFileld)
|
||||||
@@ -48,3 +49,29 @@ func convertHistoryToDataFrame(history History, items zabbix.Items) *data.Frame
|
|||||||
}
|
}
|
||||||
return wideFrame
|
return wideFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convertTrendToHistory(trend zabbix.Trend, valueType string) (zabbix.History, error) {
|
||||||
|
history := make([]zabbix.HistoryPoint, 0)
|
||||||
|
for _, point := range trend {
|
||||||
|
valueStr := point.ValueAvg
|
||||||
|
switch valueType {
|
||||||
|
case "min":
|
||||||
|
valueStr = point.ValueMin
|
||||||
|
case "max":
|
||||||
|
valueStr = point.ValueMax
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := strconv.ParseFloat(valueStr, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error parsing trend value: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
history = append(history, zabbix.HistoryPoint{
|
||||||
|
ItemID: point.ItemID,
|
||||||
|
Clock: point.Clock,
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return history, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
package datasource
|
package datasource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
||||||
simplejson "github.com/bitly/go-simplejson"
|
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@@ -71,7 +68,7 @@ func (ds *ZabbixDatasourceInstance) queryNumericDataForItems(ctx context.Context
|
|||||||
consolidateBy = valueType
|
consolidateBy = valueType
|
||||||
}
|
}
|
||||||
|
|
||||||
history, err := ds.getHistotyOrTrend(ctx, query, items)
|
history, err := ds.getHistotyOrTrend(ctx, query, items, valueType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -103,59 +100,19 @@ func (ds *ZabbixDatasourceInstance) getConsolidateBy(query *QueryModel) string {
|
|||||||
return consolidateBy
|
return consolidateBy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ZabbixDatasourceInstance) getHistotyOrTrend(ctx context.Context, query *QueryModel, items zabbix.Items) (History, error) {
|
func (ds *ZabbixDatasourceInstance) getHistotyOrTrend(ctx context.Context, query *QueryModel, items zabbix.Items, trendValueType string) (zabbix.History, error) {
|
||||||
timeRange := query.TimeRange
|
timeRange := query.TimeRange
|
||||||
useTrend := ds.isUseTrend(timeRange)
|
useTrend := ds.isUseTrend(timeRange)
|
||||||
allHistory := History{}
|
|
||||||
|
|
||||||
groupedItems := map[int]zabbix.Items{}
|
|
||||||
|
|
||||||
for _, j := range items {
|
|
||||||
groupedItems[j.ValueType] = append(groupedItems[j.ValueType], j)
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, l := range groupedItems {
|
|
||||||
var itemids []string
|
|
||||||
for _, m := range l {
|
|
||||||
itemids = append(itemids, m.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
params := zabbix.ZabbixAPIParams{
|
|
||||||
"output": "extend",
|
|
||||||
"sortfield": "clock",
|
|
||||||
"sortorder": "ASC",
|
|
||||||
"itemids": itemids,
|
|
||||||
"time_from": timeRange.From.Unix(),
|
|
||||||
"time_till": timeRange.To.Unix(),
|
|
||||||
}
|
|
||||||
|
|
||||||
var response *simplejson.Json
|
|
||||||
var err error
|
|
||||||
if useTrend {
|
|
||||||
response, err = ds.zabbix.Request(ctx, &zabbix.ZabbixAPIRequest{Method: "trend.get", Params: params})
|
|
||||||
} else {
|
|
||||||
params["history"] = &k
|
|
||||||
response, err = ds.zabbix.Request(ctx, &zabbix.ZabbixAPIRequest{Method: "history.get", Params: params})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if useTrend {
|
||||||
|
result, err := ds.zabbix.GetTrend(ctx, items, timeRange)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return convertTrendToHistory(result, trendValueType)
|
||||||
pointJSON, err := response.MarshalJSON()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Internal error parsing response JSON: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
history := History{}
|
|
||||||
err = json.Unmarshal(pointJSON, &history)
|
|
||||||
if err != nil {
|
|
||||||
ds.logger.Error("Error handling history response", "error", err.Error())
|
|
||||||
} else {
|
|
||||||
allHistory = append(allHistory, history...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return allHistory, nil
|
|
||||||
|
return ds.zabbix.GetHistory(ctx, items, timeRange)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ds *ZabbixDatasourceInstance) isUseTrend(timeRange backend.TimeRange) bool {
|
func (ds *ZabbixDatasourceInstance) isUseTrend(timeRange backend.TimeRange) bool {
|
||||||
|
|||||||
@@ -2,8 +2,82 @@ package zabbix
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (ds *Zabbix) GetHistory(ctx context.Context, items []Item, timeRange backend.TimeRange) (History, error) {
|
||||||
|
history := History{}
|
||||||
|
// Zabbix stores history in different tables and `history` param required for query. So in one query it's only
|
||||||
|
// possible to get history for items with one type. In order to get history for items with multple types (numeric unsigned and numeric float),
|
||||||
|
// items should be grouped by the `value_type` field.
|
||||||
|
groupedItemids := make(map[int][]string, 0)
|
||||||
|
for _, item := range items {
|
||||||
|
groupedItemids[item.ValueType] = append(groupedItemids[item.ValueType], item.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
for historyType, itemids := range groupedItemids {
|
||||||
|
result, err := ds.getHistory(ctx, itemids, historyType, timeRange)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
history = append(history, result...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return history, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *Zabbix) getHistory(ctx context.Context, itemids []string, historyType int, timeRange backend.TimeRange) (History, error) {
|
||||||
|
params := ZabbixAPIParams{
|
||||||
|
"output": "extend",
|
||||||
|
"itemids": itemids,
|
||||||
|
"history": historyType,
|
||||||
|
"time_from": timeRange.From.Unix(),
|
||||||
|
"time_till": timeRange.To.Unix(),
|
||||||
|
"sortfield": "clock",
|
||||||
|
"sortorder": "ASC",
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := ds.Request(ctx, &ZabbixAPIRequest{Method: "history.get", Params: params})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var history History
|
||||||
|
err = convertTo(result, &history)
|
||||||
|
return history, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *Zabbix) GetTrend(ctx context.Context, items []Item, timeRange backend.TimeRange) (Trend, error) {
|
||||||
|
itemids := make([]string, 0)
|
||||||
|
for _, item := range items {
|
||||||
|
itemids = append(itemids, item.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ds.getTrend(ctx, itemids, timeRange)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *Zabbix) getTrend(ctx context.Context, itemids []string, timeRange backend.TimeRange) (Trend, error) {
|
||||||
|
params := ZabbixAPIParams{
|
||||||
|
"output": "extend",
|
||||||
|
"itemids": itemids,
|
||||||
|
"time_from": timeRange.From.Unix(),
|
||||||
|
"time_till": timeRange.To.Unix(),
|
||||||
|
"sortfield": "clock",
|
||||||
|
"sortorder": "ASC",
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := ds.Request(ctx, &ZabbixAPIRequest{Method: "trend.get", Params: params})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var trend Trend
|
||||||
|
err = convertTo(result, &trend)
|
||||||
|
return trend, err
|
||||||
|
}
|
||||||
|
|
||||||
func (ds *Zabbix) GetItems(ctx context.Context, groupFilter string, hostFilter string, appFilter string, itemFilter string, itemType string) ([]Item, error) {
|
func (ds *Zabbix) GetItems(ctx context.Context, groupFilter string, hostFilter string, appFilter string, itemFilter string, itemType string) ([]Item, error) {
|
||||||
hosts, err := ds.GetHosts(ctx, groupFilter, hostFilter)
|
hosts, err := ds.GetHosts(ctx, groupFilter, hostFilter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user