Use backend queries for item id mode
This commit is contained in:
@@ -122,15 +122,22 @@ func (ds *ZabbixDatasource) QueryData(ctx context.Context, req *backend.QueryDat
|
|||||||
ds.logger.Debug("DS query", "query", q)
|
ds.logger.Debug("DS query", "query", q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.Error = err
|
res.Error = err
|
||||||
} else if query.Mode != 0 {
|
} else if query.QueryType == MODE_METRICS {
|
||||||
res.Error = ErrNonMetricQueryNotSupported
|
|
||||||
} else {
|
|
||||||
frames, err := zabbixDS.queryNumericItems(ctx, &query)
|
frames, err := zabbixDS.queryNumericItems(ctx, &query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.Error = err
|
res.Error = err
|
||||||
} else {
|
} else {
|
||||||
res.Frames = append(res.Frames, frames...)
|
res.Frames = append(res.Frames, frames...)
|
||||||
}
|
}
|
||||||
|
} else if query.QueryType == MODE_ITEMID {
|
||||||
|
frames, err := zabbixDS.queryItemIdData(ctx, &query)
|
||||||
|
if err != nil {
|
||||||
|
res.Error = err
|
||||||
|
} else {
|
||||||
|
res.Frames = append(res.Frames, frames...)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.Error = ErrNonMetricQueryNotSupported
|
||||||
}
|
}
|
||||||
qdr.Responses[q.RefID] = res
|
qdr.Responses[q.RefID] = res
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,15 @@ import (
|
|||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MODE_METRICS = "0"
|
||||||
|
MODE_ITSERVICE = "1"
|
||||||
|
MODE_TEXT = "2"
|
||||||
|
MODE_ITEMID = "3"
|
||||||
|
MODE_TRIGGERS = "4"
|
||||||
|
MODE_PROBLEMS = "5"
|
||||||
|
)
|
||||||
|
|
||||||
// ZabbixDatasourceSettingsDTO model
|
// ZabbixDatasourceSettingsDTO model
|
||||||
type ZabbixDatasourceSettingsDTO struct {
|
type ZabbixDatasourceSettingsDTO struct {
|
||||||
Trends bool `json:"trends"`
|
Trends bool `json:"trends"`
|
||||||
@@ -44,11 +53,17 @@ type ZabbixAPIResourceResponse struct {
|
|||||||
|
|
||||||
// QueryModel model
|
// QueryModel model
|
||||||
type QueryModel struct {
|
type QueryModel struct {
|
||||||
|
// Deprecated `mode` field, use QueryType instead
|
||||||
Mode int64 `json:"mode"`
|
Mode int64 `json:"mode"`
|
||||||
|
|
||||||
Group QueryFilter `json:"group"`
|
Group QueryFilter `json:"group"`
|
||||||
Host QueryFilter `json:"host"`
|
Host QueryFilter `json:"host"`
|
||||||
Application QueryFilter `json:"application"`
|
Application QueryFilter `json:"application"`
|
||||||
Item QueryFilter `json:"item"`
|
Item QueryFilter `json:"item"`
|
||||||
|
|
||||||
|
// Item ID mode
|
||||||
|
ItemIDs string `json:"itemids,omitempty"`
|
||||||
|
|
||||||
Functions []QueryFunction `json:"functions,omitempty"`
|
Functions []QueryFunction `json:"functions,omitempty"`
|
||||||
Options QueryOptions `json:"options"`
|
Options QueryOptions `json:"options"`
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package datasource
|
package datasource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
||||||
@@ -60,6 +61,25 @@ func (ds *ZabbixDatasourceInstance) queryNumericItems(ctx context.Context, query
|
|||||||
return frames, nil
|
return frames, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ds *ZabbixDatasourceInstance) queryItemIdData(ctx context.Context, query *QueryModel) ([]*data.Frame, error) {
|
||||||
|
itemids := strings.Split(query.ItemIDs, ",")
|
||||||
|
for i, id := range itemids {
|
||||||
|
itemids[i] = strings.Trim(id, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
items, err := ds.zabbix.GetItemsByIDs(ctx, itemids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
frames, err := ds.queryNumericDataForItems(ctx, query, items)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ds *ZabbixDatasourceInstance) queryNumericDataForItems(ctx context.Context, query *QueryModel, items []*zabbix.Item) ([]*data.Frame, error) {
|
func (ds *ZabbixDatasourceInstance) queryNumericDataForItems(ctx context.Context, query *QueryModel, items []*zabbix.Item) ([]*data.Frame, error) {
|
||||||
trendValueType := ds.getTrendValueType(query)
|
trendValueType := ds.getTrendValueType(query)
|
||||||
consolidateBy := ds.getConsolidateBy(query)
|
consolidateBy := ds.getConsolidateBy(query)
|
||||||
|
|||||||
@@ -274,6 +274,29 @@ func (ds *Zabbix) GetAllItems(ctx context.Context, hostids []string, appids []st
|
|||||||
return items, err
|
return items, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ds *Zabbix) GetItemsByIDs(ctx context.Context, itemids []string) ([]*Item, error) {
|
||||||
|
params := ZabbixAPIParams{
|
||||||
|
"itemids": itemids,
|
||||||
|
"output": []string{"itemid", "name", "key_", "value_type", "hostid", "status", "state", "units", "valuemapid", "delay"},
|
||||||
|
"webitems": true,
|
||||||
|
"selectHosts": []string{"hostid", "name"},
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := ds.Request(ctx, &ZabbixAPIRequest{Method: "item.get", Params: params})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var items []*Item
|
||||||
|
err = convertTo(result, &items)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
items = expandItems(items)
|
||||||
|
return items, err
|
||||||
|
}
|
||||||
|
|
||||||
func (ds *Zabbix) GetAllApps(ctx context.Context, hostids []string) ([]Application, error) {
|
func (ds *Zabbix) GetAllApps(ctx context.Context, hostids []string) ([]Application, error) {
|
||||||
params := ZabbixAPIParams{
|
params := ZabbixAPIParams{
|
||||||
"output": "extend",
|
"output": "extend",
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ export const DATAPOINT_VALUE = 0;
|
|||||||
export const DATAPOINT_TS = 1;
|
export const DATAPOINT_TS = 1;
|
||||||
|
|
||||||
// Editor modes
|
// Editor modes
|
||||||
export const MODE_METRICS = 0;
|
export const MODE_METRICS = '0';
|
||||||
export const MODE_ITSERVICE = 1;
|
export const MODE_ITSERVICE = '1';
|
||||||
export const MODE_TEXT = 2;
|
export const MODE_TEXT = '2';
|
||||||
export const MODE_ITEMID = 3;
|
export const MODE_ITEMID = '3';
|
||||||
export const MODE_TRIGGERS = 4;
|
export const MODE_TRIGGERS = '4';
|
||||||
export const MODE_PROBLEMS = 5;
|
export const MODE_PROBLEMS = '5';
|
||||||
|
|
||||||
// Triggers severity
|
// Triggers severity
|
||||||
export const SEV_NOT_CLASSIFIED = 0;
|
export const SEV_NOT_CLASSIFIED = 0;
|
||||||
|
|||||||
@@ -100,15 +100,21 @@ export class ZabbixDatasource extends DataSourceApi<ZabbixMetricsQuery, ZabbixDS
|
|||||||
* @return {Object} Grafana metrics object with timeseries data for each target.
|
* @return {Object} Grafana metrics object with timeseries data for each target.
|
||||||
*/
|
*/
|
||||||
query(request: DataQueryRequest<any>): Promise<DataQueryResponse> | Observable<DataQueryResponse> {
|
query(request: DataQueryRequest<any>): Promise<DataQueryResponse> | Observable<DataQueryResponse> {
|
||||||
const isMetricQuery = request.targets.every(q => q.queryType === c.MODE_METRICS || q.mode === c.MODE_METRICS);
|
// Migrate old targets
|
||||||
if (isMetricQuery) {
|
request.targets = request.targets.map(t => {
|
||||||
|
// Prevent changes of original object
|
||||||
|
const target = _.cloneDeep(t);
|
||||||
|
return migrations.migrate(target);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isBackendQuery(request)) {
|
||||||
return this.backendQuery(request);
|
return this.backendQuery(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create request for each target
|
// Create request for each target
|
||||||
const promises = _.map(request.targets, t => {
|
const promises = _.map(request.targets, target => {
|
||||||
// Don't request for hidden targets
|
// Don't request for hidden targets
|
||||||
if (t.hide) {
|
if (target.hide) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,11 +124,6 @@ export class ZabbixDatasource extends DataSourceApi<ZabbixMetricsQuery, ZabbixDS
|
|||||||
// Add range variables
|
// Add range variables
|
||||||
request.scopedVars = Object.assign({}, request.scopedVars, utils.getRangeScopedVars(request.range));
|
request.scopedVars = Object.assign({}, request.scopedVars, utils.getRangeScopedVars(request.range));
|
||||||
|
|
||||||
// Prevent changes of original object
|
|
||||||
let target = _.cloneDeep(t);
|
|
||||||
|
|
||||||
// Migrate old targets
|
|
||||||
target = migrations.migrate(target);
|
|
||||||
this.replaceTargetVariables(target, request);
|
this.replaceTargetVariables(target, request);
|
||||||
|
|
||||||
// Apply Time-related functions (timeShift(), etc)
|
// Apply Time-related functions (timeShift(), etc)
|
||||||
@@ -213,10 +214,6 @@ export class ZabbixDatasource extends DataSourceApi<ZabbixMetricsQuery, ZabbixDS
|
|||||||
target = migrations.migrate(target);
|
target = migrations.migrate(target);
|
||||||
this.replaceTargetVariables(target, request);
|
this.replaceTargetVariables(target, request);
|
||||||
|
|
||||||
if (target.queryType !== c.MODE_METRICS) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...target,
|
...target,
|
||||||
datasourceId,
|
datasourceId,
|
||||||
@@ -839,6 +836,10 @@ export class ZabbixDatasource extends DataSourceApi<ZabbixMetricsQuery, ZabbixDS
|
|||||||
target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars);
|
target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target.itemids) {
|
||||||
|
target.itemids = this.templateSrv.replace(target.itemids, options.scopedVars, zabbixItemIdsTemplateFormat);
|
||||||
|
}
|
||||||
|
|
||||||
_.forEach(target.functions, func => {
|
_.forEach(target.functions, func => {
|
||||||
func.params = _.map(func.params, param => {
|
func.params = _.map(func.params, param => {
|
||||||
if (typeof param === 'number') {
|
if (typeof param === 'number') {
|
||||||
@@ -969,3 +970,10 @@ function getRequestTarget(request: DataQueryRequest<any>, refId: string): any {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isBackendQuery(request: DataQueryRequest<any>): boolean {
|
||||||
|
return request.targets.every(q =>
|
||||||
|
q.queryType === c.MODE_METRICS ||
|
||||||
|
q.queryType === c.MODE_ITEMID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ function migrateQueryType(target) {
|
|||||||
delete target.mode;
|
delete target.mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// queryType is a string in query model
|
||||||
|
target.queryType = (target.queryType as number).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function migrateSLA(target) {
|
function migrateSLA(target) {
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export class ZabbixQueryController extends QueryCtrl {
|
|||||||
zabbix: any;
|
zabbix: any;
|
||||||
replaceTemplateVars: any;
|
replaceTemplateVars: any;
|
||||||
templateSrv: TemplateSrv;
|
templateSrv: TemplateSrv;
|
||||||
editorModes: Array<{ value: string; text: string; queryType: number; }>;
|
editorModes: Array<{ value: string; text: string; queryType: string; }>;
|
||||||
slaPropertyList: Array<{ name: string; property: string; }>;
|
slaPropertyList: Array<{ name: string; property: string; }>;
|
||||||
slaIntervals: Array<{ text: string; value: string; }>;
|
slaIntervals: Array<{ text: string; value: string; }>;
|
||||||
ackFilters: Array<{ text: string; value: number; }>;
|
ackFilters: Array<{ text: string; value: number; }>;
|
||||||
|
|||||||
Reference in New Issue
Block a user