Merge branch 'develop-1.9' into develop

Conflicts:
	.gitignore
	zabbix/datasource.js
	zabbix/partials/query.editor.html
	zabbix/queryCtrl.js
This commit is contained in:
Alexander Zobnin
2015-05-16 18:29:54 +03:00
3 changed files with 79 additions and 24 deletions

View File

@@ -1,2 +1,43 @@
# grafana-zabbix
Zabbix API datasource for Grafana dashboard
![alt tag](https://cloud.githubusercontent.com/assets/4932851/7454206/34bf9f8c-f27a-11e4-8e96-a73829f188c4.png)
Query editor allows to add metric by step-by-step selection from host group, host, application dropdown menus.
![alt tag](https://cloud.githubusercontent.com/assets/4932851/7441162/4f6af788-f0e4-11e4-887b-34d987d00c40.png)
![alt tag](https://cloud.githubusercontent.com/assets/4932851/7441163/56f28f16-f0e4-11e4-9d46-54181c2a2e7e.png)
![alt tag](https://cloud.githubusercontent.com/assets/4932851/7441167/5f29cc94-f0e4-11e4-8d39-7580f33201f6.png)
## Installation
### Grafana 1.9.x
Download latest release and unpack into `<your grafana installation>/plugins/datasource/`. Then edit Grafana config.js:
* Add dependencies
```
plugins: {
panels: [],
dependencies: ['datasource/zabbix/datasource', 'datasource/zabbix/queryCtrl'],
}
```
* Add datasource and setup your Zabbix API url, username and password
```
datasources: {
...
},
zabbix: {
type: 'ZabbixAPIDatasource',
url: 'http://www.zabbix.org/zabbix/api_jsonrpc.php',
username: 'guest',
password: ''
}
},
```
### Grafana 2.0.x
Now in development.

View File

@@ -39,14 +39,14 @@ function (angular, _, kbn) {
// Need for find target alias
var targets = options.targets;
// TODO: remove undefined targets from request
// Check that all targets defined
var targetsDefined = options.targets.every(function (target, index, array) {
return target.item;
// Remove undefined and hidden targets
var displayedTargets = _.filter(targets, function (target) {
return (!target.hide && target.item);
});
if (targetsDefined) {
if (displayedTargets.length) {
// Extract zabbix api item objects from targets
var target_items = _.map(options.targets, 'item');
var target_items = _.map(displayedTargets, 'item');
} else {
// No valid targets, return the empty dataset
var d = $q.defer();
@@ -75,13 +75,15 @@ function (angular, _, kbn) {
// Index returned datapoints by item/metric id
var indexed_result = _.groupBy(response, 'itemid');
// TODO: realize correct timeseries reduce
/*
// Reduce timeseries to the same size for stacking and tooltip work properly
var min_length = _.min(_.map(indexed_result, function (history) {
return history.length;
}));
_.each(indexed_result, function (item) {
item.splice(0, item.length - min_length);
});
});*/
// Sort result as the same as targets for display
// stacked timeseries in proper order
@@ -120,7 +122,7 @@ function (angular, _, kbn) {
// Request data from Zabbix API
ZabbixAPIDatasource.prototype.doZabbixAPIRequest = function(request_data) {
ZabbixAPIDatasource.prototype.performZabbixAPIRequest = function(request_data) {
var options = {
method: 'POST',
headers: {
@@ -180,7 +182,7 @@ function (angular, _, kbn) {
itemids: item_ids,
sortfield: 'clock',
sortorder: 'ASC',
limit: self.limitMetrics,
limit: self.limitmetrics,
time_from: start,
},
auth: self.auth,
@@ -192,7 +194,7 @@ function (angular, _, kbn) {
data.params.time_till = end;
}
apiRequests.push(self.doZabbixAPIRequest(data));
apiRequests.push(self.performZabbixAPIRequest(data));
});
return this.handleMultipleRequest(apiRequests);
@@ -265,7 +267,7 @@ function (angular, _, kbn) {
id: 1
};
return this.doZabbixAPIRequest(data);
return this.performZabbixAPIRequest(data);
};
@@ -285,7 +287,7 @@ function (angular, _, kbn) {
data.params.groupids = groupid;
}
return this.doZabbixAPIRequest(data);
return this.performZabbixAPIRequest(data);
};
@@ -303,7 +305,7 @@ function (angular, _, kbn) {
id: 1
};
return this.doZabbixAPIRequest(data);
return this.performZabbixAPIRequest(data);
};
@@ -329,7 +331,7 @@ function (angular, _, kbn) {
data.params.applicationids = applicationid;
}
return this.doZabbixAPIRequest(data);
return this.performZabbixAPIRequest(data);
};
@@ -349,7 +351,7 @@ function (angular, _, kbn) {
params: {
output: ['triggerid', 'description'],
itemids: annotation.aids.split(','), // TODO: validate / pull automatically from dashboard.
limit: self.limitMetrics,
limit: self.limitmetrics,
},
auth: self.auth,
id: 1
@@ -372,7 +374,7 @@ function (angular, _, kbn) {
time_from: from,
time_till: to,
objectids: _.keys(obs),
limit: self.limitMetrics,
limit: self.limitmetrics,
},
auth: self.auth,
id: 1

View File

@@ -35,10 +35,20 @@ function (angular, _) {
}
}
setItemAlias();
$scope.target.errors = validateTarget($scope.target);
};
// Take alias from item name by default
function setItemAlias() {
if (!$scope.target.alias && $scope.target.item) {
$scope.target.alias = $scope.target.item.expandedName;
}
};
$scope.targetBlur = function() {
setItemAlias();
$scope.target.errors = validateTarget($scope.target);
if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
$scope.oldTarget = angular.copy($scope.target);
@@ -65,7 +75,7 @@ function (angular, _) {
// Call when host selected
$scope.selectHost = function() {
if ($scope.target.host) {
// Update item list
if ($scope.target.application) {
$scope.updateItemList($scope.target.host.hostid, $scope.target.application.applicationid);
@@ -75,6 +85,7 @@ function (angular, _) {
// Update application list
$scope.updateAppList($scope.target.host.hostid);
}
$scope.target.errors = validateTarget($scope.target);
if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
@@ -104,6 +115,7 @@ function (angular, _) {
// Call when item selected
$scope.selectItem = function() {
setItemAlias();
$scope.target.errors = validateTarget($scope.target);
if (!_.isEqual($scope.oldTarget, $scope.target) && _.isEmpty($scope.target.errors)) {
$scope.oldTarget = angular.copy($scope.target);