diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000000..3a0f40dcf59 --- /dev/null +++ b/.babelrc @@ -0,0 +1,11 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "targets": { "browsers": "last 3 versions" }, + "useBuiltIns": "entry" + } + ] + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 181ba0719cf..69b78a30f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,40 @@ # 5.5.0 (unreleased) +### New Features +* **Alerting**: Adds support for Google Hangouts Chat notifications [#11221](https://github.com/grafana/grafana/issues/11221), thx [@PatrickSchuster](https://github.com/PatrickSchuster) + ### Minor * **Elasticsearch**: Add support for offset in date histogram aggregation [#12653](https://github.com/grafana/grafana/issues/12653), thx [@mattiarossi](https://github.com/mattiarossi) +* **Elasticsearch**: Add support for moving average and derivative using doc count (metric count) [#8843](https://github.com/grafana/grafana/issues/8843) [#11175](https://github.com/grafana/grafana/issues/11175) * **Auth**: Prevent password reset when login form is disabled or either LDAP or Auth Proxy is enabled [#14246](https://github.com/grafana/grafana/issues/14246), thx [@SilverFire](https://github.com/SilverFire) * **Dataproxy**: Override incoming Authorization header [#13815](https://github.com/grafana/grafana/issues/13815), thx [@kornholi](https://github.com/kornholi) +* **Admin**: Fix prevent removing last grafana admin permissions [#11067](https://github.com/grafana/grafana/issues/11067), thx [@danielbh](https://github.com/danielbh) +* **Templating**: Escaping "Custom" template variables [#13754](https://github.com/grafana/grafana/issues/13754), thx [@IntegersOfK](https://github.com/IntegersOfK) + +# 5.4.2 (2018-12-13) + +* **Datasource admin**: Fix for issue creating new data source when same name exists [#14467](https://github.com/grafana/grafana/issues/14467) +* **OAuth**: Fix for oauth auto login setting, can now be set using env variable [#14435](https://github.com/grafana/grafana/issues/14435) +* **Dashboard search**: Fix for searching tags in tags filter dropdown. + +# 5.4.1 (2018-12-10) + +* **Stackdriver**: Fixes issue with data proxy and Authorization header [#14262](https://github.com/grafana/grafana/issues/14262) +* **Units**: fixedUnit for Flow:l/min and mL/min [#14294](https://github.com/grafana/grafana/issues/14294), thx [@flopp999](https://github.com/flopp999). +* **Logging**: Fix for issue where data proxy logged a secret when debug logging was enabled, now redacted. [#14319](https://github.com/grafana/grafana/issues/14319) +* **InfluxDB**: Add support for alerting on InfluxDB queries that use the cumulative_sum function. [#14314](https://github.com/grafana/grafana/pull/14314), thx [@nitti](https://github.com/nitti) +* **Plugins**: Panel plugins should no receive the panel-initialized event again as usual. +* **Embedded Graphs**: Iframe graph panels should now work as usual. [#14284](https://github.com/grafana/grafana/issues/14284) +* **Postgres**: Improve PostgreSQL Query Editor if using different Schemas, [#14313]( +https://github.com/grafana/grafana/pull/14313) +* **Quotas**: Fixed for updating org & user quotas. [#14347](https://github.com/grafana/grafana/pull/14347), thx [#moznion](https://github.com/moznion) +* **Cloudwatch**: Add the AWS/SES Cloudwatch metrics of BounceRate and ComplaintRate to auto complete list. [#14401](https://github.com/grafana/grafana/pull/14401), thx [@sglajchEG](https://github.com/sglajchEG) +* **Dashboard Search**: Fixed filtering by tag issues. +* **Graph**: Fixed time region issues, [#14425](https://github.com/grafana/grafana/issues/14425), [#14280](https://github.com/grafana/grafana/issues/14280) +* **Graph**: Fixed issue with series color picker popover being placed outside window. + + # 5.4.0 (2018-12-03) diff --git a/conf/defaults.ini b/conf/defaults.ini index a9aa2239b16..2ef2ad7942a 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -246,6 +246,10 @@ disable_signout_menu = false # URL to redirect the user to after sign out signout_redirect_url = +# Set to true to attempt login with OAuth automatically, skipping the login screen. +# This setting is ignored if multiple OAuth providers are configured. +oauth_auto_login = false + #################################### Anonymous Auth ###################### [auth.anonymous] # enable anonymous access diff --git a/conf/sample.ini b/conf/sample.ini index 3c61b2b61d1..ba65727dc4b 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -226,6 +226,10 @@ log_queries = # URL to redirect the user to after sign out ;signout_redirect_url = +# Set to true to attempt login with OAuth automatically, skipping the login screen. +# This setting is ignored if multiple OAuth providers are configured. +;oauth_auto_login = false + #################################### Anonymous Auth ########################## [auth.anonymous] # enable anonymous access diff --git a/devenv/datasources.yaml b/devenv/datasources.yaml index a4e9bf05641..a264bb503bd 100644 --- a/devenv/datasources.yaml +++ b/devenv/datasources.yaml @@ -35,7 +35,7 @@ datasources: tsdbResolution: 1 tsdbVersion: 1 - - name: gdev-elasticsearch-metrics + - name: gdev-elasticsearch-v2-metrics type: elasticsearch access: proxy database: "[metrics-]YYYY.MM.DD" @@ -43,6 +43,57 @@ datasources: jsonData: interval: Daily timeField: "@timestamp" + esVersion: 2 + + - name: gdev-elasticsearch-v2-logs + type: elasticsearch + access: proxy + database: "[logs-]YYYY.MM.DD" + url: http://localhost:9200 + jsonData: + interval: Daily + timeField: "@timestamp" + esVersion: 2 + + - name: gdev-elasticsearch-v5-metrics + type: elasticsearch + access: proxy + database: "[metrics-]YYYY.MM.DD" + url: http://localhost:10200 + jsonData: + interval: Daily + timeField: "@timestamp" + esVersion: 5 + + - name: gdev-elasticsearch-v5-logs + type: elasticsearch + access: proxy + database: "[logs-]YYYY.MM.DD" + url: http://localhost:10200 + jsonData: + interval: Daily + timeField: "@timestamp" + esVersion: 5 + + - name: gdev-elasticsearch-v6-metrics + type: elasticsearch + access: proxy + database: "[metrics-]YYYY.MM.DD" + url: http://localhost:11200 + jsonData: + interval: Daily + timeField: "@timestamp" + esVersion: 60 + + - name: gdev-elasticsearch-v6-logs + type: elasticsearch + access: proxy + database: "[logs-]YYYY.MM.DD" + url: http://localhost:11200 + jsonData: + interval: Daily + timeField: "@timestamp" + esVersion: 60 - name: gdev-mysql type: mysql diff --git a/devenv/dev-dashboards/datasource_tests_elasticsearch_compare.json b/devenv/dev-dashboards/datasource_tests_elasticsearch_compare.json new file mode 100644 index 00000000000..f07c6f46332 --- /dev/null +++ b/devenv/dev-dashboards/datasource_tests_elasticsearch_compare.json @@ -0,0 +1,5394 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": false, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1542304484522, + "links": [ + { + "icon": "external link", + "tags": [ + "gdev", + "elasticsearch" + ], + "type": "dashboards" + } + ], + "panels": [ + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 5, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 1 + }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "select field", + "id": "1", + "type": "count" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Basic (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 3, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "select field", + "id": "1", + "type": "count" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Basic (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "1m", + "min_doc_count": 50, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "select field", + "id": "1", + "type": "count" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Basic (version one) - interval 1m + min doc count 50", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "1m", + "min_doc_count": 50, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "select field", + "id": "1", + "type": "count" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Basic (version two) - interval 1m + min doc count 50", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 19 + }, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 10 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "select field", + "id": "1", + "type": "count" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Basic (version one) - interval 5m + trim edges=10", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 19 + }, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 10 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "select field", + "id": "1", + "type": "count" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Basic (version two) - interval 5m + trim edges=10", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Basic date histogram with count", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 11, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 2 + }, + "id": 12, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "missing": null + }, + "type": "avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "avg (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 2 + }, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "missing": null + }, + "type": "avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "avg (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 11 + }, + "id": 14, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "missing": null + }, + "type": "sum" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "sum (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 11 + }, + "id": 15, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "missing": null + }, + "type": "sum" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "sum (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 16, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "max (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 21, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "max (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 29 + }, + "id": 17, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "min" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "min (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 29 + }, + "id": 22, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "min" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "min (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 38 + }, + "id": 18, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sort": "min", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": { + "avg": true, + "count": true, + "max": true, + "min": true, + "std_deviation": true, + "std_deviation_bounds_lower": true, + "std_deviation_bounds_upper": true, + "sum": true + }, + "settings": {}, + "type": "extended_stats" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "extended stats (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 38 + }, + "id": 23, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sort": "min", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": { + "avg": true, + "count": true, + "max": true, + "min": true, + "std_deviation": true, + "std_deviation_bounds_lower": true, + "std_deviation_bounds_upper": true, + "sum": true + }, + "settings": {}, + "type": "extended_stats" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "extended stats (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 47 + }, + "id": 19, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "percents": [ + 25, + 50, + 75, + 95, + 99 + ] + }, + "type": "percentiles" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "percentiles (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 47 + }, + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "missing": null, + "percents": [ + 25, + 50, + 75, + 95, + 99 + ] + }, + "type": "percentiles" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "percentiles (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 56 + }, + "id": 20, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "cardinality" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "unique count (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 56 + }, + "id": 25, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": null + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "cardinality" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "unique count (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Basic date histogram with metric aggregation", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 27, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 3 + }, + "id": 55, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "count" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "count (version one) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 3 + }, + "id": 34, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "count" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "count (version two) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 29, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "avg" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "avg (version one) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 56, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "avg" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "avg (version two) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 21 + }, + "id": 30, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "sum" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "sum (version one) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 21 + }, + "id": 35, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "sum" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "sum (version two) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 30 + }, + "id": 31, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "max (version one) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 30 + }, + "id": 36, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "max (version two) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 39 + }, + "id": 32, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "min" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "min (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 39 + }, + "id": 37, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "min" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "min (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 48 + }, + "id": 33, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "cardinality" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "unique count (version one) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 48 + }, + "id": 38, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "cardinality" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": { + "minimize": false, + "model": "simple", + "window": 5 + }, + "type": "moving_avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "unique count (version two) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Basic date histogram with moving average aggregation", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 39, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 4 + }, + "id": 57, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "count" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "count (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 4 + }, + "id": 41, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "count" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "count (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 13 + }, + "id": 40, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "avg" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "avg (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 13 + }, + "id": 58, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "avg" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "avg (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 22 + }, + "id": 42, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "sum" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "sum (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 22 + }, + "id": 43, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "sum" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "sum (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 31 + }, + "id": 44, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "max (version one) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 45, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "max (version two) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 40 + }, + "id": 46, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "min" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "min (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 40 + }, + "id": 47, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "min" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "min (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 49 + }, + "id": 48, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "cardinality" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "unique count (version one) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 49 + }, + "id": 49, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "@value", + "hide": true, + "id": "1", + "meta": {}, + "settings": {}, + "type": "cardinality" + }, + { + "field": "1", + "id": "3", + "meta": {}, + "pipelineAgg": "1", + "settings": {}, + "type": "derivative" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "unique count (version two) - interval 5m", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Basic date histogram with derivative aggregation", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 4 + }, + "id": 54, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_one", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 5 + }, + "id": 51, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sort": "min", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "alias": "{{@source}} - {{@hostname}} - {{@metric}} {{metric}}", + "bucketAggs": [ + { + "fake": true, + "field": "@source", + "id": "4", + "settings": { + "min_doc_count": 1, + "order": "desc", + "orderBy": "_count", + "size": "10" + }, + "type": "terms" + }, + { + "fake": true, + "field": "@metric", + "id": "5", + "settings": { + "min_doc_count": 1, + "order": "desc", + "orderBy": "_term", + "size": "10" + }, + "type": "terms" + }, + { + "fake": true, + "field": "@hostname", + "id": "3", + "settings": { + "min_doc_count": 1, + "order": "desc", + "orderBy": "_term", + "size": "5" + }, + "type": "terms" + }, + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "select field", + "id": "1", + "type": "count" + }, + { + "field": "@value", + "id": "6", + "meta": {}, + "settings": {}, + "type": "avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "count/average with triple terms agg (version one) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "$version_two", + "decimals": 3, + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 5 + }, + "id": 52, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sort": "min", + "sortDesc": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "alias": "{{@source}} - {{@hostname}} - {{@metric}} {{metric}}", + "bucketAggs": [ + { + "fake": true, + "field": "@source", + "id": "4", + "settings": { + "min_doc_count": 1, + "order": "desc", + "orderBy": "_count", + "size": "10" + }, + "type": "terms" + }, + { + "fake": true, + "field": "@metric", + "id": "5", + "settings": { + "min_doc_count": 1, + "order": "desc", + "orderBy": "_term", + "size": "10" + }, + "type": "terms" + }, + { + "fake": true, + "field": "@hostname", + "id": "3", + "settings": { + "min_doc_count": 1, + "order": "desc", + "orderBy": "_term", + "size": "5" + }, + "type": "terms" + }, + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "metrics": [ + { + "field": "select field", + "id": "1", + "type": "count" + }, + { + "field": "@value", + "id": "6", + "meta": {}, + "settings": {}, + "type": "avg" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "count/average with triple terms agg (version two) - interval auto", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Multiple metrics and aggregations", + "type": "row" + } + ], + "refresh": false, + "schemaVersion": 16, + "style": "dark", + "tags": [ + "gdev", + "elasticsearch" + ], + "templating": { + "list": [ + { + "current": { + "text": "gdev-elasticsearch-v2-metrics", + "value": "gdev-elasticsearch-v2-metrics" + }, + "hide": 0, + "label": "Version One", + "name": "version_one", + "options": [], + "query": "elasticsearch", + "refresh": 1, + "regex": "/^gdev.*metrics$/", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "text": "gdev-elasticsearch-v5-metrics", + "value": "gdev-elasticsearch-v5-metrics" + }, + "hide": 0, + "label": "Version Two", + "name": "version_two", + "options": [], + "query": "elasticsearch", + "refresh": 1, + "regex": "/^gdev.*metrics$/", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Datasource tests - Elasticsearch comparison", + "uid": "fuFWehBmk", + "version": 10 +} \ No newline at end of file diff --git a/devenv/dev-dashboards/datasource_tests_elasticsearch_v2.json b/devenv/dev-dashboards/datasource_tests_elasticsearch_v2.json new file mode 100644 index 00000000000..e7c580bb75e --- /dev/null +++ b/devenv/dev-dashboards/datasource_tests_elasticsearch_v2.json @@ -0,0 +1,649 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": false, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + }, + { + "datasource": "Elastic 5 Logs", + "enable": false, + "iconColor": "rgba(255, 96, 96, 1)", + "limit": 100, + "name": "test", + "query": "", + "showIn": 0, + "textField": "description", + "type": "alert" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1542303970887, + "links": [ + { + "icon": "external link", + "tags": [ + "gdev", + "elasticsearch" + ], + "type": "dashboards" + } + ], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v2-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@hostname", + "id": "3", + "settings": { + "min_doc_count": 1, + "order": "asc", + "orderBy": "1", + "size": "5" + }, + "type": "terms" + }, + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + } + ], + "query": "*", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Top 5 servers", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Count": "#6ED0E0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v2-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Count", + "lines": false, + "yaxis": 2, + "zindex": -1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "{{metric}}", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "percents": [ + 25, + 50, + 75, + 95, + 99 + ] + }, + "type": "percentiles" + } + ], + "query": "@metric:cpu", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Percentiles & Metric filter", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Count": "#6ED0E0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v2-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Count", + "lines": false, + "yaxis": 2, + "zindex": -1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "{{metric}}", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": { + "std_deviation_bounds_lower": true, + "std_deviation_bounds_upper": true + }, + "settings": {}, + "type": "extended_stats" + } + ], + "query": "@metric:cpu", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Standard dev", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "columns": [ + { + "text": "@hostname", + "value": "@hostname" + }, + { + "text": "Average", + "value": "Average" + }, + { + "text": "Max", + "value": "Max" + }, + { + "text": "Sum", + "value": "Sum" + } + ], + "datasource": "gdev-elasticsearch-v2-metrics", + "editable": true, + "error": false, + "fontSize": "100%", + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 6, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "@timestamp", + "type": "date" + }, + { + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "bucketAggs": [ + { + "field": "@hostname", + "id": "2", + "settings": { + "min_doc_count": 1, + "order": "asc", + "orderBy": "_term", + "size": "0" + }, + "type": "terms" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "avg" + }, + { + "field": "@value", + "id": "3", + "meta": {}, + "settings": {}, + "type": "max" + }, + { + "field": "@value", + "id": "4", + "meta": {}, + "settings": {}, + "type": "sum" + } + ], + "refId": "B", + "timeField": "@timestamp" + } + ], + "title": "ES Metrics", + "transform": "table", + "type": "table" + }, + { + "columns": [ + { + "text": "@timestamp", + "value": "@timestamp" + }, + { + "text": "@message", + "value": "@message" + }, + { + "text": "tags", + "value": "tags" + }, + { + "text": "description", + "value": "description" + } + ], + "datasource": "gdev-elasticsearch-v2-logs", + "editable": true, + "error": false, + "fontSize": "100%", + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 5, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "@timestamp", + "type": "date" + } + ], + "targets": [ + { + "bucketAggs": [], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "select field", + "id": "1", + "meta": {}, + "settings": { + "size": 500 + }, + "type": "raw_document" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "title": "ES Log query", + "transform": "json", + "type": "table" + } + ], + "schemaVersion": 16, + "style": "dark", + "tags": [ + "elasticsearch", + "gdev" + ], + "templating": { + "list": [ + { + "datasource": "gdev-elasticsearch-v2-metrics", + "filters": [], + "hide": 0, + "label": "", + "name": "Filters", + "skipUrlSync": false, + "type": "adhoc" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "collapse": false, + "enable": true, + "notice": false, + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "status": "Stable", + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "timezone": "browser", + "title": "Datasource tests - Elasticsearch v2", + "uid": "RlqLq2fiz", + "version": 2 +} \ No newline at end of file diff --git a/devenv/dev-dashboards/datasource_tests_elasticsearch_v5.json b/devenv/dev-dashboards/datasource_tests_elasticsearch_v5.json new file mode 100644 index 00000000000..a117815037b --- /dev/null +++ b/devenv/dev-dashboards/datasource_tests_elasticsearch_v5.json @@ -0,0 +1,651 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": false, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + }, + { + "datasource": "Elastic 5 Logs", + "enable": false, + "iconColor": "rgba(255, 96, 96, 1)", + "limit": 100, + "name": "test", + "query": "", + "showIn": 0, + "textField": "description", + "type": "alert" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1542303896062, + "links": [ + { + "asDropdown": false, + "icon": "external link", + "tags": [ + "gdev", + "elasticsearch" + ], + "title": "Dashboard", + "type": "dashboards" + } + ], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v5-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@hostname", + "id": "3", + "settings": { + "min_doc_count": 1, + "order": "asc", + "orderBy": "1", + "size": "5" + }, + "type": "terms" + }, + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + } + ], + "query": "*", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Top 5 servers", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Count": "#6ED0E0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v5-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Count", + "lines": false, + "yaxis": 2, + "zindex": -1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "{{metric}}", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "percents": [ + 25, + 50, + 75, + 95, + 99 + ] + }, + "type": "percentiles" + } + ], + "query": "@metric:cpu", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Percentiles & Metric filter", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Count": "#6ED0E0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v5-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Count", + "lines": false, + "yaxis": 2, + "zindex": -1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "{{metric}}", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": { + "std_deviation_bounds_lower": true, + "std_deviation_bounds_upper": true + }, + "settings": {}, + "type": "extended_stats" + } + ], + "query": "@metric:cpu", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Standard dev", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "columns": [ + { + "text": "@hostname", + "value": "@hostname" + }, + { + "text": "Average", + "value": "Average" + }, + { + "text": "Max", + "value": "Max" + }, + { + "text": "Sum", + "value": "Sum" + } + ], + "datasource": "gdev-elasticsearch-v5-metrics", + "editable": true, + "error": false, + "fontSize": "100%", + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 6, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "@timestamp", + "type": "date" + }, + { + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "bucketAggs": [ + { + "field": "@hostname", + "id": "2", + "settings": { + "min_doc_count": 1, + "order": "asc", + "orderBy": "_term", + "size": "0" + }, + "type": "terms" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "avg" + }, + { + "field": "@value", + "id": "3", + "meta": {}, + "settings": {}, + "type": "max" + }, + { + "field": "@value", + "id": "4", + "meta": {}, + "settings": {}, + "type": "sum" + } + ], + "refId": "B", + "timeField": "@timestamp" + } + ], + "title": "ES Metrics", + "transform": "table", + "type": "table" + }, + { + "columns": [ + { + "text": "@timestamp", + "value": "@timestamp" + }, + { + "text": "@message", + "value": "@message" + }, + { + "text": "tags", + "value": "tags" + }, + { + "text": "description", + "value": "description" + } + ], + "datasource": "gdev-elasticsearch-v5-logs", + "editable": true, + "error": false, + "fontSize": "100%", + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 5, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "@timestamp", + "type": "date" + } + ], + "targets": [ + { + "bucketAggs": [], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "select field", + "id": "1", + "meta": {}, + "settings": { + "size": 500 + }, + "type": "raw_document" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "title": "ES Log query", + "transform": "json", + "type": "table" + } + ], + "schemaVersion": 16, + "style": "dark", + "tags": [ + "elasticsearch", + "gdev" + ], + "templating": { + "list": [ + { + "datasource": "gdev-elasticsearch-v5-metrics", + "filters": [], + "hide": 0, + "label": "", + "name": "Filters", + "skipUrlSync": false, + "type": "adhoc" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "collapse": false, + "enable": true, + "notice": false, + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "status": "Stable", + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "timezone": "browser", + "title": "Datasource tests - Elasticsearch v5", + "uid": "8HjT32Bmz", + "version": 27 +} \ No newline at end of file diff --git a/devenv/dev-dashboards/datasource_tests_elasticsearch_v6.json b/devenv/dev-dashboards/datasource_tests_elasticsearch_v6.json new file mode 100644 index 00000000000..ee5306d40cc --- /dev/null +++ b/devenv/dev-dashboards/datasource_tests_elasticsearch_v6.json @@ -0,0 +1,649 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": false, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + }, + { + "datasource": "Elastic 5 Logs", + "enable": false, + "iconColor": "rgba(255, 96, 96, 1)", + "limit": 100, + "name": "test", + "query": "", + "showIn": 0, + "textField": "description", + "type": "alert" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1542303999511, + "links": [ + { + "icon": "external link", + "tags": [ + "gdev", + "elasticsearch" + ], + "type": "dashboards" + } + ], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v6-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": true, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "bucketAggs": [ + { + "field": "@hostname", + "id": "3", + "settings": { + "min_doc_count": 1, + "order": "asc", + "orderBy": "1", + "size": "5" + }, + "type": "terms" + }, + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "max" + } + ], + "query": "*", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Top 5 servers", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Count": "#6ED0E0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v6-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 7 + }, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Count", + "lines": false, + "yaxis": 2, + "zindex": -1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "{{metric}}", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "5m", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": { + "percents": [ + 25, + 50, + 75, + 95, + 99 + ] + }, + "type": "percentiles" + } + ], + "query": "@metric:cpu", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Percentiles & Metric filter", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "Count": "#6ED0E0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "gdev-elasticsearch-v6-metrics", + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 7 + }, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Count", + "lines": false, + "yaxis": 2, + "zindex": -1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "{{metric}}", + "bucketAggs": [ + { + "field": "@timestamp", + "id": "2", + "settings": { + "interval": "auto", + "min_doc_count": 0, + "trimEdges": 0 + }, + "type": "date_histogram" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": { + "std_deviation_bounds_lower": true, + "std_deviation_bounds_upper": true + }, + "settings": {}, + "type": "extended_stats" + } + ], + "query": "@metric:cpu", + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Standard dev", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "columns": [ + { + "text": "@hostname", + "value": "@hostname" + }, + { + "text": "Average", + "value": "Average" + }, + { + "text": "Max", + "value": "Max" + }, + { + "text": "Sum", + "value": "Sum" + } + ], + "datasource": "gdev-elasticsearch-v6-metrics", + "editable": true, + "error": false, + "fontSize": "100%", + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 6, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "@timestamp", + "type": "date" + }, + { + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "bucketAggs": [ + { + "field": "@hostname", + "id": "2", + "settings": { + "min_doc_count": 1, + "order": "asc", + "orderBy": "_term", + "size": "0" + }, + "type": "terms" + } + ], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "@value", + "id": "1", + "meta": {}, + "settings": {}, + "type": "avg" + }, + { + "field": "@value", + "id": "3", + "meta": {}, + "settings": {}, + "type": "max" + }, + { + "field": "@value", + "id": "4", + "meta": {}, + "settings": {}, + "type": "sum" + } + ], + "refId": "B", + "timeField": "@timestamp" + } + ], + "title": "ES Metrics", + "transform": "table", + "type": "table" + }, + { + "columns": [ + { + "text": "@timestamp", + "value": "@timestamp" + }, + { + "text": "@message", + "value": "@message" + }, + { + "text": "tags", + "value": "tags" + }, + { + "text": "description", + "value": "description" + } + ], + "datasource": "gdev-elasticsearch-v6-logs", + "editable": true, + "error": false, + "fontSize": "100%", + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 5, + "links": [], + "pageSize": null, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "@timestamp", + "type": "date" + } + ], + "targets": [ + { + "bucketAggs": [], + "dsType": "elasticsearch", + "metrics": [ + { + "field": "select field", + "id": "1", + "meta": {}, + "settings": { + "size": 500 + }, + "type": "raw_document" + } + ], + "refId": "A", + "target": "", + "timeField": "@timestamp" + } + ], + "title": "ES Log query", + "transform": "json", + "type": "table" + } + ], + "schemaVersion": 16, + "style": "dark", + "tags": [ + "elasticsearch", + "gdev" + ], + "templating": { + "list": [ + { + "datasource": "gdev-elasticsearch-v6-metrics", + "filters": [], + "hide": 0, + "label": "", + "name": "Filters", + "skipUrlSync": false, + "type": "adhoc" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "collapse": false, + "enable": true, + "notice": false, + "now": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "status": "Stable", + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "timezone": "browser", + "title": "Datasource tests - Elasticsearch v6", + "uid": "NF8Pq2Biz", + "version": 2 +} \ No newline at end of file diff --git a/devenv/docker/blocks/elastic/docker-compose.yaml b/devenv/docker/blocks/elastic/docker-compose.yaml index 2eba60f38be..2a6209a8f4c 100644 --- a/devenv/docker/blocks/elastic/docker-compose.yaml +++ b/devenv/docker/blocks/elastic/docker-compose.yaml @@ -5,7 +5,7 @@ - "9200:9200" - "9300:9300" volumes: - - ./blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml + - ./docker/blocks/elastic/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml fake-elastic-data: image: grafana/fake-data-gen diff --git a/devenv/docker/blocks/elastic5/docker-compose.yaml b/devenv/docker/blocks/elastic5/docker-compose.yaml index 7148aa18c42..33a7d9855b0 100644 --- a/devenv/docker/blocks/elastic5/docker-compose.yaml +++ b/devenv/docker/blocks/elastic5/docker-compose.yaml @@ -1,15 +1,18 @@ # You need to run 'sysctl -w vm.max_map_count=262144' on the host machine - +version: '2' +services: elasticsearch5: image: elasticsearch:5 command: elasticsearch ports: - - "10200:9200" - - "10300:9300" + - '10200:9200' + - '10300:9300' fake-elastic5-data: image: grafana/fake-data-gen - network_mode: bridge + links: + - elasticsearch5 + # network_mode: bridge environment: FD_DATASOURCE: elasticsearch FD_PORT: 10200 diff --git a/devenv/docker/blocks/influxdb/docker-compose.yaml b/devenv/docker/blocks/influxdb/docker-compose.yaml index e1727807d41..e3ca81ced22 100644 --- a/devenv/docker/blocks/influxdb/docker-compose.yaml +++ b/devenv/docker/blocks/influxdb/docker-compose.yaml @@ -1,17 +1,19 @@ +version: '2' +services: influxdb: image: influxdb:latest container_name: influxdb ports: - - "2004:2004" - - "8083:8083" - - "8086:8086" + - '2004:2004' + - '8083:8083' + - '8086:8086' volumes: - ./docker/blocks/influxdb/influxdb.conf:/etc/influxdb/influxdb.conf fake-influxdb-data: image: grafana/fake-data-gen - network_mode: bridge + links: + - influxdb environment: FD_DATASOURCE: influxdb FD_PORT: 8086 - diff --git a/docs/sources/alerting/notifications.md b/docs/sources/alerting/notifications.md index e791492495e..5327039341f 100644 --- a/docs/sources/alerting/notifications.md +++ b/docs/sources/alerting/notifications.md @@ -157,27 +157,29 @@ There are a couple of configuration options which need to be set up in Grafana U Once these two properties are set, you can send the alerts to Kafka for further processing or throttling. -### All supported notifiers +### Google Hangouts Chat -Name | Type |Support images | Support reminders ------|------------ | ------ | ------ | -Slack | `slack` | yes | yes -Pagerduty | `pagerduty` | yes | yes -Email | `email` | yes | yes -Webhook | `webhook` | link | yes -Kafka | `kafka` | no | yes -Hipchat | `hipchat` | yes | yes -VictorOps | `victorops` | yes | yes -Sensu | `sensu` | yes | yes -OpsGenie | `opsgenie` | yes | yes -Threema | `threema` | yes | yes -Pushover | `pushover` | no | yes -Telegram | `telegram` | no | yes -Line | `line` | no | yes -Microsoft Teams | `teams` | yes | yes -Prometheus Alertmanager | `prometheus-alertmanager` | no | no +Notifications can be sent by setting up an incoming webhook in Google Hangouts chat. Configuring such a webhook is described [here](https://developers.google.com/hangouts/chat/how-tos/webhooks). +### All supported notifier +Name | Type |Support images +-----|------------ | ------ +Slack | `slack` | yes +Pagerduty | `pagerduty` | yes +Email | `email` | yes +Webhook | `webhook` | link +Kafka | `kafka` | no +Google Hangouts Chat | `googlechat` | yes +Hipchat | `hipchat` | yes +VictorOps | `victorops` | yes +Sensu | `sensu` | yes +OpsGenie | `opsgenie` | yes +Threema | `threema` | yes +Pushover | `pushover` | no +Telegram | `telegram` | no +Line | `line` | no +Prometheus Alertmanager | `prometheus-alertmanager` | no # Enable images in notifications {#external-image-store} diff --git a/docs/sources/features/explore/index.md b/docs/sources/features/explore/index.md new file mode 100644 index 00000000000..438943b3243 --- /dev/null +++ b/docs/sources/features/explore/index.md @@ -0,0 +1,162 @@ ++++ +title = "Explore" +type = "docs" +[menu.docs] +name = "Explore" +identifier = "explore" +parent = "features" +weight = 5 ++++ + +# Introduction + +One of the major new features of Grafana 6.0 is the new query-focused Explore workflow for troubleshooting and/or for data exploration. + +Grafana's dashboard UI is all about building dashboards for visualization. Explore strips away all the dashboard and panel options so that you can focus on the query. Iterate until you have a working query and then think about building a dashboard. + +For infrastructure monitoring and incident response, you no longer need to switch to other tools to debug what went wrong. Explore allows you to dig deeper into your metrics and logs to find the cause. Grafana's new logging datasource, [Loki](https://github.com/grafana/loki) is tightly integrated into Explore and allows you to correlate metrics and logs by viewing them side-by-side. This creates a new debugging workflow where you can: + +1. Receive an alert +2. Drill down and examine metrics +3. Drill down again and search logs related to the metric and time interval (and in the future, distributed traces). + +If you just want to explore your data and do not want to create a dashboard then Explore makes this much easier. Explore will show the results as both a graph and a table enabling you to see trends in the data and more detail at the same time (if the datasource supports both graph and table data). + +## Turning the Explore Feature On + +Explore will be officially released in Grafana 6.0. It is however already in the latest nightly builds of Grafana and can be turned using a feature flag in the config file. Restart Grafana after making the config file change. + +```ini +[explore] +# Enable the Explore section +enabled = true +``` + +Or if using docker: + +```bash +docker pull grafana/grafana:master +docker run --name grafana -p 3000:3000 -e "GF_EXPLORE_ENABLED=true" grafana/grafana:master +``` + +## How to Start Exploring + +There is a new Explore icon on the menu bar to the left. This opens a new empty Explore tab. + +{{< docs-imagebox img="/img/docs/v60/explore_menu.png" class="docs-image--no-shadow" caption="Screenshot of the new Explore Icon" >}} + +If you want to start with an existing query in a panel then choose the Explore option from the Panel menu. This opens an Explore tab with the query from the panel and allows you to tweak or iterate in the query outside of your dashboard. + +{{< docs-imagebox img="/img/docs/v60/explore_panel_menu.png" class="docs-image--no-shadow" caption="Screenshot of the new Explore option in the panel menu" >}} + +Choose your datasource in the dropdown in the top left. Prometheus has a custom Explore implementation, the other datasources (for now) use their standard query editor. + +The query field is where you can write your query and explore your data. There are three buttons beside the query field, a clear button (X), an add query button (+) and the remove query button (-). Just like the normal query editor, you can add and remove multiple queries. + +## Split and Compare + +The Split feature is an easy way to compare graphs and tables side-by-side or to look at related data together on one page. Click the split button to duplicate the current query and split the page into two side-by-side queries. It is possible to select another datasource for the new query which for example, allows you to compare the same query for two different servers or to compare the staging environment to the production environment. + +{{< docs-imagebox img="/img/docs/v60/explore_split.png" class="docs-image--no-shadow" caption="Screenshot of the new Explore option in the panel menu" >}} + +You can close the newly created query by clicking on the Close Split button. + +## Prometheus-specific Features + +The first version of Explore features a custom querying experience for Prometheus. When a query is executed, it actually executes two queries, a normal Prometheus query for the graph and an Instant Query for the table. An Instant Query returns the last value for each time series which shows a good summary of the data shown in the graph. + +### Metrics Explorer + +On the left-hand side of the query field is a `Metrics` button, clicking on this opens the Metric Explorer. This shows a hierarchical menu with metrics grouped by their prefix. For example, all the Alert Manager metrics will be grouped under the `alertmanager` prefix. This is a good starting point if you just want to explore which metrics are available. + +{{< docs-imagebox img="/img/docs/v60/explore_metric_explorer.png" class="docs-image--no-shadow" caption="Screenshot of the new Explore option in the panel menu" >}} + +### Query Field + +The Query field supports autocomplete for metric names, function and works mostly the same way as the standard Prometheus query editor. Press the enter key to execute a query. + +The autocomplete menu can be trigger by pressing Ctrl + Space. The Autocomplete menu contains a new History section with a list of recently executed queries. + +Suggestions can appear under the query field - click on them to update your query with the suggested change. + +- For counters (monotonously increasing metrics), a rate function will be suggested. +- For buckets, a histogram function will be suggested. +- For recording rules, possible to expand the rules. + +### Table Filters + +Click on the filter button in a labels column in the Table panel to add filters to the query expression. This works with multiple queries too - the filter will be added for all the queries. + +## Logs Integration - Loki-specific Features + +For Grafana 6.0, the first log integration is for the new open source log aggregation system from Grafana Labs - [Loki](https://github.com/grafana/loki). Loki is designed to be very cost effective, as it does not index the contents of the logs, but rather a set of labels for each log stream. The logs from Loki are queried in a similar way to querying with label selectors in Prometheus. It uses labels to group log streams which can be made to match up with your Prometheus labels. Read more about Grafana Loki [here](https://github.com/grafana/loki) or the Grafana Labs hosted variant: [Grafana Cloud Logs](https://grafana.com/loki). + +### Switching from Metrics to Logs + +If you switch from a Prometheus query to a logs query (you can do a split first to have your metrics and logs side by side) then it will keep the labels from your query that exist in the logs and use those to query the log streams. For example, the following Prometheus query: + +`grafana_alerting_active_alerts{job="grafana"}` + +after switching to the Logs datasource, the query changes to: + +`{job="grafana"}` + +This will return a chunk of logs in the selected time range that can be grepped/text searched. + +### Log Queries + +A log query consists of two parts: **log stream selector**, and a **search expression**. For performance reasons you need to start by choosing a log stream by selecting a log label. + +The Logs Explorer (the `Log labels` button) next to the query field shows a list of labels of available log streams. An alternative way to write a query is to use the query field's autocomplete - you start by typing a left curly brace `{` and the autocomplete menu will suggest a list of labels. Press the `enter` key to execute the query. + +Once the result is returned, the log panel shows a list of log rows and a bar chart where the x-axis shows the time and the y-axis shows the frequency/count. + +{{< docs-imagebox img="/img/docs/v60/explore_loki.png" class="docs-image--no-shadow" caption="Explore Loki Log Streams" >}} + +#### Log Stream Selector + +For the label part of the query expression, wrap it in curly braces `{}` and then use the key value syntax for selecting labels. Multiple label expressions are separated by a comma: + +`{app="mysql",name="mysql-backup"}` + +The following label matching operators are currently supported: + +- `=` exactly equal. +- `!=` not equal. +- `=~` regex-match. +- `!~` do not regex-match. + +Examples: + +- `{name=~"mysql.+"}` +- `{name!~"mysql.+"}` + +The [same rules that apply for Prometheus Label Selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#instant-vector-selectors) apply for Loki Log Stream Selectors. + +Another way to add a label selector, is in the table section, clicking on the **Filter** button beside a label will add the label to the query expression. This even works for multiple queries and will the label selector to each query. + +#### Search Expression + +After writing the Log Stream Selector, you can filter the results further by writing a search expression. The search expression can be just text or a regex expression. + +Example queries: + +- `{job="mysql"} error` +- `{name="kafka"} tsdb-ops.*io:2003` +- `{instance=~"kafka-[23]",name="kafka"} kafka.server:type=ReplicaManager` + +### Deduping + +Log data can be very repetitive and Explore can help by hiding duplicate log lines. There are a few different deduplication algorithms that you can use: + +- `exact` Exact matches are done on the whole line, except for date fields. +- `numbers` Matches on the line after stripping out numbers (durations, IP addresses etc.). +- `signature` The most aggressive deduping - strips all letters and numbers, and matches on the remaining whitespace and punctuation. + +### Timestamp, Local time and Labels + +There are some other check boxes under the logging graph apart from the Deduping options. + +- Timestamp: shows/hides the Timestamp column +- Local time: shows/hides the Local time column +- Labels: shows/hides the label filters column diff --git a/latest.json b/latest.json index d36158608bf..21a3f38e1af 100644 --- a/latest.json +++ b/latest.json @@ -1,4 +1,4 @@ { - "stable": "5.4.0", - "testing": "5.4.0" + "stable": "5.4.2", + "testing": "5.4.2" } diff --git a/package.json b/package.json index f5e6e22a8a2..d8ea4c036d4 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,12 @@ "url": "http://github.com/grafana/grafana.git" }, "devDependencies": { + "@babel/core": "^7.1.2", + "@rtsao/plugin-proposal-class-properties": "^7.0.1-patch.1", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/preset-env": "^7.1.0", + "@babel/preset-react": "^7.0.0", + "@babel/preset-typescript": "^7.1.0", "@types/d3": "^4.10.1", "@types/enzyme": "^3.1.13", "@types/jest": "^23.3.2", @@ -21,10 +27,10 @@ "angular-mocks": "1.6.6", "autoprefixer": "^6.4.0", "axios": "^0.17.1", - "babel-core": "^6.26.0", - "babel-loader": "^7.1.4", - "babel-plugin-syntax-dynamic-import": "^6.18.0", - "babel-preset-es2015": "^6.24.1", + "babel-core": "^7.0.0-bridge", + "babel-jest": "^23.6.0", + "babel-loader": "^8.0.4", + "babel-plugin-angularjs-annotate": "^0.9.0", "clean-webpack-plugin": "^0.1.19", "css-loader": "^0.28.7", "enzyme": "^3.6.0", @@ -108,18 +114,9 @@ "precommit": "lint-staged && grunt precommit" }, "lint-staged": { - "*.{ts,tsx}": [ - "prettier --write", - "git add" - ], - "*.scss": [ - "prettier --write", - "git add" - ], - "*pkg/**/*.go": [ - "gofmt -w -s", - "git add" - ] + "*.{ts,tsx}": ["prettier --write", "git add"], + "*.scss": ["prettier --write", "git add"], + "*pkg/**/*.go": ["gofmt -w -s", "git add"] }, "prettier": { "trailingComma": "es5", @@ -128,13 +125,12 @@ }, "license": "Apache-2.0", "dependencies": { + "@babel/polyfill": "^7.0.0", "angular": "1.6.6", "angular-bindonce": "0.3.1", "angular-native-dragdrop": "1.2.2", "angular-route": "1.6.6", "angular-sanitize": "1.6.6", - "babel-jest": "^23.6.0", - "babel-polyfill": "^6.26.0", "baron": "^3.0.3", "brace": "^0.10.0", "classnames": "^2.2.5", @@ -156,7 +152,7 @@ "react-custom-scrollbars": "^4.2.1", "react-dom": "^16.5.0", "react-grid-layout": "0.16.6", - "react-highlight-words": "^0.10.0", + "react-highlight-words": "0.11.0", "react-popper": "^0.7.5", "react-redux": "^5.0.7", "react-select": "2.1.0", diff --git a/packaging/docker/build-enterprise.sh b/packaging/docker/build-enterprise.sh index e10e0d691e8..10c24784d5c 100755 --- a/packaging/docker/build-enterprise.sh +++ b/packaging/docker/build-enterprise.sh @@ -18,3 +18,8 @@ docker build \ . docker push "${_docker_repo}:${_grafana_tag}" + +if echo "$_raw_grafana_tag" | grep -q "^v" && echo "$_raw_grafana_tag" | grep -qv "beta"; then + docker tag "${_docker_repo}:${_grafana_tag}" "${_docker_repo}:latest" + docker push "${_docker_repo}:latest" +fi diff --git a/packaging/publish/publish_both.sh b/packaging/publish/publish_both.sh index cbe3918bf38..b1d480567e9 100755 --- a/packaging/publish/publish_both.sh +++ b/packaging/publish/publish_both.sh @@ -1,7 +1,7 @@ #! /usr/bin/env bash -version=5.0.2 +version=5.4.1 -wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${version}_amd64.deb +wget https://dl.grafana.com/oss/release/grafana_${version}_amd64.deb package_cloud push grafana/stable/debian/jessie grafana_${version}_amd64.deb package_cloud push grafana/stable/debian/wheezy grafana_${version}_amd64.deb @@ -11,7 +11,7 @@ package_cloud push grafana/testing/debian/jessie grafana_${version}_amd64.deb package_cloud push grafana/testing/debian/wheezy grafana_${version}_amd64.deb --verbose package_cloud push grafana/testing/debian/stretch grafana_${version}_amd64.deb --verbose -wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-${version}-1.x86_64.rpm +wget https://dl.grafana.com/release/grafana-${version}-1.x86_64.rpm package_cloud push grafana/testing/el/6 grafana-${version}-1.x86_64.rpm --verbose package_cloud push grafana/testing/el/7 grafana-${version}-1.x86_64.rpm --verbose diff --git a/pkg/api/admin_users.go b/pkg/api/admin_users.go index dc3d390dda9..efc760d2b51 100644 --- a/pkg/api/admin_users.go +++ b/pkg/api/admin_users.go @@ -76,6 +76,7 @@ func AdminUpdateUserPassword(c *m.ReqContext, form dtos.AdminUpdateUserPasswordF c.JsonOK("User password updated") } +// PUT /api/admin/users/:id/permissions func AdminUpdateUserPermissions(c *m.ReqContext, form dtos.AdminUpdateUserPermissionsForm) { userID := c.ParamsInt64(":id") @@ -85,6 +86,11 @@ func AdminUpdateUserPermissions(c *m.ReqContext, form dtos.AdminUpdateUserPermis } if err := bus.Dispatch(&cmd); err != nil { + if err == m.ErrLastGrafanaAdmin { + c.JsonApiErr(400, m.ErrLastGrafanaAdmin.Error(), nil) + return + } + c.JsonApiErr(500, "Failed to update user permissions", err) return } diff --git a/pkg/api/admin_users_test.go b/pkg/api/admin_users_test.go new file mode 100644 index 00000000000..0b94a64b3fb --- /dev/null +++ b/pkg/api/admin_users_test.go @@ -0,0 +1,50 @@ +package api + +import ( + "testing" + + "github.com/grafana/grafana/pkg/api/dtos" + "github.com/grafana/grafana/pkg/bus" + m "github.com/grafana/grafana/pkg/models" + + . "github.com/smartystreets/goconvey/convey" +) + +func TestAdminApiEndpoint(t *testing.T) { + role := m.ROLE_ADMIN + Convey("Given a server admin attempts to remove themself as an admin", t, func() { + + updateCmd := dtos.AdminUpdateUserPermissionsForm{ + IsGrafanaAdmin: false, + } + + bus.AddHandler("test", func(cmd *m.UpdateUserPermissionsCommand) error { + return m.ErrLastGrafanaAdmin + }) + + putAdminScenario("When calling PUT on", "/api/admin/users/1/permissions", "/api/admin/users/:id/permissions", role, updateCmd, func(sc *scenarioContext) { + sc.fakeReqWithParams("PUT", sc.url, map[string]string{}).exec() + So(sc.resp.Code, ShouldEqual, 400) + }) + }) +} + +func putAdminScenario(desc string, url string, routePattern string, role m.RoleType, cmd dtos.AdminUpdateUserPermissionsForm, fn scenarioFunc) { + Convey(desc+" "+url, func() { + defer bus.ClearBusHandlers() + + sc := setupScenarioContext(url) + sc.defaultHandler = Wrap(func(c *m.ReqContext) { + sc.context = c + sc.context.UserId = TestUserID + sc.context.OrgId = TestOrgID + sc.context.OrgRole = role + + AdminUpdateUserPermissions(c, cmd) + }) + + sc.m.Put(routePattern, sc.defaultHandler) + + fn(sc) + }) +} diff --git a/pkg/api/index.go b/pkg/api/index.go index 253fa9c17af..2980d8a5c6b 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -147,9 +147,6 @@ func (hs *HTTPServer) setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, er SubTitle: "Explore your data", Icon: "fa fa-rocket", Url: setting.AppSubUrl + "/explore", - Children: []*dtos.NavLink{ - {Text: "New tab", Icon: "gicon gicon-dashboard-new", Url: setting.AppSubUrl + "/explore"}, - }, }) } diff --git a/pkg/api/pluginproxy/pluginproxy.go b/pkg/api/pluginproxy/pluginproxy.go index ffbe470cb20..66e4498c283 100644 --- a/pkg/api/pluginproxy/pluginproxy.go +++ b/pkg/api/pluginproxy/pluginproxy.go @@ -87,7 +87,7 @@ func NewApiPluginProxy(ctx *m.ReqContext, proxyPath string, route *plugins.AppPl } for key, value := range headers { - log.Trace("setting key %v value %v", key, value[0]) + log.Trace("setting key %v value ", key) req.Header.Set(key, value[0]) } } diff --git a/pkg/components/dynmap/dynmap.go b/pkg/components/dynmap/dynmap.go index 96effb24332..f247aca959f 100644 --- a/pkg/components/dynmap/dynmap.go +++ b/pkg/components/dynmap/dynmap.go @@ -1,5 +1,5 @@ // uses code from https://github.com/antonholmquist/jason/blob/master/jason.go -// MIT Licence +// MIT License package dynmap diff --git a/pkg/components/dynmap/dynmap_test.go b/pkg/components/dynmap/dynmap_test.go index 62d356bd67d..68d938214a3 100644 --- a/pkg/components/dynmap/dynmap_test.go +++ b/pkg/components/dynmap/dynmap_test.go @@ -1,5 +1,5 @@ // uses code from https://github.com/antonholmquist/jason/blob/master/jason.go -// MIT Licence +// MIT License package dynmap diff --git a/pkg/models/user.go b/pkg/models/user.go index e3c7b556d35..69031e40338 100644 --- a/pkg/models/user.go +++ b/pkg/models/user.go @@ -7,7 +7,8 @@ import ( // Typed errors var ( - ErrUserNotFound = errors.New("User not found") + ErrUserNotFound = errors.New("User not found") + ErrLastGrafanaAdmin = errors.New("Cannot remove last grafana admin") ) type Password string diff --git a/pkg/services/alerting/notifiers/googlechat.go b/pkg/services/alerting/notifiers/googlechat.go new file mode 100644 index 00000000000..1aba15a7928 --- /dev/null +++ b/pkg/services/alerting/notifiers/googlechat.go @@ -0,0 +1,215 @@ +package notifiers + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/log" + m "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/alerting" + "github.com/grafana/grafana/pkg/setting" +) + +func init() { + alerting.RegisterNotifier(&alerting.NotifierPlugin{ + Type: "googlechat", + Name: "Google Hangouts Chat", + Description: "Sends notifications to Google Hangouts Chat via webhooks based on the official JSON message " + + "format (https://developers.google.com/hangouts/chat/reference/message-formats/).", + Factory: NewGoogleChatNotifier, + OptionsTemplate: ` +

Google Hangouts Chat settings

+
+ Url + +
+ `, + }) +} + +func NewGoogleChatNotifier(model *m.AlertNotification) (alerting.Notifier, error) { + url := model.Settings.Get("url").MustString() + if url == "" { + return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} + } + + return &GoogleChatNotifier{ + NotifierBase: NewNotifierBase(model), + Url: url, + log: log.New("alerting.notifier.googlechat"), + }, nil +} + +type GoogleChatNotifier struct { + NotifierBase + Url string + log log.Logger +} + +/** +Structs used to build a custom Google Hangouts Chat message card. +See: https://developers.google.com/hangouts/chat/reference/message-formats/cards +*/ +type outerStruct struct { + Cards []card `json:"cards"` +} + +type card struct { + Header header `json:"header"` + Sections []section `json:"sections"` +} + +type header struct { + Title string `json:"title"` +} + +type section struct { + Widgets []widget `json:"widgets"` +} + +// "generic" widget used to add different types of widgets (buttonWidget, textParagraphWidget, imageWidget) +type widget interface { +} + +type buttonWidget struct { + Buttons []button `json:"buttons"` +} + +type textParagraphWidget struct { + Text text `json:"textParagraph"` +} + +type text struct { + Text string `json:"text"` +} + +type imageWidget struct { + Image image `json:"image"` +} + +type image struct { + ImageUrl string `json:"imageUrl"` +} + +type button struct { + TextButton textButton `json:"textButton"` +} + +type textButton struct { + Text string `json:"text"` + OnClick onClick `json:"onClick"` +} + +type onClick struct { + OpenLink openLink `json:"openLink"` +} + +type openLink struct { + Url string `json:"url"` +} + +func (this *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error { + this.log.Info("Executing Google Chat notification") + + headers := map[string]string{ + "Content-Type": "application/json; charset=UTF-8", + } + + ruleUrl, err := evalContext.GetRuleUrl() + if err != nil { + this.log.Error("evalContext returned an invalid rule URL") + } + + // add a text paragraph widget for the message + widgets := []widget{ + textParagraphWidget{ + Text: text{ + Text: evalContext.Rule.Message, + }, + }, + } + + // add a text paragraph widget for the fields + var fields []textParagraphWidget + fieldLimitCount := 4 + for index, evt := range evalContext.EvalMatches { + fields = append(fields, + textParagraphWidget{ + Text: text{ + Text: "" + evt.Metric + ": " + fmt.Sprint(evt.Value) + "", + }, + }, + ) + if index > fieldLimitCount { + break + } + } + widgets = append(widgets, fields) + + // if an image exists, add it as an image widget + if evalContext.ImagePublicUrl != "" { + widgets = append(widgets, imageWidget{ + Image: image{ + ImageUrl: evalContext.ImagePublicUrl, + }, + }) + } else { + this.log.Info("Could not retrieve a public image URL.") + } + + // add a button widget (link to Grafana) + widgets = append(widgets, buttonWidget{ + Buttons: []button{ + { + TextButton: textButton{ + Text: "OPEN IN GRAFANA", + OnClick: onClick{ + OpenLink: openLink{ + Url: ruleUrl, + }, + }, + }, + }, + }, + }) + + // add text paragraph widget for the build version and timestamp + widgets = append(widgets, textParagraphWidget{ + Text: text{ + Text: "Grafana v" + setting.BuildVersion + " | " + (time.Now()).Format(time.RFC822), + }, + }) + + // nest the required structs + res1D := &outerStruct{ + Cards: []card{ + { + Header: header{ + Title: evalContext.GetNotificationTitle(), + }, + Sections: []section{ + { + Widgets: widgets, + }, + }, + }, + }, + } + body, _ := json.Marshal(res1D) + + cmd := &m.SendWebhookSync{ + Url: this.Url, + HttpMethod: "POST", + HttpHeader: headers, + Body: string(body), + } + + if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil { + this.log.Error("Failed to send Google Hangouts Chat alert", "error", err, "webhook", this.Name) + return err + } + + return nil +} diff --git a/pkg/services/alerting/notifiers/googlechat_test.go b/pkg/services/alerting/notifiers/googlechat_test.go new file mode 100644 index 00000000000..1fdce878926 --- /dev/null +++ b/pkg/services/alerting/notifiers/googlechat_test.go @@ -0,0 +1,53 @@ +package notifiers + +import ( + "testing" + + "github.com/grafana/grafana/pkg/components/simplejson" + m "github.com/grafana/grafana/pkg/models" + . "github.com/smartystreets/goconvey/convey" +) + +func TestGoogleChatNotifier(t *testing.T) { + Convey("Google Hangouts Chat notifier tests", t, func() { + + Convey("Parsing alert notification from settings", func() { + Convey("empty settings should return error", func() { + json := `{ }` + + settingsJSON, _ := simplejson.NewJson([]byte(json)) + model := &m.AlertNotification{ + Name: "ops", + Type: "googlechat", + Settings: settingsJSON, + } + + _, err := NewGoogleChatNotifier(model) + So(err, ShouldNotBeNil) + }) + + Convey("from settings", func() { + json := ` + { + "url": "http://google.com" + }` + + settingsJSON, _ := simplejson.NewJson([]byte(json)) + model := &m.AlertNotification{ + Name: "ops", + Type: "googlechat", + Settings: settingsJSON, + } + + not, err := NewGoogleChatNotifier(model) + webhookNotifier := not.(*GoogleChatNotifier) + + So(err, ShouldBeNil) + So(webhookNotifier.Name, ShouldEqual, "ops") + So(webhookNotifier.Type, ShouldEqual, "googlechat") + So(webhookNotifier.Url, ShouldEqual, "http://google.com") + }) + + }) + }) +} diff --git a/pkg/services/provisioning/dashboards/file_reader.go b/pkg/services/provisioning/dashboards/file_reader.go index ea093860f3e..f9590b01bf1 100644 --- a/pkg/services/provisioning/dashboards/file_reader.go +++ b/pkg/services/provisioning/dashboards/file_reader.go @@ -333,12 +333,12 @@ func (fr *fileReader) resolvePath(path string) string { copy := path path, err := filepath.Abs(path) if err != nil { - fr.log.Error("Could not create absolute path ", "path", path) + fr.log.Error("Could not create absolute path", "path", copy, "error", err) } path, err = filepath.EvalSymlinks(path) if err != nil { - fr.log.Error("Failed to read content of symlinked path: %s", path) + fr.log.Error("Failed to read content of symlinked path", "path", copy, "error", err) } if path == "" { diff --git a/pkg/services/sqlstore/migrations/datasource_mig.go b/pkg/services/sqlstore/migrations/datasource_mig.go index 9011429e398..fc617be72a1 100644 --- a/pkg/services/sqlstore/migrations/datasource_mig.go +++ b/pkg/services/sqlstore/migrations/datasource_mig.go @@ -127,4 +127,7 @@ func addDataSourceMigration(mg *Migrator) { mg.AddMigration("Add read_only data column", NewAddColumnMigration(tableV2, &Column{ Name: "read_only", Type: DB_Bool, Nullable: true, })) + + const migrateLoggingToLoki = `UPDATE data_source SET type = 'loki' WHERE type = 'logging'` + mg.AddMigration("Migrate logging ds to loki ds", NewRawSqlMigration(migrateLoggingToLoki)) } diff --git a/pkg/services/sqlstore/org_test.go b/pkg/services/sqlstore/org_test.go index c02686c24ba..7e966106b96 100644 --- a/pkg/services/sqlstore/org_test.go +++ b/pkg/services/sqlstore/org_test.go @@ -187,7 +187,7 @@ func TestAccountDataAccess(t *testing.T) { err := DeleteOrg(&m.DeleteOrgCommand{Id: ac2.OrgId}) So(err, ShouldBeNil) - // remove frome ac2 from ac1 org + // remove ac2 user from ac1 org remCmd := m.RemoveOrgUserCommand{OrgId: ac1.OrgId, UserId: ac2.Id, ShouldDeleteOrphanedUser: true} err = RemoveOrgUser(&remCmd) So(err, ShouldBeNil) diff --git a/pkg/services/sqlstore/quota.go b/pkg/services/sqlstore/quota.go index 7005b341268..e90b7fec131 100644 --- a/pkg/services/sqlstore/quota.go +++ b/pkg/services/sqlstore/quota.go @@ -99,14 +99,14 @@ func UpdateOrgQuota(cmd *m.UpdateOrgQuotaCmd) error { return inTransaction(func(sess *DBSession) error { //Check if quota is already defined in the DB quota := m.Quota{ - Target: cmd.Target, - OrgId: cmd.OrgId, - Updated: time.Now(), + Target: cmd.Target, + OrgId: cmd.OrgId, } has, err := sess.Get("a) if err != nil { return err } + quota.Updated = time.Now() quota.Limit = cmd.Limit if !has { quota.Created = time.Now() @@ -201,14 +201,14 @@ func UpdateUserQuota(cmd *m.UpdateUserQuotaCmd) error { return inTransaction(func(sess *DBSession) error { //Check if quota is already defined in the DB quota := m.Quota{ - Target: cmd.Target, - UserId: cmd.UserId, - Updated: time.Now(), + Target: cmd.Target, + UserId: cmd.UserId, } has, err := sess.Get("a) if err != nil { return err } + quota.Updated = time.Now() quota.Limit = cmd.Limit if !has { quota.Created = time.Now() diff --git a/pkg/services/sqlstore/quota_test.go b/pkg/services/sqlstore/quota_test.go index 49e028e9cd3..976d54d10e2 100644 --- a/pkg/services/sqlstore/quota_test.go +++ b/pkg/services/sqlstore/quota_test.go @@ -2,6 +2,7 @@ package sqlstore import ( "testing" + "time" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" @@ -168,5 +169,69 @@ func TestQuotaCommandsAndQueries(t *testing.T) { So(query.Result.Limit, ShouldEqual, 5) So(query.Result.Used, ShouldEqual, 1) }) + + // related: https://github.com/grafana/grafana/issues/14342 + Convey("Should org quota updating is successful even if it called multiple time", func() { + orgCmd := m.UpdateOrgQuotaCmd{ + OrgId: orgId, + Target: "org_user", + Limit: 5, + } + err := UpdateOrgQuota(&orgCmd) + So(err, ShouldBeNil) + + query := m.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1} + err = GetOrgQuotaByTarget(&query) + So(err, ShouldBeNil) + So(query.Result.Limit, ShouldEqual, 5) + + // XXX: resolution of `Updated` column is 1sec, so this makes delay + time.Sleep(1 * time.Second) + + orgCmd = m.UpdateOrgQuotaCmd{ + OrgId: orgId, + Target: "org_user", + Limit: 10, + } + err = UpdateOrgQuota(&orgCmd) + So(err, ShouldBeNil) + + query = m.GetOrgQuotaByTargetQuery{OrgId: orgId, Target: "org_user", Default: 1} + err = GetOrgQuotaByTarget(&query) + So(err, ShouldBeNil) + So(query.Result.Limit, ShouldEqual, 10) + }) + + // related: https://github.com/grafana/grafana/issues/14342 + Convey("Should user quota updating is successful even if it called multiple time", func() { + userQuotaCmd := m.UpdateUserQuotaCmd{ + UserId: userId, + Target: "org_user", + Limit: 5, + } + err := UpdateUserQuota(&userQuotaCmd) + So(err, ShouldBeNil) + + query := m.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1} + err = GetUserQuotaByTarget(&query) + So(err, ShouldBeNil) + So(query.Result.Limit, ShouldEqual, 5) + + // XXX: resolution of `Updated` column is 1sec, so this makes delay + time.Sleep(1 * time.Second) + + userQuotaCmd = m.UpdateUserQuotaCmd{ + UserId: userId, + Target: "org_user", + Limit: 10, + } + err = UpdateUserQuota(&userQuotaCmd) + So(err, ShouldBeNil) + + query = m.GetUserQuotaByTargetQuery{UserId: userId, Target: "org_user", Default: 1} + err = GetUserQuotaByTarget(&query) + So(err, ShouldBeNil) + So(query.Result.Limit, ShouldEqual, 10) + }) }) } diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go index 99a77ecabc3..a3ccb93b30c 100644 --- a/pkg/services/sqlstore/user.go +++ b/pkg/services/sqlstore/user.go @@ -504,8 +504,18 @@ func UpdateUserPermissions(cmd *m.UpdateUserPermissionsCommand) error { user.IsAdmin = cmd.IsGrafanaAdmin sess.UseBool("is_admin") + _, err := sess.ID(user.Id).Update(&user) - return err + if err != nil { + return err + } + + // validate that after update there is at least one server admin + if err := validateOneAdminLeft(sess); err != nil { + return err + } + + return nil }) } @@ -522,3 +532,17 @@ func SetUserHelpFlag(cmd *m.SetUserHelpFlagCommand) error { return err }) } + +func validateOneAdminLeft(sess *DBSession) error { + // validate that there is an admin user left + count, err := sess.Where("is_admin=?", true).Count(&m.User{}) + if err != nil { + return err + } + + if count == 0 { + return m.ErrLastGrafanaAdmin + } + + return nil +} diff --git a/pkg/services/sqlstore/user_test.go b/pkg/services/sqlstore/user_test.go index b26dd235772..627f2ab1ca5 100644 --- a/pkg/services/sqlstore/user_test.go +++ b/pkg/services/sqlstore/user_test.go @@ -155,6 +155,32 @@ func TestUserDataAccess(t *testing.T) { }) }) }) + + Convey("Given one grafana admin user", func() { + var err error + createUserCmd := &m.CreateUserCommand{ + Email: fmt.Sprint("admin", "@test.com"), + Name: fmt.Sprint("admin"), + Login: fmt.Sprint("admin"), + IsAdmin: true, + } + err = CreateUser(context.Background(), createUserCmd) + So(err, ShouldBeNil) + + Convey("Cannot make themselves a non-admin", func() { + updateUserPermsCmd := m.UpdateUserPermissionsCommand{IsGrafanaAdmin: false, UserId: 1} + updatePermsError := UpdateUserPermissions(&updateUserPermsCmd) + + So(updatePermsError, ShouldEqual, m.ErrLastGrafanaAdmin) + + query := m.GetUserByIdQuery{Id: createUserCmd.Result.Id} + getUserError := GetUserById(&query) + + So(getUserError, ShouldBeNil) + + So(query.Result.IsAdmin, ShouldEqual, true) + }) + }) }) } diff --git a/pkg/tsdb/cloudwatch/metric_find_query.go b/pkg/tsdb/cloudwatch/metric_find_query.go index dd026bbb79e..dfa03d2dfa9 100644 --- a/pkg/tsdb/cloudwatch/metric_find_query.go +++ b/pkg/tsdb/cloudwatch/metric_find_query.go @@ -101,7 +101,7 @@ func init() { "AWS/RDS": {"ActiveTransactions", "AuroraBinlogReplicaLag", "AuroraReplicaLag", "AuroraReplicaLagMaximum", "AuroraReplicaLagMinimum", "BinLogDiskUsage", "BlockedTransactions", "BufferCacheHitRatio", "BurstBalance", "CommitLatency", "CommitThroughput", "BinLogDiskUsage", "CPUCreditBalance", "CPUCreditUsage", "CPUUtilization", "DatabaseConnections", "DDLLatency", "DDLThroughput", "Deadlocks", "DeleteLatency", "DeleteThroughput", "DiskQueueDepth", "DMLLatency", "DMLThroughput", "EngineUptime", "FailedSqlStatements", "FreeableMemory", "FreeLocalStorage", "FreeStorageSpace", "InsertLatency", "InsertThroughput", "LoginFailures", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "NetworkThroughput", "Queries", "ReadIOPS", "ReadLatency", "ReadThroughput", "ReplicaLag", "ResultSetCacheHitRatio", "SelectLatency", "SelectThroughput", "SwapUsage", "TotalConnections", "UpdateLatency", "UpdateThroughput", "VolumeBytesUsed", "VolumeReadIOPS", "VolumeWriteIOPS", "WriteIOPS", "WriteLatency", "WriteThroughput"}, "AWS/Route53": {"ChildHealthCheckHealthyCount", "HealthCheckStatus", "HealthCheckPercentageHealthy", "ConnectionTime", "SSLHandshakeTime", "TimeToFirstByte"}, "AWS/S3": {"BucketSizeBytes", "NumberOfObjects", "AllRequests", "GetRequests", "PutRequests", "DeleteRequests", "HeadRequests", "PostRequests", "ListRequests", "BytesDownloaded", "BytesUploaded", "4xxErrors", "5xxErrors", "FirstByteLatency", "TotalRequestLatency"}, - "AWS/SES": {"Bounce", "Complaint", "Delivery", "Reject", "Send"}, + "AWS/SES": {"Bounce", "Complaint", "Delivery", "Reject", "Send", "Reputation.BounceRate", "Reputation.ComplaintRate"}, "AWS/SNS": {"NumberOfMessagesPublished", "PublishSize", "NumberOfNotificationsDelivered", "NumberOfNotificationsFailed"}, "AWS/SQS": {"NumberOfMessagesSent", "SentMessageSize", "NumberOfMessagesReceived", "NumberOfEmptyReceives", "NumberOfMessagesDeleted", "ApproximateAgeOfOldestMessage", "ApproximateNumberOfMessagesDelayed", "ApproximateNumberOfMessagesVisible", "ApproximateNumberOfMessagesNotVisible"}, "AWS/States": {"ExecutionTime", "ExecutionThrottled", "ExecutionsAborted", "ExecutionsFailed", "ExecutionsStarted", "ExecutionsSucceeded", "ExecutionsTimedOut", "ActivityRunTime", "ActivityScheduleTime", "ActivityTime", "ActivitiesFailed", "ActivitiesHeartbeatTimedOut", "ActivitiesScheduled", "ActivitiesScheduled", "ActivitiesSucceeded", "ActivitiesTimedOut", "LambdaFunctionRunTime", "LambdaFunctionScheduleTime", "LambdaFunctionTime", "LambdaFunctionsFailed", "LambdaFunctionsHeartbeatTimedOut", "LambdaFunctionsScheduled", "LambdaFunctionsStarted", "LambdaFunctionsSucceeded", "LambdaFunctionsTimedOut"}, diff --git a/pkg/tsdb/elasticsearch/models.go b/pkg/tsdb/elasticsearch/models.go index b3fdee95b91..46af5e4b745 100644 --- a/pkg/tsdb/elasticsearch/models.go +++ b/pkg/tsdb/elasticsearch/models.go @@ -73,5 +73,8 @@ func isPipelineAgg(metricType string) bool { func describeMetric(metricType, field string) string { text := metricAggType[metricType] + if metricType == countType { + return text + } return text + " " + field } diff --git a/pkg/tsdb/elasticsearch/response_parser.go b/pkg/tsdb/elasticsearch/response_parser.go index 0837c3dd9d5..b2c724a9b93 100644 --- a/pkg/tsdb/elasticsearch/response_parser.go +++ b/pkg/tsdb/elasticsearch/response_parser.go @@ -541,7 +541,7 @@ func getErrorFromElasticResponse(response *es.SearchResponse) *tsdb.QueryResult } else if reason != "" { result.ErrorString = reason } else { - result.ErrorString = "Unkown elasticsearch error response" + result.ErrorString = "Unknown elasticsearch error response" } return result diff --git a/pkg/tsdb/elasticsearch/time_series_query.go b/pkg/tsdb/elasticsearch/time_series_query.go index a25c3cf693d..28a930df3a2 100644 --- a/pkg/tsdb/elasticsearch/time_series_query.go +++ b/pkg/tsdb/elasticsearch/time_series_query.go @@ -89,15 +89,29 @@ func (e *timeSeriesQuery) execute() (*tsdb.Response, error) { } for _, m := range q.Metrics { - if m.Type == "count" { + if m.Type == countType { continue } if isPipelineAgg(m.Type) { if _, err := strconv.Atoi(m.PipelineAggregate); err == nil { - aggBuilder.Pipeline(m.ID, m.Type, m.PipelineAggregate, func(a *es.PipelineAggregation) { - a.Settings = m.Settings.MustMap() - }) + var appliedAgg *MetricAgg + for _, pipelineMetric := range q.Metrics { + if pipelineMetric.ID == m.PipelineAggregate { + appliedAgg = pipelineMetric + break + } + } + if appliedAgg != nil { + bucketPath := m.PipelineAggregate + if appliedAgg.Type == countType { + bucketPath = "_count" + } + + aggBuilder.Pipeline(m.ID, m.Type, bucketPath, func(a *es.PipelineAggregation) { + a.Settings = m.Settings.MustMap() + }) + } } else { continue } diff --git a/pkg/tsdb/elasticsearch/time_series_query_test.go b/pkg/tsdb/elasticsearch/time_series_query_test.go index 9660d70c318..a4f305242fa 100644 --- a/pkg/tsdb/elasticsearch/time_series_query_test.go +++ b/pkg/tsdb/elasticsearch/time_series_query_test.go @@ -418,6 +418,38 @@ func TestExecuteTimeSeriesQuery(t *testing.T) { So(pl.BucketPath, ShouldEqual, "3") }) + Convey("With moving average doc count", func() { + c := newFakeClient(5) + _, err := executeTsdbQuery(c, `{ + "timeField": "@timestamp", + "bucketAggs": [ + { "type": "date_histogram", "field": "@timestamp", "id": "4" } + ], + "metrics": [ + { "id": "3", "type": "count", "field": "select field" }, + { + "id": "2", + "type": "moving_avg", + "field": "3", + "pipelineAgg": "3" + } + ] + }`, from, to, 15*time.Second) + So(err, ShouldBeNil) + sr := c.multisearchRequests[0].Requests[0] + + firstLevel := sr.Aggs[0] + So(firstLevel.Key, ShouldEqual, "4") + So(firstLevel.Aggregation.Type, ShouldEqual, "date_histogram") + So(firstLevel.Aggregation.Aggs, ShouldHaveLength, 1) + + movingAvgAgg := firstLevel.Aggregation.Aggs[0] + So(movingAvgAgg.Key, ShouldEqual, "2") + So(movingAvgAgg.Aggregation.Type, ShouldEqual, "moving_avg") + pl := movingAvgAgg.Aggregation.Aggregation.(*es.PipelineAggregation) + So(pl.BucketPath, ShouldEqual, "_count") + }) + Convey("With broken moving average", func() { c := newFakeClient(5) _, err := executeTsdbQuery(c, `{ @@ -483,6 +515,34 @@ func TestExecuteTimeSeriesQuery(t *testing.T) { So(plAgg.BucketPath, ShouldEqual, "3") }) + Convey("With derivative doc count", func() { + c := newFakeClient(5) + _, err := executeTsdbQuery(c, `{ + "timeField": "@timestamp", + "bucketAggs": [ + { "type": "date_histogram", "field": "@timestamp", "id": "4" } + ], + "metrics": [ + { "id": "3", "type": "count", "field": "select field" }, + { + "id": "2", + "type": "derivative", + "pipelineAgg": "3" + } + ] + }`, from, to, 15*time.Second) + So(err, ShouldBeNil) + sr := c.multisearchRequests[0].Requests[0] + + firstLevel := sr.Aggs[0] + So(firstLevel.Key, ShouldEqual, "4") + So(firstLevel.Aggregation.Type, ShouldEqual, "date_histogram") + + derivativeAgg := firstLevel.Aggregation.Aggs[0] + So(derivativeAgg.Key, ShouldEqual, "2") + plAgg := derivativeAgg.Aggregation.Aggregation.(*es.PipelineAggregation) + So(plAgg.BucketPath, ShouldEqual, "_count") + }) }) } diff --git a/pkg/tsdb/influxdb/query_part.go b/pkg/tsdb/influxdb/query_part.go index 77f565a8597..29a77f15617 100644 --- a/pkg/tsdb/influxdb/query_part.go +++ b/pkg/tsdb/influxdb/query_part.go @@ -32,6 +32,7 @@ func init() { renders["median"] = QueryDefinition{Renderer: functionRenderer} renders["sum"] = QueryDefinition{Renderer: functionRenderer} renders["mode"] = QueryDefinition{Renderer: functionRenderer} + renders["cumulative_sum"] = QueryDefinition{Renderer: functionRenderer} renders["holt_winters"] = QueryDefinition{ Renderer: functionRenderer, diff --git a/pkg/tsdb/influxdb/query_part_test.go b/pkg/tsdb/influxdb/query_part_test.go index 08bcff9b727..76daf6446d8 100644 --- a/pkg/tsdb/influxdb/query_part_test.go +++ b/pkg/tsdb/influxdb/query_part_test.go @@ -23,6 +23,7 @@ func TestInfluxdbQueryPart(t *testing.T) { {mode: "alias", params: []string{"test"}, input: "mean(value)", expected: `mean(value) AS "test"`}, {mode: "count", params: []string{}, input: "distinct(value)", expected: `count(distinct(value))`}, {mode: "mode", params: []string{}, input: "value", expected: `mode(value)`}, + {mode: "cumulative_sum", params: []string{}, input: "mean(value)", expected: `cumulative_sum(mean(value))`}, } queryContext := &tsdb.TsdbQuery{TimeRange: tsdb.NewTimeRange("5m", "now")} diff --git a/pkg/tsdb/opentsdb/opentsdb.go b/pkg/tsdb/opentsdb/opentsdb.go index 16da764de54..a810d3c7338 100644 --- a/pkg/tsdb/opentsdb/opentsdb.go +++ b/pkg/tsdb/opentsdb/opentsdb.go @@ -84,7 +84,7 @@ func (e *OpenTsdbExecutor) createRequest(dsInfo *models.DataSource, data OpenTsd postData, err := json.Marshal(data) if err != nil { - plog.Info("Failed marshalling data", "error", err) + plog.Info("Failed marshaling data", "error", err) return nil, fmt.Errorf("Failed to create request. error: %v", err) } diff --git a/public/app/app.ts b/public/app/app.ts index 9647fbe5416..2b94ec0fe33 100644 --- a/public/app/app.ts +++ b/public/app/app.ts @@ -1,4 +1,4 @@ -import 'babel-polyfill'; +import '@babel/polyfill'; import 'file-saver'; import 'lodash'; import 'jquery'; diff --git a/public/app/core/angular_wrappers.ts b/public/app/core/angular_wrappers.ts index 7be28272f11..5609c058a27 100644 --- a/public/app/core/angular_wrappers.ts +++ b/public/app/core/angular_wrappers.ts @@ -16,7 +16,7 @@ export function registerAngularDirectives() { react2AngularDirective('searchResult', SearchResult, []); react2AngularDirective('tagFilter', TagFilter, [ 'tags', - ['onSelect', { watchDepth: 'reference' }], + ['onChange', { watchDepth: 'reference' }], ['tagOptions', { watchDepth: 'reference' }], ]); } diff --git a/public/app/core/components/PermissionList/AddPermission.tsx b/public/app/core/components/PermissionList/AddPermission.tsx index 71cc937ddfa..d6da7c68544 100644 --- a/public/app/core/components/PermissionList/AddPermission.tsx +++ b/public/app/core/components/PermissionList/AddPermission.tsx @@ -84,7 +84,7 @@ class AddPermissions extends Component { render() { const { onCancel } = this.props; const newItem = this.state; - const pickerClassName = 'width-20'; + const pickerClassName = 'min-width-20'; const isValid = this.isValid(); return (
diff --git a/public/app/core/components/Picker/UserPicker.tsx b/public/app/core/components/Picker/UserPicker.tsx index f78cf69bf5e..f80a3fc135f 100644 --- a/public/app/core/components/Picker/UserPicker.tsx +++ b/public/app/core/components/Picker/UserPicker.tsx @@ -40,7 +40,7 @@ export class UserPicker extends Component { .then(result => { return result.map(user => ({ id: user.userId, - label: `${user.login} - ${user.email}`, + label: user.login === user.email ? user.login : `${user.login} - ${user.email}`, avatarUrl: user.avatarUrl, login: user.login, })); diff --git a/public/app/core/components/TagFilter/TagFilter.tsx b/public/app/core/components/TagFilter/TagFilter.tsx index 14b6ef4932b..004221657ef 100644 --- a/public/app/core/components/TagFilter/TagFilter.tsx +++ b/public/app/core/components/TagFilter/TagFilter.tsx @@ -10,7 +10,7 @@ import ResetStyles from 'app/core/components/Picker/ResetStyles'; export interface Props { tags: string[]; tagOptions: () => any; - onSelect: (tag: string) => void; + onChange: (tags: string[]) => void; } export class TagFilter extends React.Component { @@ -18,12 +18,9 @@ export class TagFilter extends React.Component { constructor(props) { super(props); - - this.searchTags = this.searchTags.bind(this); - this.onChange = this.onChange.bind(this); } - searchTags(query) { + onLoadOptions = query => { return this.props.tagOptions().then(options => { return options.map(option => ({ value: option.term, @@ -31,18 +28,20 @@ export class TagFilter extends React.Component { count: option.count, })); }); - } + }; - onChange(newTags) { - this.props.onSelect(newTags); - } + onChange = (newTags: any[]) => { + this.props.onChange(newTags.map(tag => tag.value)); + }; render() { + const tags = this.props.tags.map(tag => ({ value: tag, label: tag, count: 0 })); + const selectOptions = { classNamePrefix: 'gf-form-select-box', isMulti: true, defaultOptions: true, - loadOptions: this.searchTags, + loadOptions: this.onLoadOptions, onChange: this.onChange, className: 'gf-form-input gf-form-input--form-dropdown', placeholder: 'Tags', @@ -50,8 +49,12 @@ export class TagFilter extends React.Component { noOptionsMessage: () => 'No tags found', getOptionValue: i => i.value, getOptionLabel: i => i.label, - value: this.props.tags, + value: tags, styles: ResetStyles, + filterOption: (option, searchQuery) => { + const regex = RegExp(searchQuery, 'i'); + return regex.test(option.value); + }, components: { Option: TagOption, IndicatorsContainer, diff --git a/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx b/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx new file mode 100644 index 00000000000..077d8772393 --- /dev/null +++ b/public/app/core/components/ToggleButtonGroup/ToggleButtonGroup.tsx @@ -0,0 +1,76 @@ +import React, { SFC, ReactNode, PureComponent, ReactElement } from 'react'; + +interface ToggleButtonGroupProps { + onChange: (value) => void; + value?: any; + label?: string; + render: (props) => void; +} + +export default class ToggleButtonGroup extends PureComponent { + getValues() { + const { children } = this.props; + return React.Children.toArray(children).map((c: ReactElement) => c.props.value); + } + + smallChildren() { + const { children } = this.props; + return React.Children.toArray(children).every((c: ReactElement) => c.props.className.includes('small')); + } + + handleToggle(toggleValue) { + const { value, onChange } = this.props; + if (value && value === toggleValue) { + return; + } + onChange(toggleValue); + } + + render() { + const { value, label } = this.props; + const values = this.getValues(); + const selectedValue = value || values[0]; + const labelClassName = `gf-form-label ${this.smallChildren() ? 'small' : ''}`; + + return ( +
+
+ {label && } + {this.props.render({ selectedValue, onChange: this.handleToggle.bind(this) })} +
+
+ ); + } +} + +interface ToggleButtonProps { + onChange?: (value) => void; + selected?: boolean; + value: any; + className?: string; + children: ReactNode; + title?: string; +} + +export const ToggleButton: SFC = ({ + children, + selected, + className = '', + title = null, + value, + onChange, +}) => { + const handleChange = event => { + event.stopPropagation(); + if (onChange) { + onChange(value); + } + }; + + const btnClassName = `btn ${className} ${selected ? 'active' : ''}`; + return ( + + ); +}; diff --git a/public/app/core/components/code_editor/theme-grafana-dark.js b/public/app/core/components/code_editor/theme-grafana-dark.js index a48715e698e..33d4a84b527 100644 --- a/public/app/core/components/code_editor/theme-grafana-dark.js +++ b/public/app/core/components/code_editor/theme-grafana-dark.js @@ -14,7 +14,7 @@ ace.define("ace/theme/grafana-dark",["require","exports","module","ace/lib/dom"] background: #555651\ }\ .gf-code-dark {\ - background-color: #111;\ + background-color: #09090b;\ color: #e0e0e0\ }\ .gf-code-dark .ace_cursor {\ diff --git a/public/app/core/components/colorpicker/SeriesColorPicker.tsx b/public/app/core/components/colorpicker/SeriesColorPicker.tsx index d6feaa31965..32b7554e38d 100644 --- a/public/app/core/components/colorpicker/SeriesColorPicker.tsx +++ b/public/app/core/components/colorpicker/SeriesColorPicker.tsx @@ -44,7 +44,7 @@ export class SeriesColorPicker extends React.Component { const drop = new Drop({ target: this.pickerElem, content: dropContentElem, - position: 'top center', + position: 'bottom center', classes: 'drop-popover', openOn: 'hover', hoverCloseDelay: 200, diff --git a/public/app/core/components/search/search.html b/public/app/core/components/search/search.html index 8723d5d0584..8a83ecbc205 100644 --- a/public/app/core/components/search/search.html +++ b/public/app/core/components/search/search.html @@ -41,7 +41,7 @@
- + diff --git a/public/app/core/components/search/search.ts b/public/app/core/components/search/search.ts index 322dd2bdf10..ff63ca5a8fe 100644 --- a/public/app/core/components/search/search.ts +++ b/public/app/core/components/search/search.ts @@ -25,8 +25,6 @@ export class SearchCtrl { appEvents.on('hide-dash-search', this.closeSearch.bind(this), $scope); this.initialFolderFilterTitle = 'All'; - this.getTags = this.getTags.bind(this); - this.onTagSelect = this.onTagSelect.bind(this); this.isEditor = contextSrv.isEditor; this.hasEditPermissionInFolders = contextSrv.hasEditPermissionInFolders; } @@ -162,7 +160,7 @@ export class SearchCtrl { const localSearchId = this.currentSearchId; const query = { ...this.query, - tag: this.query.tag.map(i => i.value), + tag: this.query.tag, }; return this.searchSrv.search(query).then(results => { @@ -195,14 +193,14 @@ export class SearchCtrl { evt.preventDefault(); } - getTags() { + getTags = () => { return this.searchSrv.getDashboardTags(); - } + }; - onTagSelect(newTags) { - this.query.tag = newTags; + onTagFiltersChanged = (tags: string[]) => { + this.query.tag = tags; this.search(); - } + }; clearSearchFilter() { this.query.tag = []; diff --git a/public/app/core/components/sidemenu/TopSectionItem.tsx b/public/app/core/components/sidemenu/TopSectionItem.tsx index 4a207cc0df9..7b3bf96dce8 100644 --- a/public/app/core/components/sidemenu/TopSectionItem.tsx +++ b/public/app/core/components/sidemenu/TopSectionItem.tsx @@ -15,7 +15,7 @@ const TopSectionItem: SFC = props => { {link.img && } - {link.children && } + ); }; diff --git a/public/app/core/components/sidemenu/__snapshots__/TopSectionItem.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/TopSectionItem.test.tsx.snap index f7ff56bff6b..d79e9171581 100644 --- a/public/app/core/components/sidemenu/__snapshots__/TopSectionItem.test.tsx.snap +++ b/public/app/core/components/sidemenu/__snapshots__/TopSectionItem.test.tsx.snap @@ -13,5 +13,8 @@ exports[`Render should render component 1`] = ` + `; diff --git a/public/app/core/config.ts b/public/app/core/config.ts index 1473f8a91f8..13d84772ecf 100644 --- a/public/app/core/config.ts +++ b/public/app/core/config.ts @@ -54,7 +54,11 @@ export class Settings { } } -const bootData = (window as any).grafanaBootData || { settings: {} }; +const bootData = (window as any).grafanaBootData || { + settings: {}, + user: {}, +}; + const options = bootData.settings; options.bootData = bootData; diff --git a/public/app/core/logs_model.ts b/public/app/core/logs_model.ts index c05f5bab866..fabb29c6e18 100644 --- a/public/app/core/logs_model.ts +++ b/public/app/core/logs_model.ts @@ -1,6 +1,6 @@ import _ from 'lodash'; import { TimeSeries } from 'app/core/core'; -import colors from 'app/core/utils/colors'; +import colors, { getThemeColor } from 'app/core/utils/colors'; export enum LogLevel { crit = 'critical', @@ -22,7 +22,7 @@ export const LogLevelColor = { [LogLevel.info]: colors[0], [LogLevel.debug]: colors[5], [LogLevel.trace]: colors[2], - [LogLevel.unkown]: '#ddd', + [LogLevel.unkown]: getThemeColor('#8e8e8e', '#dde4ed'), }; export interface LogSearchMatch { @@ -45,6 +45,13 @@ export interface LogRow { uniqueLabels?: LogsStreamLabels; } +export interface LogsLabelStat { + active?: boolean; + count: number; + proportion: number; + value: string; +} + export enum LogsMetaKind { Number, String, @@ -81,6 +88,13 @@ export interface LogsStreamLabels { [key: string]: string; } +export enum LogsDedupDescription { + none = 'No de-duplication', + exact = 'De-duplication of successive lines that are identical, ignoring ISO datetimes.', + numbers = 'De-duplication of successive lines that are identical when ignoring numbers, e.g., IP addresses, latencies.', + signature = 'De-duplication of successive lines that have identical punctuation and whitespace.', +} + export enum LogsDedupStrategy { none = 'none', exact = 'exact', @@ -88,6 +102,111 @@ export enum LogsDedupStrategy { signature = 'signature', } +export interface LogsParser { + /** + * Value-agnostic matcher for a field label. + * Used to filter rows, and first capture group contains the value. + */ + buildMatcher: (label: string) => RegExp; + + /** + * Returns all parsable substrings from a line, used for highlighting + */ + getFields: (line: string) => string[]; + + /** + * Gets the label name from a parsable substring of a line + */ + getLabelFromField: (field: string) => string; + + /** + * Gets the label value from a parsable substring of a line + */ + getValueFromField: (field: string) => string; + /** + * Function to verify if this is a valid parser for the given line. + * The parser accepts the line unless it returns undefined. + */ + test: (line: string) => any; +} + +const LOGFMT_REGEXP = /(?:^|\s)(\w+)=("[^"]*"|\S+)/; + +export const LogsParsers: { [name: string]: LogsParser } = { + JSON: { + buildMatcher: label => new RegExp(`(?:{|,)\\s*"${label}"\\s*:\\s*"?([\\d\\.]+|[^"]*)"?`), + getFields: line => { + const fields = []; + try { + const parsed = JSON.parse(line); + _.map(parsed, (value, key) => { + const fieldMatcher = new RegExp(`"${key}"\\s*:\\s*"?${_.escapeRegExp(JSON.stringify(value))}"?`); + + const match = line.match(fieldMatcher); + if (match) { + fields.push(match[0]); + } + }); + } catch {} + return fields; + }, + getLabelFromField: field => (field.match(/^"(\w+)"\s*:/) || [])[1], + getValueFromField: field => (field.match(/:\s*(.*)$/) || [])[1], + test: line => { + try { + return JSON.parse(line); + } catch (error) {} + }, + }, + + logfmt: { + buildMatcher: label => new RegExp(`(?:^|\\s)${label}=("[^"]*"|\\S+)`), + getFields: line => { + const fields = []; + line.replace(new RegExp(LOGFMT_REGEXP, 'g'), substring => { + fields.push(substring.trim()); + return ''; + }); + return fields; + }, + getLabelFromField: field => (field.match(LOGFMT_REGEXP) || [])[1], + getValueFromField: field => (field.match(LOGFMT_REGEXP) || [])[2], + test: line => LOGFMT_REGEXP.test(line), + }, +}; + +export function calculateFieldStats(rows: LogRow[], extractor: RegExp): LogsLabelStat[] { + // Consider only rows that satisfy the matcher + const rowsWithField = rows.filter(row => extractor.test(row.entry)); + const rowCount = rowsWithField.length; + + // Get field value counts for eligible rows + const countsByValue = _.countBy(rowsWithField, row => (row as LogRow).entry.match(extractor)[1]); + const sortedCounts = _.chain(countsByValue) + .map((count, value) => ({ count, value, proportion: count / rowCount })) + .sortBy('count') + .reverse() + .value(); + + return sortedCounts; +} + +export function calculateLogsLabelStats(rows: LogRow[], label: string): LogsLabelStat[] { + // Consider only rows that have the given label + const rowsWithLabel = rows.filter(row => row.labels[label] !== undefined); + const rowCount = rowsWithLabel.length; + + // Get label value counts for eligible rows + const countsByValue = _.countBy(rowsWithLabel, row => (row as LogRow).labels[label]); + const sortedCounts = _.chain(countsByValue) + .map((count, value) => ({ count, value, proportion: count / rowCount })) + .sortBy('count') + .reverse() + .value(); + + return sortedCounts; +} + const isoDateRegexp = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-6]\d[,\.]\d+([+-][0-2]\d:[0-5]\d|Z)/g; function isDuplicateRow(row: LogRow, other: LogRow, strategy: LogsDedupStrategy): boolean { switch (strategy) { @@ -128,6 +247,19 @@ export function dedupLogRows(logs: LogsModel, strategy: LogsDedupStrategy): Logs }; } +export function getParser(line: string): LogsParser { + let parser; + try { + if (LogsParsers.JSON.test(line)) { + parser = LogsParsers.JSON; + } + } catch (error) {} + if (!parser && LogsParsers.logfmt.test(line)) { + parser = LogsParsers.logfmt; + } + return parser; +} + export function filterLogLevels(logs: LogsModel, hiddenLogLevels: Set): LogsModel { if (hiddenLogLevels.size === 0) { return logs; @@ -147,31 +279,55 @@ export function filterLogLevels(logs: LogsModel, hiddenLogLevels: Set) } export function makeSeriesForLogs(rows: LogRow[], intervalMs: number): TimeSeries[] { + // currently interval is rangeMs / resolution, which is too low for showing series as bars. + // need at least 10px per bucket, so we multiply interval by 10. Should be solved higher up the chain + // when executing queries & interval calculated and not here but this is a temporary fix. + // intervalMs = intervalMs * 10; + // Graph time series by log level const seriesByLevel = {}; - rows.forEach(row => { - if (!seriesByLevel[row.logLevel]) { - seriesByLevel[row.logLevel] = { lastTs: null, datapoints: [], alias: row.logLevel }; + const bucketSize = intervalMs * 10; + const seriesList = []; + + for (const row of rows) { + let series = seriesByLevel[row.logLevel]; + + if (!series) { + seriesByLevel[row.logLevel] = series = { + lastTs: null, + datapoints: [], + alias: row.logLevel, + color: LogLevelColor[row.logLevel], + }; + + seriesList.push(series); } - const levelSeries = seriesByLevel[row.logLevel]; + + // align time to bucket size + const time = Math.round(row.timeEpochMs / bucketSize) * bucketSize; - // Bucket to nearest minute - const time = Math.round(row.timeEpochMs / intervalMs / 10) * intervalMs * 10; // Entry for time - if (time === levelSeries.lastTs) { - levelSeries.datapoints[levelSeries.datapoints.length - 1][0]++; + if (time === series.lastTs) { + series.datapoints[series.datapoints.length - 1][0]++; } else { - levelSeries.datapoints.push([1, time]); - levelSeries.lastTs = time; + series.datapoints.push([1, time]); + series.lastTs = time; } - }); - return Object.keys(seriesByLevel).reduce((acc, level) => { - if (seriesByLevel[level]) { - const gs = new TimeSeries(seriesByLevel[level]); - gs.setColor(LogLevelColor[level]); - acc.push(gs); + // add zero to other levels to aid stacking so each level series has same number of points + for (const other of seriesList) { + if (other !== series && other.lastTs !== time) { + other.datapoints.push([0, time]); + other.lastTs = time; + } } - return acc; - }, []); + } + + return seriesList.map(series => { + series.datapoints.sort((a, b) => { + return a[1] - b[1]; + }); + + return new TimeSeries(series); + }); } diff --git a/public/app/core/specs/logs_model.test.ts b/public/app/core/specs/logs_model.test.ts index 5e427468339..c59d18e8b7d 100644 --- a/public/app/core/specs/logs_model.test.ts +++ b/public/app/core/specs/logs_model.test.ts @@ -1,4 +1,12 @@ -import { dedupLogRows, LogsDedupStrategy, LogsModel } from '../logs_model'; +import { + calculateFieldStats, + calculateLogsLabelStats, + dedupLogRows, + getParser, + LogsDedupStrategy, + LogsModel, + LogsParsers, +} from '../logs_model'; describe('dedupLogRows()', () => { test('should return rows as is when dedup is set to none', () => { @@ -106,3 +114,190 @@ describe('dedupLogRows()', () => { ]); }); }); + +describe('calculateFieldStats()', () => { + test('should return no stats for empty rows', () => { + expect(calculateFieldStats([], /foo=(.*)/)).toEqual([]); + }); + + test('should return no stats if extractor does not match', () => { + const rows = [ + { + entry: 'foo=bar', + }, + ]; + + expect(calculateFieldStats(rows as any, /baz=(.*)/)).toEqual([]); + }); + + test('should return stats for found field', () => { + const rows = [ + { + entry: 'foo="42 + 1"', + }, + { + entry: 'foo=503 baz=foo', + }, + { + entry: 'foo="42 + 1"', + }, + { + entry: 't=2018-12-05T07:44:59+0000 foo=503', + }, + ]; + + expect(calculateFieldStats(rows as any, /foo=("[^"]*"|\S+)/)).toMatchObject([ + { + value: '"42 + 1"', + count: 2, + }, + { + value: '503', + count: 2, + }, + ]); + }); +}); + +describe('calculateLogsLabelStats()', () => { + test('should return no stats for empty rows', () => { + expect(calculateLogsLabelStats([], '')).toEqual([]); + }); + + test('should return no stats of label is not found', () => { + const rows = [ + { + entry: 'foo 1', + labels: { + foo: 'bar', + }, + }, + ]; + + expect(calculateLogsLabelStats(rows as any, 'baz')).toEqual([]); + }); + + test('should return stats for found labels', () => { + const rows = [ + { + entry: 'foo 1', + labels: { + foo: 'bar', + }, + }, + { + entry: 'foo 0', + labels: { + foo: 'xxx', + }, + }, + { + entry: 'foo 2', + labels: { + foo: 'bar', + }, + }, + ]; + + expect(calculateLogsLabelStats(rows as any, 'foo')).toMatchObject([ + { + value: 'bar', + count: 2, + }, + { + value: 'xxx', + count: 1, + }, + ]); + }); +}); + +describe('getParser()', () => { + test('should return no parser on empty line', () => { + expect(getParser('')).toBeUndefined(); + }); + + test('should return no parser on unknown line pattern', () => { + expect(getParser('To Be or not to be')).toBeUndefined(); + }); + + test('should return logfmt parser on key value patterns', () => { + expect(getParser('foo=bar baz="41 + 1')).toEqual(LogsParsers.logfmt); + }); + + test('should return JSON parser on JSON log lines', () => { + // TODO implement other JSON value types than string + expect(getParser('{"foo": "bar", "baz": "41 + 1"}')).toEqual(LogsParsers.JSON); + }); +}); + +describe('LogsParsers', () => { + describe('logfmt', () => { + const parser = LogsParsers.logfmt; + + test('should detect format', () => { + expect(parser.test('foo')).toBeFalsy(); + expect(parser.test('foo=bar')).toBeTruthy(); + }); + + test('should return parsed fields', () => { + expect(parser.getFields('foo=bar baz="42 + 1"')).toEqual(['foo=bar', 'baz="42 + 1"']); + }); + + test('should return label for field', () => { + expect(parser.getLabelFromField('foo=bar')).toBe('foo'); + }); + + test('should return value for field', () => { + expect(parser.getValueFromField('foo=bar')).toBe('bar'); + }); + + test('should build a valid value matcher', () => { + const matcher = parser.buildMatcher('foo'); + const match = 'foo=bar'.match(matcher); + expect(match).toBeDefined(); + expect(match[1]).toBe('bar'); + }); + }); + + describe('JSON', () => { + const parser = LogsParsers.JSON; + + test('should detect format', () => { + expect(parser.test('foo')).toBeFalsy(); + expect(parser.test('{"foo":"bar"}')).toBeTruthy(); + }); + + test('should return parsed fields', () => { + expect(parser.getFields('{ "foo" : "bar", "baz" : 42 }')).toEqual(['"foo" : "bar"', '"baz" : 42']); + }); + + test('should return parsed fields for nested quotes', () => { + expect(parser.getFields(`{"foo":"bar: '[value=\\"42\\"]'"}`)).toEqual([`"foo":"bar: '[value=\\"42\\"]'"`]); + }); + + test('should return label for field', () => { + expect(parser.getLabelFromField('"foo" : "bar"')).toBe('foo'); + }); + + test('should return value for field', () => { + expect(parser.getValueFromField('"foo" : "bar"')).toBe('"bar"'); + expect(parser.getValueFromField('"foo" : 42')).toBe('42'); + expect(parser.getValueFromField('"foo" : 42.1')).toBe('42.1'); + }); + + test('should build a valid value matcher for strings', () => { + const matcher = parser.buildMatcher('foo'); + const match = '{"foo":"bar"}'.match(matcher); + expect(match).toBeDefined(); + expect(match[1]).toBe('bar'); + }); + + test('should build a valid value matcher for integers', () => { + const matcher = parser.buildMatcher('foo'); + const match = '{"foo":42.1}'.match(matcher); + expect(match).toBeDefined(); + expect(match[1]).toBe('42.1'); + }); + }); +}); diff --git a/public/app/core/utils/colors.ts b/public/app/core/utils/colors.ts index 13e02b76e30..34508e94a9f 100644 --- a/public/app/core/utils/colors.ts +++ b/public/app/core/utils/colors.ts @@ -1,5 +1,6 @@ import _ from 'lodash'; import tinycolor from 'tinycolor2'; +import config from 'app/core/config'; export const PALETTE_ROWS = 4; export const PALETTE_COLUMNS = 14; @@ -90,5 +91,9 @@ export function hslToHex(color) { return tinycolor(color).toHexString(); } +export function getThemeColor(dark: string, light: string): string { + return config.bootData.user.lightTheme ? light : dark; +} + export let sortedColors = sortColorsByHue(colors); export default colors; diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts index be771c1b232..26b6a527d95 100644 --- a/public/app/core/utils/explore.ts +++ b/public/app/core/utils/explore.ts @@ -1,15 +1,15 @@ import _ from 'lodash'; import { renderUrl } from 'app/core/utils/url'; -import { ExploreState, ExploreUrlState, HistoryItem, QueryTransaction } from 'app/types/explore'; -import { DataQuery, RawTimeRange } from 'app/types/series'; - -import TableModel, { mergeTablesIntoModel } from 'app/core/table_model'; import kbn from 'app/core/utils/kbn'; -import colors from 'app/core/utils/colors'; -import TimeSeries from 'app/core/time_series2'; -import { parse as parseDate } from 'app/core/utils/datemath'; import store from 'app/core/store'; +import colors from 'app/core/utils/colors'; +import { parse as parseDate } from 'app/core/utils/datemath'; + +import TimeSeries from 'app/core/time_series2'; +import TableModel, { mergeTablesIntoModel } from 'app/core/table_model'; +import { ExploreState, ExploreUrlState, HistoryItem, QueryTransaction } from 'app/types/explore'; +import { DataQuery, RawTimeRange, IntervalValues, DataSourceApi } from 'app/types/series'; export const DEFAULT_RANGE = { from: 'now-6h', @@ -130,10 +130,15 @@ export function ensureQueries(queries?: DataQuery[]): DataQuery[] { } /** - * A target is non-empty when it has keys other than refId and key. + * A target is non-empty when it has keys (with non-empty values) other than refId and key. */ export function hasNonEmptyQuery(queries: DataQuery[]): boolean { - return queries.some(query => Object.keys(query).length > 2); + return queries.some( + query => + Object.keys(query) + .map(k => query[k]) + .filter(v => v).length > 2 + ); } export function calculateResultsFromQueryTransactions( @@ -165,18 +170,16 @@ export function calculateResultsFromQueryTransactions( }; } -export function getIntervals( - range: RawTimeRange, - datasource, - resolution: number -): { interval: string; intervalMs: number } { +export function getIntervals(range: RawTimeRange, datasource: DataSourceApi, resolution: number): IntervalValues { if (!datasource || !resolution) { return { interval: '1s', intervalMs: 1000 }; } + const absoluteRange: RawTimeRange = { from: parseDate(range.from, false), to: parseDate(range.to, true), }; + return kbn.calculateInterval(absoluteRange, resolution, datasource.interval); } diff --git a/public/app/core/utils/text.test.ts b/public/app/core/utils/text.test.ts index 4f9d8367218..206e8507f9d 100644 --- a/public/app/core/utils/text.test.ts +++ b/public/app/core/utils/text.test.ts @@ -16,9 +16,20 @@ describe('findMatchesInText()', () => { expect(findMatchesInText(' foo ', 'foo')).toEqual([{ length: 3, start: 1, text: 'foo', end: 4 }]); }); - expect(findMatchesInText(' foo foo bar ', 'foo|bar')).toEqual([ - { length: 3, start: 1, text: 'foo', end: 4 }, - { length: 3, start: 5, text: 'foo', end: 8 }, - { length: 3, start: 9, text: 'bar', end: 12 }, - ]); + test('should find all matches for a complete regex', () => { + expect(findMatchesInText(' foo foo bar ', 'foo|bar')).toEqual([ + { length: 3, start: 1, text: 'foo', end: 4 }, + { length: 3, start: 5, text: 'foo', end: 8 }, + { length: 3, start: 9, text: 'bar', end: 12 }, + ]); + }); + + test('not fail on incomplete regex', () => { + expect(findMatchesInText(' foo foo bar ', 'foo|')).toEqual([ + { length: 3, start: 1, text: 'foo', end: 4 }, + { length: 3, start: 5, text: 'foo', end: 8 }, + ]); + expect(findMatchesInText('foo foo bar', '(')).toEqual([]); + expect(findMatchesInText('foo foo bar', '(foo|')).toEqual([]); + }); }); diff --git a/public/app/core/utils/text.ts b/public/app/core/utils/text.ts index 5d7591a31e2..4e948116dba 100644 --- a/public/app/core/utils/text.ts +++ b/public/app/core/utils/text.ts @@ -8,6 +8,10 @@ export function findHighlightChunksInText({ searchWords, textToHighlight }) { return findMatchesInText(textToHighlight, searchWords.join(' ')); } +const cleanNeedle = (needle: string): string => { + return needle.replace(/[[{(][\w,.-?:*+]+$/, ''); +}; + /** * Returns a list of substring regexp matches. */ @@ -16,17 +20,25 @@ export function findMatchesInText(haystack: string, needle: string): TextMatch[] if (!haystack || !needle) { return []; } - const regexp = new RegExp(`(?:${needle})`, 'g'); const matches = []; - let match = regexp.exec(haystack); - while (match) { - matches.push({ - text: match[0], - start: match.index, - length: match[0].length, - end: match.index + match[0].length, - }); - match = regexp.exec(haystack); + const cleaned = cleanNeedle(needle); + let regexp; + try { + regexp = new RegExp(`(?:${cleaned})`, 'g'); + } catch (error) { + return matches; } + haystack.replace(regexp, (substring, ...rest) => { + if (substring) { + const offset = rest[rest.length - 2]; + matches.push({ + text: substring, + start: offset, + length: substring.length, + end: offset + substring.length, + }); + } + return ''; + }); return matches; } diff --git a/public/app/features/dashboard/dashboard_model.ts b/public/app/features/dashboard/dashboard_model.ts index 3320783ec67..18a16d5c1d4 100644 --- a/public/app/features/dashboard/dashboard_model.ts +++ b/public/app/features/dashboard/dashboard_model.ts @@ -223,6 +223,8 @@ export class DashboardModel { } panelInitialized(panel: PanelModel) { + panel.initialized(); + if (!this.otherPanelInFullscreen(panel)) { panel.refresh(); } diff --git a/public/app/features/dashboard/panel_model.ts b/public/app/features/dashboard/panel_model.ts index dc8a509f2eb..737841be7e8 100644 --- a/public/app/features/dashboard/panel_model.ts +++ b/public/app/features/dashboard/panel_model.ts @@ -132,7 +132,7 @@ export class PanelModel { } } - panelInitialized() { + initialized() { this.events.emit('panel-initialized'); } diff --git a/public/app/features/datasources/state/actions.ts b/public/app/features/datasources/state/actions.ts index bb8fce8424a..50296db9031 100644 --- a/public/app/features/datasources/state/actions.ts +++ b/public/app/features/datasources/state/actions.ts @@ -148,7 +148,7 @@ export function loadDataSourceTypes(): ThunkResult { export function nameExits(dataSources, name) { return ( dataSources.filter(dataSource => { - return dataSource.name === name; + return dataSource.name.toLowerCase() === name.toLowerCase(); }).length > 0 ); } diff --git a/public/app/features/explore/Explore.tsx b/public/app/features/explore/Explore.tsx index 3e35a68bf84..4a9c67a2338 100644 --- a/public/app/features/explore/Explore.tsx +++ b/public/app/features/explore/Explore.tsx @@ -38,7 +38,7 @@ import Graph from './Graph'; import Logs from './Logs'; import Table from './Table'; import ErrorBoundary from './ErrorBoundary'; -import TimePicker from './TimePicker'; +import TimePicker, { parseTime } from './TimePicker'; interface ExploreProps { datasourceSrv: DatasourceSrv; @@ -115,7 +115,7 @@ export class Explore extends React.PureComponent { } else { const { datasource, queries, range } = props.urlState as ExploreUrlState; initialQueries = ensureQueries(queries); - const initialRange = range || { ...DEFAULT_RANGE }; + const initialRange = { from: parseTime(range.from), to: parseTime(range.to) } || { ...DEFAULT_RANGE }; // Millies step for helper bar charts const initialGraphInterval = 15 * 1000; this.state = { @@ -253,6 +253,7 @@ export class Explore extends React.PureComponent { datasourceLoading: false, datasourceName: datasource.name, initialQueries: nextQueries, + logsHighlighterExpressions: undefined, showingStartPage: Boolean(StartPage), }, () => { @@ -291,7 +292,11 @@ export class Explore extends React.PureComponent { return qt; }); - return { initialQueries: nextQueries, queryTransactions: nextQueryTransactions }; + return { + initialQueries: nextQueries, + logsHighlighterExpressions: undefined, + queryTransactions: nextQueryTransactions, + }; }); }; @@ -337,6 +342,9 @@ export class Explore extends React.PureComponent { queryTransactions: nextQueryTransactions, }; }, this.onSubmit); + } else if (this.state.datasource.getHighlighterExpression && this.modifiedQueries.length === 1) { + // Live preview of log search matches. Can only work on single row query for now + this.updateLogsHighlights(value); } }; @@ -351,6 +359,7 @@ export class Explore extends React.PureComponent { }; onClickClear = () => { + this.onStopScanning(); this.modifiedQueries = ensureQueries(); this.setState( prevState => ({ @@ -528,6 +537,7 @@ export class Explore extends React.PureComponent { return { ...results, initialQueries: nextQueries, + logsHighlighterExpressions: undefined, queryTransactions: nextQueryTransactions, }; }, @@ -644,6 +654,7 @@ export class Explore extends React.PureComponent { ...results, queryTransactions: nextQueryTransactions, showingStartPage: false, + graphInterval: queryOptions.intervalMs, }; }); @@ -664,7 +675,8 @@ export class Explore extends React.PureComponent { } this.setState(state => { - const { history, queryTransactions, scanning } = state; + const { history, queryTransactions } = state; + let { scanning } = state; // Transaction might have been discarded const transaction = queryTransactions.find(qt => qt.id === transactionId); @@ -701,15 +713,21 @@ export class Explore extends React.PureComponent { const nextHistory = updateHistory(history, datasourceId, queries); // Keep scanning for results if this was the last scanning transaction - if (_.size(result) === 0 && scanning) { - const other = nextQueryTransactions.find(qt => qt.scanning && !qt.done); - if (!other) { - this.scanTimer = setTimeout(this.scanPreviousRange, 1000); + if (scanning) { + if (_.size(result) === 0) { + const other = nextQueryTransactions.find(qt => qt.scanning && !qt.done); + if (!other) { + this.scanTimer = setTimeout(this.scanPreviousRange, 1000); + } + } else { + // We can stop scanning if we have a result + scanning = false; } } return { ...results, + scanning, history: nextHistory, queryTransactions: nextQueryTransactions, }; @@ -725,7 +743,7 @@ export class Explore extends React.PureComponent { console.error(response); - let error: string | JSX.Element = response; + let error: string | JSX.Element; if (response.data) { if (typeof response.data === 'string') { error = response.data; @@ -742,6 +760,12 @@ export class Explore extends React.PureComponent { } else { throw new Error('Could not handle error response'); } + } else if (response.message) { + error = response.message; + } else if (typeof response === 'string') { + error = response; + } else { + error = 'Unknown error during query transaction. Please check JS console logs.'; } this.setState(state => { @@ -771,6 +795,9 @@ export class Explore extends React.PureComponent { async runQueries(resultType: ResultType, queryOptions: any, resultGetter?: any) { const queries = [...this.modifiedQueries]; if (!hasNonEmptyQuery(queries)) { + this.setState({ + queryTransactions: [], + }); return; } const { datasource } = this.state; @@ -790,6 +817,17 @@ export class Explore extends React.PureComponent { }); } + updateLogsHighlights = _.debounce((value: DataQuery, index: number) => { + this.setState(state => { + const { datasource } = state; + if (datasource.getHighlighterExpression) { + const logsHighlighterExpressions = [state.datasource.getHighlighterExpression(value)]; + return { logsHighlighterExpressions }; + } + return null; + }); + }, 500); + cloneState(): ExploreState { // Copy state, but copy queries including modifications return { @@ -816,6 +854,7 @@ export class Explore extends React.PureComponent { graphResult, history, initialQueries, + logsHighlighterExpressions, logsResult, queryTransactions, range, @@ -960,6 +999,7 @@ export class Explore extends React.PureComponent { +
+
{value}
+
{count}
+
{percent}
+
+
+
+
+
+ ); +} + +const STATS_ROW_LIMIT = 5; +export class Stats extends PureComponent<{ + stats: LogsLabelStat[]; + label: string; + value: string; + rowCount: number; + onClickClose: () => void; +}> { + render() { + const { label, rowCount, stats, value, onClickClose } = this.props; + const topRows = stats.slice(0, STATS_ROW_LIMIT); + let activeRow = topRows.find(row => row.value === value); + let otherRows = stats.slice(STATS_ROW_LIMIT); + const insertActiveRow = !activeRow; + // Remove active row from other to show extra + if (insertActiveRow) { + activeRow = otherRows.find(row => row.value === value); + otherRows = otherRows.filter(row => row.value !== value); + } + const otherCount = otherRows.reduce((sum, row) => sum + row.count, 0); + const topCount = topRows.reduce((sum, row) => sum + row.count, 0); + const total = topCount + otherCount; + const otherProportion = otherCount / total; + + return ( +
+
+ + {label}: {total} of {rowCount} rows have that label + + +
+
+ {topRows.map(stat => )} + {insertActiveRow && activeRow && } + {otherCount > 0 && ( + + )} +
+
+ ); + } +} + +class Label extends PureComponent< + { + getRows?: () => LogRow[]; + label: string; + plain?: boolean; + value: string; + onClickLabel?: (label: string, value: string) => void; + }, + { showStats: boolean; stats: LogsLabelStat[] } +> { + state = { + stats: null, + showStats: false, + }; + + onClickClose = () => { + this.setState({ showStats: false }); + }; + + onClickLabel = () => { + const { onClickLabel, label, value } = this.props; + if (onClickLabel) { + onClickLabel(label, value); + } + }; + + onClickStats = () => { + this.setState(state => { + if (state.showStats) { + return { showStats: false, stats: null }; + } + const allRows = this.props.getRows(); + const stats = calculateLogsLabelStats(allRows, this.props.label); + return { showStats: true, stats }; + }); + }; + + render() { + const { getRows, label, plain, value } = this.props; + const { showStats, stats } = this.state; + const tooltip = `${label}: ${value}`; + return ( + + + {value} + + {!plain && ( + + )} + {!plain && getRows && } + {showStats && ( + + + + )} + + ); + } +} + +export default class LogLabels extends PureComponent<{ + getRows?: () => LogRow[]; + labels: LogsStreamLabels; + plain?: boolean; + onClickLabel?: (label: string, value: string) => void; +}> { + render() { + const { getRows, labels, onClickLabel, plain } = this.props; + return Object.keys(labels).map(key => ( +