diff --git a/pkg/plugins/dashboard_importer.go b/pkg/plugins/dashboard_importer.go
index b5dc286f6d1..834bfabd048 100644
--- a/pkg/plugins/dashboard_importer.go
+++ b/pkg/plugins/dashboard_importer.go
@@ -7,7 +7,6 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
- "github.com/grafana/grafana/pkg/log"
m "github.com/grafana/grafana/pkg/models"
)
@@ -95,11 +94,10 @@ type DashTemplateEvaluator struct {
varRegex *regexp.Regexp
}
-func (this *DashTemplateEvaluator) findInput(varName string, varDef *simplejson.Json) *ImportDashboardInput {
- inputType := varDef.Get("type").MustString()
+func (this *DashTemplateEvaluator) findInput(varName string, varType string) *ImportDashboardInput {
for _, input := range this.inputs {
- if inputType == input.Type && (input.Name == varName || input.Name == "*") {
+ if varType == input.Type && (input.Name == varName || input.Name == "*") {
return &input
}
}
@@ -110,21 +108,20 @@ func (this *DashTemplateEvaluator) findInput(varName string, varDef *simplejson.
func (this *DashTemplateEvaluator) Eval() (*simplejson.Json, error) {
this.result = simplejson.New()
this.variables = make(map[string]string)
- this.varRegex, _ = regexp.Compile("\\$__(\\w+)")
+ this.varRegex, _ = regexp.Compile(`(\$\{\w+\})`)
// check that we have all inputs we need
- if inputDefs := this.template.Get("__inputs"); inputDefs != nil {
- for varName, value := range inputDefs.MustMap() {
- input := this.findInput(varName, simplejson.NewFromAny(value))
+ for _, inputDef := range this.template.Get("__inputs").MustArray() {
+ inputDefJson := simplejson.NewFromAny(inputDef)
+ inputName := inputDefJson.Get("name").MustString()
+ inputType := inputDefJson.Get("type").MustString()
+ input := this.findInput(inputName, inputType)
- if input == nil {
- return nil, &DashboardInputMissingError{VariableName: varName}
- }
-
- this.variables["$__"+varName] = input.Value
+ if input == nil {
+ return nil, &DashboardInputMissingError{VariableName: inputName}
}
- } else {
- log.Info("Import: dashboard has no __import section")
+
+ this.variables["${"+inputName+"}"] = input.Value
}
return simplejson.NewFromAny(this.evalObject(this.template)), nil
@@ -137,7 +134,11 @@ func (this *DashTemplateEvaluator) evalValue(source *simplejson.Json) interface{
switch v := sourceValue.(type) {
case string:
interpolated := this.varRegex.ReplaceAllStringFunc(v, func(match string) string {
- return this.variables[match]
+ if replacement, exists := this.variables[match]; exists {
+ return replacement
+ } else {
+ return match
+ }
})
return interpolated
case bool:
diff --git a/pkg/plugins/dashboard_importer_test.go b/pkg/plugins/dashboard_importer_test.go
index 9b5605277d4..d2897fad1cd 100644
--- a/pkg/plugins/dashboard_importer_test.go
+++ b/pkg/plugins/dashboard_importer_test.go
@@ -59,13 +59,14 @@ func TestDashboardImport(t *testing.T) {
Convey("When evaling dashboard template", t, func() {
template, _ := simplejson.NewJson([]byte(`{
- "__inputs": {
- "graphite": {
+ "__inputs": [
+ {
+ "name": "DS_NAME",
"type": "datasource"
}
- },
+ ],
"test": {
- "prop": "$__graphite"
+ "prop": "${DS_NAME}"
}
}`))
diff --git a/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json b/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json
index b9f2db18927..845fc1930bd 100644
--- a/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json
+++ b/public/app/plugins/datasource/graphite/dashboards/carbon_metrics.json
@@ -1,11 +1,11 @@
{
- "__inputs": {
- "graphite": {
+ "__inputs": [
+ {
+ "name": "DS_NAME",
"type": "datasource",
- "pluginId": "graphite",
- "description": "Graphite datasource"
+ "pluginId": "graphite"
}
- },
+ ],
"revision": "1.0",
"title": "Graphite Carbon Metrics",
@@ -29,7 +29,7 @@
"enable": false
},
"bars": false,
- "datasource": "$__graphite",
+ "datasource": "${DS_NAME}",
"editable": true,
"fill": 0,
"grid": {
diff --git a/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json b/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json
new file mode 100644
index 00000000000..e008317a96e
--- /dev/null
+++ b/public/app/plugins/datasource/prometheus/dashboards/prometheus_stats.json
@@ -0,0 +1,577 @@
+{
+ "__inputs": [
+ {
+ "name": "DS_NAME",
+ "type": "datasource",
+ "pluginId": "prometheus"
+ }
+ ],
+
+ "revision": "1.0",
+ "title": "Prometheus Stats",
+ "tags": ["prometheus"],
+ "style": "dark",
+ "timezone": "browser",
+ "editable": true,
+ "hideControls": true,
+ "sharedCrosshair": false,
+ "rows": [
+ {
+ "collapse": false,
+ "editable": true,
+ "height": 178,
+ "panels": [
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(245, 54, 54, 0.9)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(50, 172, 45, 0.97)"
+ ],
+ "datasource": "${DS_NAME}",
+ "decimals": 1,
+ "editable": true,
+ "error": false,
+ "format": "s",
+ "id": 5,
+ "interval": null,
+ "links": [],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "span": 3,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "targets": [
+ {
+ "expr": "(time() - process_start_time_seconds{job=\"prometheus\"})",
+ "intervalFactor": 2,
+ "refId": "A"
+ }
+ ],
+ "thresholds": "",
+ "title": "Uptime",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_NAME}",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "id": 6,
+ "interval": null,
+ "links": [],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "span": 3,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": true
+ },
+ "targets": [
+ {
+ "expr": "prometheus_local_storage_memory_series",
+ "intervalFactor": 2,
+ "refId": "A"
+ }
+ ],
+ "thresholds": "0,1,5",
+ "title": "Local Storage Memory Series",
+ "type": "singlestat",
+ "valueFontSize": "70%",
+ "valueMaps": [],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_NAME}",
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "id": 7,
+ "interval": null,
+ "links": [],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "span": 3,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": true
+ },
+ "targets": [
+ {
+ "expr": "prometheus_local_storage_indexing_queue_length",
+ "intervalFactor": 2,
+ "refId": "A"
+ }
+ ],
+ "thresholds": "0,500,4000",
+ "title": "Interal Storage Queue Length",
+ "type": "singlestat",
+ "valueFontSize": "70%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "Empty",
+ "value": "0"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "content": "\nPrometheus\n\n
You're using Prometheus, an open-source systems monitoring and alerting toolkit originally built at SoundCloud. For more information, check out the Grafana and Prometheus projects.
", + "editable": true, + "error": false, + "id": 9, + "links": [], + "mode": "html", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": 227, + "panels": [ + { + "aliasColors": { + "prometheus": "#C15C17", + "{instance=\"localhost:9090\",job=\"prometheus\"}": "#C15C17" + }, + "bars": false, + "datasource": "${DS_NAME}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 9, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_local_storage_ingested_samples_total[5m])", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{job}}", + "metric": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Samples ingested (rate-5m)", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + }, + { + "content": "#### Samples Ingested\nThis graph displays the count of samples ingested by the Prometheus server, as measured over the last 5 minutes, per time series in the range vector. When troubleshooting an issue on IRC or Github, this is often the first stat requested by the Prometheus team. ", + "editable": true, + "error": false, + "id": 8, + "links": [], + "mode": "markdown", + "span": 2.995914043583536, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": { + "prometheus": "#F9BA8F", + "{instance=\"localhost:9090\",interval=\"5s\",job=\"prometheus\"}": "#F9BA8F" + }, + "bars": false, + "datasource": "${DS_NAME}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 5, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "rate(prometheus_target_interval_length_seconds_count[5m])", + "intervalFactor": 2, + "legendFormat": "{{job}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Target Scrapes (last 5m)", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + }, + { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_NAME}", + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 4, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_target_interval_length_seconds{quantile!=\"0.01\", quantile!=\"0.05\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{quantile}} ({{interval}})", + "metric": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Scrape Duration", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "short", + "short" + ] + }, + { + "content": "#### Scrapes\nPrometheus scrapes metrics from instrumented jobs, either directly or via an intermediary push gateway for short-lived jobs. Target scrapes will show how frequently targets are scraped, as measured over the last 5 minutes, per time series in the range vector. Scrape Duration will show how long the scrapes are taking, with percentiles available as series. ", + "editable": true, + "error": false, + "id": 11, + "links": [], + "mode": "markdown", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + } + ], + "title": "New row" + }, + { + "collapse": false, + "editable": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "datasource": "${DS_NAME}", + "decimals": null, + "editable": true, + "error": false, + "fill": 1, + "grid": { + "leftLogBase": 1, + "leftMax": null, + "leftMin": null, + "rightLogBase": 1, + "rightMax": null, + "rightMin": null, + "threshold1": null, + "threshold1Color": "rgba(216, 200, 27, 0.27)", + "threshold2": null, + "threshold2Color": "rgba(234, 112, 112, 0.22)" + }, + "id": 12, + "leftYAxisLabel": "", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "span": 9, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "prometheus_evaluator_duration_milliseconds{quantile!=\"0.01\", quantile!=\"0.05\"}", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{quantile}}", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Rule Eval Duration", + "tooltip": { + "shared": true, + "value_type": "cumulative" + }, + "type": "graph", + "x-axis": true, + "y-axis": true, + "y_formats": [ + "percentunit", + "short" + ] + }, + { + "content": "#### Rule Evaluation Duration\nThis graph panel plots the duration for all evaluations to execute. The 50th percentile, 90th percentile and 99th percentile are shown as three separate series to help identify outliers that may be skewing the data.", + "editable": true, + "error": false, + "id": 15, + "links": [], + "mode": "markdown", + "span": 3, + "style": {}, + "title": "", + "transparent": true, + "type": "text" + } + ], + "title": "New row" + } + ], + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "templating": { + "list": [] + }, + "annotations": { + "list": [] + }, + "refresh": false, + "schemaVersion": 7, + "links": [ + { + "icon": "info", + "tags": [], + "targetBlank": true, + "title": "Grafana Docs", + "tooltip": "", + "type": "link", + "url": "http://www.grafana.org/docs" + }, + { + "icon": "info", + "tags": [], + "targetBlank": true, + "title": "Prometheus Docs", + "type": "link", + "url": "http://prometheus.io/docs/introduction/overview/" + } + ] +} diff --git a/public/app/plugins/datasource/prometheus/plugin.json b/public/app/plugins/datasource/prometheus/plugin.json index 66dd9145e6a..2ff198d5129 100644 --- a/public/app/plugins/datasource/prometheus/plugin.json +++ b/public/app/plugins/datasource/prometheus/plugin.json @@ -3,6 +3,10 @@ "name": "Prometheus", "id": "prometheus", + "includes": [ + {"type": "dashboard", "name": "Prometheus Stats", "path": "dashboards/prometheus_stats.json"} + ], + "metrics": true, "annotations": true } diff --git a/tests/test-app/dashboards/connections.json b/tests/test-app/dashboards/connections.json index 2f5102fba3e..ee5e40140b3 100644 --- a/tests/test-app/dashboards/connections.json +++ b/tests/test-app/dashboards/connections.json @@ -1,11 +1,11 @@ { - "__inputs": { - "graphite": { + "__inputs": [ + { + "name": "DS_NAME", "type": "datasource", - "pluginId": "graphite", - "description": "Graphite datasource" + "pluginId": "graphite" } - }, + ], "title": "Nginx Connections", "revision": "1.5", @@ -20,7 +20,7 @@ "panels": [ { "type": "graph", - "datasource": "$__graphite" + "datasource": "${DS_NAME}" } ] }