Refactor history/trend queries
This commit is contained in:
@@ -2,6 +2,7 @@ package datasource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
"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.Name = "time"
|
||||
frame := data.NewFrame("History", timeFileld)
|
||||
@@ -48,3 +49,29 @@ func convertHistoryToDataFrame(history History, items zabbix.Items) *data.Frame
|
||||
}
|
||||
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
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"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/data"
|
||||
"golang.org/x/net/context"
|
||||
@@ -71,7 +68,7 @@ func (ds *ZabbixDatasourceInstance) queryNumericDataForItems(ctx context.Context
|
||||
consolidateBy = valueType
|
||||
}
|
||||
|
||||
history, err := ds.getHistotyOrTrend(ctx, query, items)
|
||||
history, err := ds.getHistotyOrTrend(ctx, query, items, valueType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -103,59 +100,19 @@ func (ds *ZabbixDatasourceInstance) getConsolidateBy(query *QueryModel) string {
|
||||
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
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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 convertTrendToHistory(result, trendValueType)
|
||||
}
|
||||
return allHistory, nil
|
||||
|
||||
return ds.zabbix.GetHistory(ctx, items, timeRange)
|
||||
}
|
||||
|
||||
func (ds *ZabbixDatasourceInstance) isUseTrend(timeRange backend.TimeRange) bool {
|
||||
|
||||
@@ -2,8 +2,82 @@ package zabbix
|
||||
|
||||
import (
|
||||
"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) {
|
||||
hosts, err := ds.GetHosts(ctx, groupFilter, hostFilter)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user