mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'master' into export-dashboard
This commit is contained in:
commit
53bb264375
16
docker/blocks/collectd/Dockerfile
Normal file
16
docker/blocks/collectd/Dockerfile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
FROM ubuntu:xenial
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
RUN apt-get -y update
|
||||||
|
RUN apt-get -y install collectd curl python-pip
|
||||||
|
|
||||||
|
# add a fake mtab for host disk stats
|
||||||
|
ADD etc_mtab /etc/mtab
|
||||||
|
|
||||||
|
ADD collectd.conf.tpl /etc/collectd/collectd.conf.tpl
|
||||||
|
|
||||||
|
RUN pip install envtpl
|
||||||
|
ADD start_container /usr/bin/start_container
|
||||||
|
RUN chmod +x /usr/bin/start_container
|
||||||
|
CMD start_container
|
37
docker/blocks/collectd/README.md
Normal file
37
docker/blocks/collectd/README.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
collectd-write-graphite
|
||||||
|
=======================
|
||||||
|
|
||||||
|
Basic collectd-based server monitoring. Sends stats to Graphite.
|
||||||
|
|
||||||
|
Collectd metrics:
|
||||||
|
|
||||||
|
* CPU used/free/idle/etc
|
||||||
|
* Free disk (via mounting hosts '/' into container, eg: -v /:/hostfs:ro)
|
||||||
|
* Disk performance
|
||||||
|
* Load average
|
||||||
|
* Memory used/free/etc
|
||||||
|
* Uptime
|
||||||
|
* Network interface
|
||||||
|
* Swap
|
||||||
|
|
||||||
|
Environment variables
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
* `HOST_NAME`
|
||||||
|
- Will be sent to Graphite
|
||||||
|
- Required
|
||||||
|
* `GRAPHITE_HOST`
|
||||||
|
- Graphite IP or hostname
|
||||||
|
- Required
|
||||||
|
* `GRAPHITE_PORT`
|
||||||
|
- Graphite port
|
||||||
|
- Optional, defaults to 2003
|
||||||
|
* `GRAPHITE_PREFIX`
|
||||||
|
- Graphite prefix
|
||||||
|
- Optional, defaults to collectd.
|
||||||
|
* `REPORT_BY_CPU`
|
||||||
|
- Report per-CPU metrics if true, global sum of CPU metrics if false (details: [collectd.conf man page](https://collectd.org/documentation/manpages/collectd.conf.5.shtml#plugin_cpu))
|
||||||
|
- Optional, defaults to false.
|
||||||
|
* `COLLECT_INTERVAL`
|
||||||
|
- Collection interval and thus resolution of metrics
|
||||||
|
- Optional, defaults to 10
|
76
docker/blocks/collectd/collectd.conf.tpl
Normal file
76
docker/blocks/collectd/collectd.conf.tpl
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
Hostname "{{ HOST_NAME }}"
|
||||||
|
|
||||||
|
FQDNLookup false
|
||||||
|
Interval {{ COLLECT_INTERVAL | default("10") }}
|
||||||
|
Timeout 2
|
||||||
|
ReadThreads 5
|
||||||
|
|
||||||
|
LoadPlugin cpu
|
||||||
|
LoadPlugin df
|
||||||
|
LoadPlugin load
|
||||||
|
LoadPlugin memory
|
||||||
|
LoadPlugin disk
|
||||||
|
LoadPlugin interface
|
||||||
|
LoadPlugin uptime
|
||||||
|
LoadPlugin swap
|
||||||
|
LoadPlugin write_graphite
|
||||||
|
|
||||||
|
<Plugin cpu>
|
||||||
|
ReportByCpu {{ REPORT_BY_CPU | default("false") }}
|
||||||
|
</Plugin>
|
||||||
|
|
||||||
|
<Plugin df>
|
||||||
|
# expose host's mounts into container using -v /:/host:ro (location inside container does not matter much)
|
||||||
|
# ignore rootfs; else, the root file-system would appear twice, causing
|
||||||
|
# one of the updates to fail and spam the log
|
||||||
|
FSType rootfs
|
||||||
|
# ignore the usual virtual / temporary file-systems
|
||||||
|
FSType sysfs
|
||||||
|
FSType proc
|
||||||
|
FSType devtmpfs
|
||||||
|
FSType devpts
|
||||||
|
FSType tmpfs
|
||||||
|
FSType fusectl
|
||||||
|
FSType cgroup
|
||||||
|
FSType overlay
|
||||||
|
FSType debugfs
|
||||||
|
FSType pstore
|
||||||
|
FSType securityfs
|
||||||
|
FSType hugetlbfs
|
||||||
|
FSType squashfs
|
||||||
|
FSType mqueue
|
||||||
|
MountPoint "/etc/resolv.conf"
|
||||||
|
MountPoint "/etc/hostname"
|
||||||
|
MountPoint "/etc/hosts"
|
||||||
|
IgnoreSelected true
|
||||||
|
ReportByDevice false
|
||||||
|
ReportReserved true
|
||||||
|
ReportInodes true
|
||||||
|
</Plugin>
|
||||||
|
|
||||||
|
<Plugin "disk">
|
||||||
|
Disk "/^[hs]d[a-z]/"
|
||||||
|
IgnoreSelected false
|
||||||
|
</Plugin>
|
||||||
|
|
||||||
|
|
||||||
|
<Plugin interface>
|
||||||
|
Interface "lo"
|
||||||
|
Interface "/^veth.*/"
|
||||||
|
Interface "/^docker.*/"
|
||||||
|
IgnoreSelected true
|
||||||
|
</Plugin>
|
||||||
|
|
||||||
|
|
||||||
|
<Plugin "write_graphite">
|
||||||
|
<Carbon>
|
||||||
|
Host "{{ GRAPHITE_HOST }}"
|
||||||
|
Port "{{ GRAPHITE_PORT | default("2003") }}"
|
||||||
|
Prefix "{{ GRAPHITE_PREFIX | default("collectd.") }}"
|
||||||
|
EscapeCharacter "_"
|
||||||
|
SeparateInstances true
|
||||||
|
StoreRates true
|
||||||
|
AlwaysAppendDS false
|
||||||
|
</Carbon>
|
||||||
|
</Plugin>
|
||||||
|
|
1
docker/blocks/collectd/etc_mtab
Normal file
1
docker/blocks/collectd/etc_mtab
Normal file
@ -0,0 +1 @@
|
|||||||
|
hostfs /.dockerinit ext4 ro,relatime,user_xattr,barrier=1,data=ordered 0 0
|
11
docker/blocks/collectd/fig
Normal file
11
docker/blocks/collectd/fig
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
collectd:
|
||||||
|
build: blocks/collectd
|
||||||
|
environment:
|
||||||
|
HOST_NAME: myserver
|
||||||
|
GRAPHITE_HOST: graphite
|
||||||
|
GRAPHITE_PORT: 2003
|
||||||
|
GRAPHITE_PREFIX: collectd.
|
||||||
|
REPORT_BY_CPU: 'false'
|
||||||
|
COLLECT_INTERVAL: 10
|
||||||
|
links:
|
||||||
|
- graphite
|
5
docker/blocks/collectd/start_container
Normal file
5
docker/blocks/collectd/start_container
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
envtpl /etc/collectd/collectd.conf.tpl
|
||||||
|
|
||||||
|
collectd -f
|
@ -244,7 +244,7 @@ function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q, $http, $
|
|||||||
registerPluginComponent(scope, elem, attrs, componentInfo);
|
registerPluginComponent(scope, elem, attrs, componentInfo);
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
$rootScope.appEvent('alert-error', ['Plugin Error', err.message || err]);
|
$rootScope.appEvent('alert-error', ['Plugin Error', err.message || err]);
|
||||||
console.log('Plugin componnet error', err);
|
console.log('Plugin component error', err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -12,9 +12,21 @@ function($, _) {
|
|||||||
|
|
||||||
kbn.round_interval = function(interval) {
|
kbn.round_interval = function(interval) {
|
||||||
switch (true) {
|
switch (true) {
|
||||||
// 0.3s
|
// 0.015s
|
||||||
case (interval <= 300):
|
case (interval <= 15):
|
||||||
return 100; // 0.1s
|
return 10; // 0.01s
|
||||||
|
// 0.035s
|
||||||
|
case (interval <= 35):
|
||||||
|
return 20; // 0.02s
|
||||||
|
// 0.075s
|
||||||
|
case (interval <= 75):
|
||||||
|
return 50; // 0.05s
|
||||||
|
// 0.15s
|
||||||
|
case (interval <= 150):
|
||||||
|
return 100; // 0.1s
|
||||||
|
// 0.35s
|
||||||
|
case (interval <= 350):
|
||||||
|
return 200; // 0.2s
|
||||||
// 0.75s
|
// 0.75s
|
||||||
case (interval <= 750):
|
case (interval <= 750):
|
||||||
return 500; // 0.5s
|
return 500; // 0.5s
|
||||||
@ -133,7 +145,7 @@ function($, _) {
|
|||||||
return str;
|
return str;
|
||||||
};
|
};
|
||||||
|
|
||||||
kbn.interval_regex = /(\d+(?:\.\d+)?)([Mwdhmsy])/;
|
kbn.interval_regex = /(\d+(?:\.\d+)?)(ms|[Mwdhmsy])/;
|
||||||
|
|
||||||
// histogram & trends
|
// histogram & trends
|
||||||
kbn.intervals_in_seconds = {
|
kbn.intervals_in_seconds = {
|
||||||
@ -143,7 +155,8 @@ function($, _) {
|
|||||||
d: 86400,
|
d: 86400,
|
||||||
h: 3600,
|
h: 3600,
|
||||||
m: 60,
|
m: 60,
|
||||||
s: 1
|
s: 1,
|
||||||
|
ms: 0.001
|
||||||
};
|
};
|
||||||
|
|
||||||
kbn.calculateInterval = function(range, resolution, userInterval) {
|
kbn.calculateInterval = function(range, resolution, userInterval) {
|
||||||
|
@ -25,6 +25,7 @@ function (angular, _) {
|
|||||||
{value: "interval", text: "Interval"},
|
{value: "interval", text: "Interval"},
|
||||||
{value: "datasource", text: "Data source"},
|
{value: "datasource", text: "Data source"},
|
||||||
{value: "custom", text: "Custom"},
|
{value: "custom", text: "Custom"},
|
||||||
|
{value: "constant", text: "Constant"},
|
||||||
];
|
];
|
||||||
|
|
||||||
$scope.refreshOptions = [
|
$scope.refreshOptions = [
|
||||||
@ -141,15 +142,34 @@ function (angular, _) {
|
|||||||
$scope.current = angular.copy(replacementDefaults);
|
$scope.current = angular.copy(replacementDefaults);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.showSelectionOptions = function() {
|
||||||
|
if ($scope.current) {
|
||||||
|
if ($scope.current.type === 'query') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($scope.current.type === 'custom') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
$scope.typeChanged = function () {
|
$scope.typeChanged = function () {
|
||||||
if ($scope.current.type === 'interval') {
|
if ($scope.current.type === 'interval') {
|
||||||
$scope.current.query = '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d';
|
$scope.current.query = '1m,10m,30m,1h,6h,12h,1d,7d,14d,30d';
|
||||||
|
$scope.current.refresh = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($scope.current.type === 'query') {
|
if ($scope.current.type === 'query') {
|
||||||
$scope.current.query = '';
|
$scope.current.query = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($scope.current.type === 'constant') {
|
||||||
|
$scope.current.query = '';
|
||||||
|
$scope.current.refresh = 0;
|
||||||
|
$scope.current.hide = 2;
|
||||||
|
}
|
||||||
|
|
||||||
if ($scope.current.type === 'datasource') {
|
if ($scope.current.type === 'datasource') {
|
||||||
$scope.current.query = $scope.datasourceTypes[0].value;
|
$scope.current.query = $scope.datasourceTypes[0].value;
|
||||||
$scope.current.regex = '';
|
$scope.current.regex = '';
|
||||||
|
@ -152,6 +152,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div ng-show="current.type === 'constant'" class="gf-form-group">
|
||||||
|
<h5 class="section-heading">Constant options</h5>
|
||||||
|
<div class="gf-form">
|
||||||
|
<span class="gf-form-label">Value</span>
|
||||||
|
<input type="text" class="gf-form-input" ng-model='current.query' ng-blur="runQuery()" placeholder="your metric prefix"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div ng-show="current.type === 'query'" class="gf-form-group">
|
<div ng-show="current.type === 'query'" class="gf-form-group">
|
||||||
<h5 class="section-heading">Query Options</h5>
|
<h5 class="section-heading">Query Options</h5>
|
||||||
|
|
||||||
@ -214,7 +222,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section gf-form-group" ng-hide="current.type === 'datasource'">
|
<div class="section gf-form-group" ng-show="showSelectionOptions()">
|
||||||
<h5 class="section-heading">Selection Options</h5>
|
<h5 class="section-heading">Selection Options</h5>
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<gf-form-switch class="gf-form"
|
<gf-form-switch class="gf-form"
|
||||||
|
@ -168,6 +168,11 @@ function (angular, _, kbn) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (variable.type === 'constant') {
|
||||||
|
variable.options = [{text: variable.query, value: variable.query}];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// extract options in comma seperated string
|
// extract options in comma seperated string
|
||||||
variable.options = _.map(variable.query.split(/[,]+/), function(text) {
|
variable.options = _.map(variable.query.split(/[,]+/), function(text) {
|
||||||
return { text: text.trim(), value: text.trim() };
|
return { text: text.trim(), value: text.trim() };
|
||||||
@ -175,6 +180,7 @@ function (angular, _, kbn) {
|
|||||||
|
|
||||||
if (variable.type === 'interval') {
|
if (variable.type === 'interval') {
|
||||||
self.updateAutoInterval(variable);
|
self.updateAutoInterval(variable);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variable.type === 'custom' && variable.includeAll) {
|
if (variable.type === 'custom' && variable.includeAll) {
|
||||||
@ -273,7 +279,7 @@ function (angular, _, kbn) {
|
|||||||
if (currentOption) {
|
if (currentOption) {
|
||||||
return self.setVariableValue(variable, currentOption, false);
|
return self.setVariableValue(variable, currentOption, false);
|
||||||
} else {
|
} else {
|
||||||
if (!variable.options.length) { return; }
|
if (!variable.options.length) { return $q.when(null); }
|
||||||
return self.setVariableValue(variable, variable.options[0]);
|
return self.setVariableValue(variable, variable.options[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,5 +147,11 @@ define([
|
|||||||
var str = kbn.calculateInterval(range, 1000, '>10s');
|
var str = kbn.calculateInterval(range, 1000, '>10s');
|
||||||
expect(str).to.be('20m');
|
expect(str).to.be('20m');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('10s 900 resolution and user low limit in ms', function() {
|
||||||
|
var range = { from: dateMath.parse('now-10s'), to: dateMath.parse('now') };
|
||||||
|
var str = kbn.calculateInterval(range, 900, '>15ms');
|
||||||
|
expect(str).to.be('15ms');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user