Files
grafana-zabbix/src/datasource-zabbix/zabbix/connectors/dbConnector.js
Alexander Zobnin 869634ef62 Fix ds provisioning with direct DB connection enabled (#723)
* fix ds provisioning with direct DB connection #711

* fix linter error
2019-04-19 12:56:51 +03:00

158 lines
4.1 KiB
JavaScript

import _ from 'lodash';
export const DEFAULT_QUERY_LIMIT = 10000;
export const HISTORY_TO_TABLE_MAP = {
'0': 'history',
'1': 'history_str',
'2': 'history_log',
'3': 'history_uint',
'4': 'history_text'
};
export const TREND_TO_TABLE_MAP = {
'0': 'trends',
'3': 'trends_uint'
};
export const consolidateByFunc = {
'avg': 'AVG',
'min': 'MIN',
'max': 'MAX',
'sum': 'SUM',
'count': 'COUNT'
};
export const consolidateByTrendColumns = {
'avg': 'value_avg',
'min': 'value_min',
'max': 'value_max',
'sum': 'num*value_avg' // sum of sums inside the one-hour trend period
};
/**
* Base class for external history database connectors. Subclasses should implement `getHistory()`, `getTrends()` and
* `testDataSource()` methods, which describe how to fetch data from source other than Zabbix API.
*/
export class DBConnector {
constructor(options, datasourceSrv) {
this.datasourceSrv = datasourceSrv;
this.datasourceId = options.datasourceId;
this.datasourceName = options.datasourceName;
this.datasourceTypeId = null;
this.datasourceTypeName = null;
}
static loadDatasource(dsId, dsName, datasourceSrv) {
if (!dsName && dsId !== undefined) {
let ds = _.find(datasourceSrv.getAll(), {'id': dsId});
if (!ds) {
return Promise.reject(`Data Source with ID ${dsId} not found`);
}
dsName = ds.name;
}
if (dsName) {
return datasourceSrv.loadDatasource(dsName);
} else {
return Promise.reject(`Data Source name should be specified`);
}
}
loadDBDataSource() {
return DBConnector.loadDatasource(this.datasourceId, this.datasourceName, this.datasourceSrv)
.then(ds => {
this.datasourceTypeId = ds.meta.id;
this.datasourceTypeName = ds.meta.name;
if (!this.datasourceName) {
this.datasourceName = ds.name;
}
if (!this.datasourceId) {
this.datasourceId = ds.id;
}
return ds;
});
}
/**
* Send test request to datasource in order to ensure it's working.
*/
testDataSource() {
throw new ZabbixNotImplemented('testDataSource()');
}
/**
* Get history data from external sources.
*/
getHistory() {
throw new ZabbixNotImplemented('getHistory()');
}
/**
* Get trends data from external sources.
*/
getTrends() {
throw new ZabbixNotImplemented('getTrends()');
}
handleGrafanaTSResponse(history, items, addHostName = true) {
return convertGrafanaTSResponse(history, items, addHostName);
}
}
// Define Zabbix DB Connector exception type for non-implemented methods
export class ZabbixNotImplemented {
constructor(methodName) {
this.code = null;
this.name = 'ZabbixNotImplemented';
this.message = `Zabbix DB Connector Error: method ${methodName || ''} should be implemented in subclass of DBConnector`;
}
toString() {
return this.message;
}
}
/**
* Converts time series returned by the data source into format that Grafana expects
* time_series is Array of series:
* ```
* [{
* name: string,
* points: Array<[value: number, timestamp: number]>
* }]
* ```
*/
function convertGrafanaTSResponse(time_series, items, addHostName) {
//uniqBy is needed to deduplicate
var hosts = _.uniqBy(_.flatten(_.map(items, 'hosts')), 'hostid');
let grafanaSeries = _.map(_.compact(time_series), series => {
let itemid = series.name;
var item = _.find(items, {'itemid': itemid});
var alias = item.name;
//only when actual multi hosts selected
if (_.keys(hosts).length > 1 && addHostName) {
var host = _.find(hosts, {'hostid': item.hostid});
alias = host.name + ": " + alias;
}
// CachingProxy deduplicates requests and returns one time series for equal queries.
// Clone is needed to prevent changing of series object shared between all targets.
let datapoints = _.cloneDeep(series.points);
return {
target: alias,
datapoints: datapoints
};
});
return _.sortBy(grafanaSeries, 'target');
}
const defaults = {
DBConnector,
DEFAULT_QUERY_LIMIT,
HISTORY_TO_TABLE_MAP,
TREND_TO_TABLE_MAP,
consolidateByFunc,
consolidateByTrendColumns
};
export default defaults;