From 4e253f544cdc94de9241f46224ef80a3b8a69b8f Mon Sep 17 00:00:00 2001 From: Tudor Golubenco Date: Thu, 5 Oct 2017 13:58:47 +0200 Subject: [PATCH] Improvements and fixes to the Host Overview dashboard * Use `beat.name` instead of `beat.hostname` in visualizations. See #5276 for the motivation * Add a "tip" widget that tells user how they can select another host. * Automatically set a search pattern of the form `beat.name: "HOSTNAME"` where HOSTNAME is the Beat name (hostname) that uploads the dashboards. The way the last point works is that I saved the dashbaord using this filter: `beat.name:"CHANGEME_HOSTNAME"`. The kibana loader code does a string replacement and replaces `CHANGEME_HOSTNAME` with the actual hostname. The disadvantage of this approach (vs doing JSON parsing) is that we must remember to always save that dashboard with the `CHANGEME_HOSTNAME` wildcard in place. I have added a unit test to the system module that checks for that, so it should be relatively hard for us to forget. Closes #5276. --- CHANGELOG.asciidoc | 2 + libbeat/cmd/instance/beat.go | 2 +- libbeat/dashboards/dashboards.go | 4 +- libbeat/dashboards/kibana_loader.go | 17 +++-- libbeat/dashboards/modify_json.go | 14 ++++ libbeat/dashboards/modify_json_test.go | 54 ++++++++++++++ .../Metricbeat-containers-overview.json | 12 +-- .../dashboard/Metricbeat-host-overview.json | 74 ++++++++++--------- .../dashboard/Metricbeat-system-overview.json | 34 ++++----- metricbeat/module/system/util_test.go | 16 ++++ 10 files changed, 165 insertions(+), 64 deletions(-) create mode 100644 libbeat/dashboards/modify_json_test.go diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index becbbb5e4f9..807fb459521 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -47,6 +47,8 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di *Metricbeat* - Change field type of http header from nested to object {pull}5258[5258] +- Use `beat.name` instead of `beat.hostname` in the Host Overview dashboard. {pull}5340[5340] +- Auto-select a hostname (based on the host on which the Beat is running) in the Host Overview dashboard. {pull}5340[5340] *Packetbeat* diff --git a/libbeat/cmd/instance/beat.go b/libbeat/cmd/instance/beat.go index 62671b01c62..d02a140aaf4 100644 --- a/libbeat/cmd/instance/beat.go +++ b/libbeat/cmd/instance/beat.go @@ -537,7 +537,7 @@ func (b *Beat) loadDashboards(force bool) error { if b.Config.Output.Name() == "elasticsearch" { esConfig = b.Config.Output.Config() } - err := dashboards.ImportDashboards(b.Info.Beat, b.Info.Version, paths.Resolve(paths.Home, ""), + err := dashboards.ImportDashboards(b.Info.Beat, b.Info.Name, paths.Resolve(paths.Home, ""), b.Config.Kibana, esConfig, b.Config.Dashboards, nil) if err != nil { return fmt.Errorf("Error importing Kibana dashboards: %v", err) diff --git a/libbeat/dashboards/dashboards.go b/libbeat/dashboards/dashboards.go index 080885deae1..a867212f631 100644 --- a/libbeat/dashboards/dashboards.go +++ b/libbeat/dashboards/dashboards.go @@ -10,7 +10,7 @@ import ( "github.com/elastic/beats/libbeat/logp" ) -func ImportDashboards(beatName, beatVersion, homePath string, +func ImportDashboards(beatName, hostname, homePath string, kibanaConfig *common.Config, esConfig *common.Config, dashboardsConfig *common.Config, msgOutputter MessageOutputter) error { @@ -62,7 +62,7 @@ func ImportDashboards(beatName, beatVersion, homePath string, kibanaConfig.SetString("password", -1, esLoader.client.Password) } - kibanaLoader, err := NewKibanaLoader(kibanaConfig, &dashConfig, msgOutputter) + kibanaLoader, err := NewKibanaLoader(kibanaConfig, &dashConfig, hostname, msgOutputter) if err != nil { return fmt.Errorf("fail to create the Kibana loader: %v", err) } diff --git a/libbeat/dashboards/kibana_loader.go b/libbeat/dashboards/kibana_loader.go index ba58a931b7e..065a0a8bbd8 100644 --- a/libbeat/dashboards/kibana_loader.go +++ b/libbeat/dashboards/kibana_loader.go @@ -17,10 +17,11 @@ type KibanaLoader struct { client *kibana.Client config *Config version string + hostname string msgOutputter MessageOutputter } -func NewKibanaLoader(cfg *common.Config, dashboardsConfig *Config, msgOutputter MessageOutputter) (*KibanaLoader, error) { +func NewKibanaLoader(cfg *common.Config, dashboardsConfig *Config, hostname string, msgOutputter MessageOutputter) (*KibanaLoader, error) { if cfg == nil || !cfg.Enabled() { return nil, fmt.Errorf("Kibana is not configured or enabled") @@ -35,6 +36,7 @@ func NewKibanaLoader(cfg *common.Config, dashboardsConfig *Config, msgOutputter client: client, config: dashboardsConfig, version: client.GetVersion(), + hostname: hostname, msgOutputter: msgOutputter, } @@ -50,13 +52,13 @@ func (loader KibanaLoader) ImportIndex(file string) error { // read json file reader, err := ioutil.ReadFile(file) if err != nil { - return fmt.Errorf("fail to read index-pattern: %v", err) + return fmt.Errorf("fail to read index-pattern from file %s: %v", file, err) } var indexContent common.MapStr err = json.Unmarshal(reader, &indexContent) if err != nil { - return fmt.Errorf("fail to unmarshal the index content: %v", err) + return fmt.Errorf("fail to unmarshal the index content from file %s: %v", file, err) } indexContent = ReplaceIndexInIndexPattern(loader.config.Index, indexContent) @@ -72,16 +74,21 @@ func (loader KibanaLoader) ImportDashboard(file string) error { // read json file reader, err := ioutil.ReadFile(file) if err != nil { - return fmt.Errorf("fail to read index-pattern: %v", err) + return fmt.Errorf("fail to read dashboard from file %s: %v", file, err) } var content common.MapStr err = json.Unmarshal(reader, &content) if err != nil { - return fmt.Errorf("fail to unmarshal the index content: %v", err) + return fmt.Errorf("fail to unmarshal the dashboard content from file %s: %v", file, err) } content = ReplaceIndexInDashboardObject(loader.config.Index, content) + content, err = ReplaceStringInDashboard("CHANGEME_HOSTNAME", loader.hostname, content) + if err != nil { + return fmt.Errorf("fail to replace the hostname in dashboard %s: %v", file, err) + } + return loader.client.ImportJSON(importAPI, params, content) } diff --git a/libbeat/dashboards/modify_json.go b/libbeat/dashboards/modify_json.go index 2a219bfdfeb..75c9ff15655 100644 --- a/libbeat/dashboards/modify_json.go +++ b/libbeat/dashboards/modify_json.go @@ -1,6 +1,7 @@ package dashboards import ( + "bytes" "encoding/json" "fmt" @@ -103,3 +104,16 @@ func ReplaceIndexInDashboardObject(index string, content common.MapStr) common.M } return content } + +func ReplaceStringInDashboard(old, new string, content common.MapStr) (common.MapStr, error) { + marshaled, err := json.Marshal(content) + if err != nil { + return nil, fmt.Errorf("fail to marshal dashboard object: %v", content) + } + + replaced := bytes.Replace(marshaled, []byte(old), []byte(new), -1) + + var result common.MapStr + err = json.Unmarshal(replaced, &result) + return result, nil +} diff --git a/libbeat/dashboards/modify_json_test.go b/libbeat/dashboards/modify_json_test.go new file mode 100644 index 00000000000..9e8c3dcf610 --- /dev/null +++ b/libbeat/dashboards/modify_json_test.go @@ -0,0 +1,54 @@ +package dashboards + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/elastic/beats/libbeat/common" +) + +func TestReplaceStringInDashboard(t *testing.T) { + tests := []struct { + content common.MapStr + old string + new string + expected common.MapStr + }{ + { + content: common.MapStr{"test": "CHANGEME"}, + old: "CHANGEME", + new: "hostname", + expected: common.MapStr{"test": "hostname"}, + }, + { + content: common.MapStr{"test": "hello"}, + old: "CHANGEME", + new: "hostname", + expected: common.MapStr{"test": "hello"}, + }, + { + content: common.MapStr{"test": map[string]interface{}{"key": "\"CHANGEME\""}}, + old: "CHANGEME", + new: "hostname.local", + expected: common.MapStr{"test": map[string]interface{}{"key": "\"hostname.local\""}}, + }, + { + content: common.MapStr{ + "kibanaSavedObjectMeta": map[string]interface{}{ + "searchSourceJSON": "{\"filter\":[],\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"beat.name:\\\"CHANGEME_HOSTNAME\\\"\",\"language\":\"lucene\"}}"}}, + + old: "CHANGEME_HOSTNAME", + new: "hostname.local", + expected: common.MapStr{ + "kibanaSavedObjectMeta": map[string]interface{}{ + "searchSourceJSON": "{\"filter\":[],\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"beat.name:\\\"hostname.local\\\"\",\"language\":\"lucene\"}}"}}, + }, + } + + for _, test := range tests { + result, err := ReplaceStringInDashboard(test.old, test.new, test.content) + assert.NoError(t, err) + assert.Equal(t, test.expected, result) + } +} diff --git a/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-containers-overview.json b/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-containers-overview.json index 4366bb67ef2..9d5fd650d14 100644 --- a/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-containers-overview.json +++ b/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-containers-overview.json @@ -13,7 +13,7 @@ }, "id": "Container-CPU-usage", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -28,7 +28,7 @@ }, "id": "System-Navigation", "type": "visualization", - "version": 6 + "version": 3 }, { "attributes": { @@ -43,7 +43,7 @@ }, "id": "Container-Memory-stats", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -58,7 +58,7 @@ }, "id": "Container-Block-IO", "type": "visualization", - "version": 3 + "version": 1 }, { "attributes": { @@ -76,8 +76,8 @@ }, "id": "CPU-slash-Memory-per-container", "type": "dashboard", - "version": 4 + "version": 1 } ], - "version": "6.0.0-beta1-SNAPSHOT" + "version": "6.0.0-rc1-SNAPSHOT" } \ No newline at end of file diff --git a/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-host-overview.json b/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-host-overview.json index c3fae5ecd76..c1b4558c772 100644 --- a/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-host-overview.json +++ b/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-host-overview.json @@ -13,7 +13,7 @@ }, "id": "6b7b9a40-faa1-11e6-86b1-cd7735ff7e23", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -28,7 +28,7 @@ }, "id": "4d546850-1b15-11e7-b09e-037021c4f8df", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -43,7 +43,7 @@ }, "id": "089b85d0-1b16-11e7-b09e-037021c4f8df", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -58,7 +58,7 @@ }, "id": "bfa5e400-1b16-11e7-b09e-037021c4f8df", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -73,7 +73,7 @@ }, "id": "e0f001c0-1b18-11e7-b09e-037021c4f8df", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -88,7 +88,7 @@ }, "id": "2e224660-1b19-11e7-b09e-037021c4f8df", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -103,7 +103,7 @@ }, "id": "ab2d1e90-1b1a-11e7-b09e-037021c4f8df", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -118,7 +118,7 @@ }, "id": "4e4bb1e0-1b1b-11e7-b09e-037021c4f8df", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -133,7 +133,7 @@ }, "id": "26732e20-1b91-11e7-bec4-a5e9ec5cab8b", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -148,7 +148,7 @@ }, "id": "83e12df0-1b91-11e7-bec4-a5e9ec5cab8b", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -163,7 +163,7 @@ }, "id": "d3166e80-1b91-11e7-bec4-a5e9ec5cab8b", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -178,7 +178,7 @@ }, "id": "522ee670-1b92-11e7-bec4-a5e9ec5cab8b", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -193,7 +193,7 @@ }, "id": "1aae9140-1b93-11e7-8ada-3df93aab833e", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -208,7 +208,7 @@ }, "id": "34f97ee0-1b96-11e7-8ada-3df93aab833e", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -223,7 +223,7 @@ }, "id": "System-Navigation", "type": "visualization", - "version": 6 + "version": 3 }, { "attributes": { @@ -238,7 +238,7 @@ }, "id": "19e123b0-4d5a-11e7-aee5-fdc812cc3bec", "type": "visualization", - "version": 3 + "version": 1 }, { "attributes": { @@ -268,7 +268,7 @@ }, "id": "825fdb80-4d1d-11e7-b5f2-2b7c1895bf32", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -283,7 +283,7 @@ }, "id": "96976150-4d5d-11e7-aa29-87a97a796de6", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -298,7 +298,7 @@ }, "id": "99381c80-4d60-11e7-9a4c-ed99bbcaa42b", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -313,7 +313,7 @@ }, "id": "c5e3cf90-4d60-11e7-9a4c-ed99bbcaa42b", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -328,6 +328,21 @@ }, "id": "590a60f0-5d87-11e7-8884-1bb4c3b890e4", "type": "visualization", + "version": 1 + }, + { + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{}" + }, + "title": "Tip [Metricbeat System]", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"Tip [Metricbeat System]\",\"type\":\"markdown\",\"params\":{\"fontSize\":12,\"markdown\":\"**TIP:** To select another host, go to the [System Overview](#/dashboard/Metricbeat-system-overview) dashboard and double-click a host name.\"},\"aggs\":[]}" + }, + "id": "3d65d450-a9c3-11e7-af20-67db8aecb295", + "type": "visualization", "version": 2 }, { @@ -335,26 +350,19 @@ "description": "", "hits": 0, "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"filter\":[],\"highlightAll\":true,\"version\":true,\"query\":{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"\",\"default_field\":\"*\"}},\"language\":\"lucene\"}}" + "searchSourceJSON": "{\"filter\":[],\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":\"beat.name:\\\"CHANGEME_HOSTNAME\\\"\"}}" }, "optionsJSON": "{\"darkTheme\":false}", - "panelsJSON": "[{\"col\":1,\"id\":\"6b7b9a40-faa1-11e6-86b1-cd7735ff7e23\",\"panelIndex\":1,\"row\":12,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"4d546850-1b15-11e7-b09e-037021c4f8df\",\"panelIndex\":2,\"row\":6,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"089b85d0-1b16-11e7-b09e-037021c4f8df\",\"panelIndex\":3,\"row\":12,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"bfa5e400-1b16-11e7-b09e-037021c4f8df\",\"panelIndex\":4,\"row\":9,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"e0f001c0-1b18-11e7-b09e-037021c4f8df\",\"panelIndex\":5,\"row\":15,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"2e224660-1b19-11e7-b09e-037021c4f8df\",\"panelIndex\":6,\"row\":15,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"ab2d1e90-1b1a-11e7-b09e-037021c4f8df\",\"panelIndex\":7,\"row\":6,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"4e4bb1e0-1b1b-11e7-b09e-037021c4f8df\",\"panelIndex\":8,\"row\":9,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":5,\"id\":\"26732e20-1b91-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":9,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":1,\"id\":\"83e12df0-1b91-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":10,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":3,\"id\":\"d3166e80-1b91-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":11,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":7,\"id\":\"522ee670-1b92-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":12,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":9,\"id\":\"1aae9140-1b93-11e7-8ada-3df93aab833e\",\"panelIndex\":13,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":9,\"id\":\"34f97ee0-1b96-11e7-8ada-3df93aab833e\",\"panelIndex\":14,\"row\":4,\"size_x\":4,\"size_y\":2,\"type\":\"visualization\"},{\"col\":1,\"id\":\"System-Navigation\",\"panelIndex\":16,\"row\":1,\"size_x\":12,\"size_y\":1,\"type\":\"visualization\"},{\"col\":1,\"id\":\"19e123b0-4d5a-11e7-aee5-fdc812cc3bec\",\"panelIndex\":21,\"row\":4,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":3,\"id\":\"d2e80340-4d5c-11e7-aa29-87a97a796de6\",\"panelIndex\":22,\"row\":4,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":7,\"id\":\"825fdb80-4d1d-11e7-b5f2-2b7c1895bf32\",\"panelIndex\":23,\"row\":4,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":11,\"id\":\"96976150-4d5d-11e7-aa29-87a97a796de6\",\"panelIndex\":25,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":1,\"id\":\"99381c80-4d60-11e7-9a4c-ed99bbcaa42b\",\"panelIndex\":27,\"row\":18,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"c5e3cf90-4d60-11e7-9a4c-ed99bbcaa42b\",\"panelIndex\":28,\"row\":18,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":5,\"id\":\"590a60f0-5d87-11e7-8884-1bb4c3b890e4\",\"panelIndex\":29,\"row\":4,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"}]", - "refreshInterval": { - "display": "Off", - "pause": false, - "value": 0 - }, - "timeFrom": "now-15m", - "timeRestore": true, - "timeTo": "now", + "panelsJSON": "[{\"col\":1,\"id\":\"6b7b9a40-faa1-11e6-86b1-cd7735ff7e23\",\"panelIndex\":1,\"row\":12,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"4d546850-1b15-11e7-b09e-037021c4f8df\",\"panelIndex\":2,\"row\":6,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"089b85d0-1b16-11e7-b09e-037021c4f8df\",\"panelIndex\":3,\"row\":12,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"bfa5e400-1b16-11e7-b09e-037021c4f8df\",\"panelIndex\":4,\"row\":9,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"e0f001c0-1b18-11e7-b09e-037021c4f8df\",\"panelIndex\":5,\"row\":15,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"2e224660-1b19-11e7-b09e-037021c4f8df\",\"panelIndex\":6,\"row\":15,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":1,\"id\":\"ab2d1e90-1b1a-11e7-b09e-037021c4f8df\",\"panelIndex\":7,\"row\":6,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"4e4bb1e0-1b1b-11e7-b09e-037021c4f8df\",\"panelIndex\":8,\"row\":9,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":5,\"id\":\"26732e20-1b91-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":9,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":1,\"id\":\"83e12df0-1b91-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":10,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":3,\"id\":\"d3166e80-1b91-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":11,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":7,\"id\":\"522ee670-1b92-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":12,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":9,\"id\":\"1aae9140-1b93-11e7-8ada-3df93aab833e\",\"panelIndex\":13,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":9,\"id\":\"34f97ee0-1b96-11e7-8ada-3df93aab833e\",\"panelIndex\":14,\"row\":4,\"size_x\":4,\"size_y\":2,\"type\":\"visualization\"},{\"col\":1,\"id\":\"System-Navigation\",\"panelIndex\":16,\"row\":1,\"size_x\":6,\"size_y\":1,\"type\":\"visualization\"},{\"col\":1,\"id\":\"19e123b0-4d5a-11e7-aee5-fdc812cc3bec\",\"panelIndex\":21,\"row\":4,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":3,\"id\":\"d2e80340-4d5c-11e7-aa29-87a97a796de6\",\"panelIndex\":22,\"row\":4,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":7,\"id\":\"825fdb80-4d1d-11e7-b5f2-2b7c1895bf32\",\"panelIndex\":23,\"row\":4,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":11,\"id\":\"96976150-4d5d-11e7-aa29-87a97a796de6\",\"panelIndex\":25,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":1,\"id\":\"99381c80-4d60-11e7-9a4c-ed99bbcaa42b\",\"panelIndex\":27,\"row\":18,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":7,\"id\":\"c5e3cf90-4d60-11e7-9a4c-ed99bbcaa42b\",\"panelIndex\":28,\"row\":18,\"size_x\":6,\"size_y\":3,\"type\":\"visualization\"},{\"col\":5,\"id\":\"590a60f0-5d87-11e7-8884-1bb4c3b890e4\",\"panelIndex\":29,\"row\":4,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":7,\"id\":\"3d65d450-a9c3-11e7-af20-67db8aecb295\",\"panelIndex\":30,\"row\":1,\"size_x\":6,\"size_y\":1,\"type\":\"visualization\"}]", + "timeRestore": false, "title": "[Metricbeat System] Host overview", "uiStateJSON": "{\"P-29\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}}}", "version": 1 }, "id": "79ffd6e0-faa0-11e6-947f-177f697178b8", "type": "dashboard", - "version": 3 + "version": 12 } ], - "version": "6.0.0-beta1-SNAPSHOT" -} + "version": "6.0.0-rc1-SNAPSHOT" +} \ No newline at end of file diff --git a/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-system-overview.json b/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-system-overview.json index e1f7122bf5a..aee9a29ce2c 100644 --- a/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-system-overview.json +++ b/metricbeat/module/system/_meta/kibana/default/dashboard/Metricbeat-system-overview.json @@ -13,7 +13,7 @@ }, "id": "System-Navigation", "type": "visualization", - "version": 6 + "version": 3 }, { "attributes": { @@ -28,7 +28,7 @@ }, "id": "c6f2ffd0-4d17-11e7-a196-69b9a7a020a9", "type": "visualization", - "version": 2 + "version": 1 }, { "attributes": { @@ -39,7 +39,7 @@ "title": "Top Hosts By Memory (Realtime) [Metricbeat System]", "uiStateJSON": "{}", "version": 1, - "visState": "{\"title\":\"Top Hosts By Memory (Realtime) [Metricbeat System]\",\"type\":\"metrics\",\"params\":{\"id\":\"31e5afa0-1b1c-11e7-b09e-037021c4f8df\",\"type\":\"top_n\",\"series\":[{\"id\":\"31e5afa1-1b1c-11e7-b09e-037021c4f8df\",\"color\":\"#68BC00\",\"split_mode\":\"terms\",\"metrics\":[{\"id\":\"31e5afa2-1b1c-11e7-b09e-037021c4f8df\",\"type\":\"avg\",\"field\":\"system.memory.actual.used.pct\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"percent\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"terms_field\":\"beat.hostname\",\"terms_order_by\":\"31e5afa2-1b1c-11e7-b09e-037021c4f8df\",\"terms_size\":\"10\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"bar_color_rules\":[{\"value\":0,\"id\":\"33349dd0-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(104,188,0,1)\",\"opperator\":\"gte\"},{\"value\":0.6,\"id\":\"997dc440-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(254,146,0,1)\",\"opperator\":\"gte\"},{\"value\":0.85,\"id\":\"a10d7f20-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(211,49,21,1)\",\"opperator\":\"gte\"}],\"drilldown_url\":\"../app/kibana#/dashboard/79ffd6e0-faa0-11e6-947f-177f697178b8?_a=(query:(query_string:(analyze_wildcard:!t,query:'beat.hostname:\\\"{{key}}\\\"')))\",\"filter\":\"\",\"show_grid\":1},\"aggs\":[]}" + "visState": "{\"title\":\"Top Hosts By Memory (Realtime) [Metricbeat System]\",\"type\":\"metrics\",\"params\":{\"id\":\"31e5afa0-1b1c-11e7-b09e-037021c4f8df\",\"type\":\"top_n\",\"series\":[{\"id\":\"31e5afa1-1b1c-11e7-b09e-037021c4f8df\",\"color\":\"#68BC00\",\"split_mode\":\"terms\",\"metrics\":[{\"id\":\"31e5afa2-1b1c-11e7-b09e-037021c4f8df\",\"type\":\"avg\",\"field\":\"system.memory.actual.used.pct\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"percent\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"terms_field\":\"beat.name\",\"terms_order_by\":\"31e5afa2-1b1c-11e7-b09e-037021c4f8df\",\"terms_size\":\"10\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"bar_color_rules\":[{\"value\":0,\"id\":\"33349dd0-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(104,188,0,1)\",\"opperator\":\"gte\"},{\"value\":0.6,\"id\":\"997dc440-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(254,146,0,1)\",\"opperator\":\"gte\"},{\"value\":0.85,\"id\":\"a10d7f20-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(211,49,21,1)\",\"opperator\":\"gte\"}],\"drilldown_url\":\"../app/kibana#/dashboard/79ffd6e0-faa0-11e6-947f-177f697178b8?_a=(query:(query_string:(analyze_wildcard:!t,query:'beat.hostname:\\\"{{key}}\\\"')))\",\"filter\":\"\",\"show_grid\":1},\"aggs\":[]}" }, "id": "fe064790-1b1f-11e7-bec4-a5e9ec5cab8b", "type": "visualization", @@ -49,12 +49,12 @@ "attributes": { "description": "", "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\n \"query\": {\n \"query_string\": {\n \"query\": \"*\"\n }\n },\n \"filter\": []\n}" + "searchSourceJSON": "{\"query\":{\"query\":{\"query_string\":{\"query\":\"*\"}},\"language\":\"lucene\"},\"filter\":[]}" }, "title": "Top Hosts By CPU (Realtime) [Metricbeat System]", "uiStateJSON": "{}", "version": 1, - "visState": "{\n \"title\": \"Top Hosts By CPU (Realtime)\",\n \"type\": \"metrics\",\n \"params\": {\n \"id\": \"31e5afa0-1b1c-11e7-b09e-037021c4f8df\",\n \"type\": \"top_n\",\n \"series\": [\n {\n \"id\": \"31e5afa1-1b1c-11e7-b09e-037021c4f8df\",\n \"color\": \"#68BC00\",\n \"split_mode\": \"terms\",\n \"metrics\": [\n {\n \"id\": \"31e5afa2-1b1c-11e7-b09e-037021c4f8df\",\n \"type\": \"avg\",\n \"field\": \"system.cpu.user.pct\"\n }\n ],\n \"seperate_axis\": 0,\n \"axis_position\": \"right\",\n \"formatter\": \"percent\",\n \"chart_type\": \"line\",\n \"line_width\": 1,\n \"point_size\": 1,\n \"fill\": 0.5,\n \"stacked\": \"none\",\n \"terms_field\": \"beat.hostname\",\n \"terms_order_by\": \"31e5afa2-1b1c-11e7-b09e-037021c4f8df\",\n \"terms_size\": \"10\"\n }\n ],\n \"time_field\": \"@timestamp\",\n \"index_pattern\": \"*\",\n \"interval\": \"auto\",\n \"axis_position\": \"left\",\n \"axis_formatter\": \"number\",\n \"show_legend\": 1,\n \"bar_color_rules\": [\n {\n \"value\": 0,\n \"id\": \"33349dd0-1b1c-11e7-b09e-037021c4f8df\",\n \"bar_color\": \"rgba(104,188,0,1)\",\n \"opperator\": \"gte\"\n },\n {\n \"value\": 0.6,\n \"id\": \"997dc440-1b1c-11e7-b09e-037021c4f8df\",\n \"bar_color\": \"rgba(254,146,0,1)\",\n \"opperator\": \"gte\"\n },\n {\n \"value\": 0.85,\n \"id\": \"a10d7f20-1b1c-11e7-b09e-037021c4f8df\",\n \"bar_color\": \"rgba(211,49,21,1)\",\n \"opperator\": \"gte\"\n }\n ],\n \"drilldown_url\": \"../app/kibana#/dashboard/79ffd6e0-faa0-11e6-947f-177f697178b8?_a=(query:(query_string:(analyze_wildcard:!t,query:'beat.hostname:\\\"{{key}}\\\"')))\",\n \"filter\": \"\"\n },\n \"aggs\": [],\n \"listeners\": {}\n}" + "visState": "{\"title\":\"Top Hosts By CPU (Realtime) [Metricbeat System]\",\"type\":\"metrics\",\"params\":{\"id\":\"31e5afa0-1b1c-11e7-b09e-037021c4f8df\",\"type\":\"top_n\",\"series\":[{\"id\":\"31e5afa1-1b1c-11e7-b09e-037021c4f8df\",\"color\":\"#68BC00\",\"split_mode\":\"terms\",\"metrics\":[{\"id\":\"31e5afa2-1b1c-11e7-b09e-037021c4f8df\",\"type\":\"avg\",\"field\":\"system.cpu.user.pct\"}],\"seperate_axis\":0,\"axis_position\":\"right\",\"formatter\":\"percent\",\"chart_type\":\"line\",\"line_width\":1,\"point_size\":1,\"fill\":0.5,\"stacked\":\"none\",\"terms_field\":\"beat.name\",\"terms_order_by\":\"31e5afa2-1b1c-11e7-b09e-037021c4f8df\",\"terms_size\":\"10\"}],\"time_field\":\"@timestamp\",\"index_pattern\":\"*\",\"interval\":\"auto\",\"axis_position\":\"left\",\"axis_formatter\":\"number\",\"show_legend\":1,\"bar_color_rules\":[{\"value\":0,\"id\":\"33349dd0-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(104,188,0,1)\",\"opperator\":\"gte\"},{\"value\":0.6,\"id\":\"997dc440-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(254,146,0,1)\",\"opperator\":\"gte\"},{\"value\":0.85,\"id\":\"a10d7f20-1b1c-11e7-b09e-037021c4f8df\",\"bar_color\":\"rgba(211,49,21,1)\",\"opperator\":\"gte\"}],\"drilldown_url\":\"../app/kibana#/dashboard/79ffd6e0-faa0-11e6-947f-177f697178b8?_a=(query:(query_string:(analyze_wildcard:!t,query:'beat.hostname:\\\"{{key}}\\\"')))\",\"filter\":\"\",\"show_grid\":1},\"aggs\":[]}" }, "id": "855899e0-1b1c-11e7-b09e-037021c4f8df", "type": "visualization", @@ -67,9 +67,9 @@ "searchSourceJSON": "{\"index\":\"metricbeat-*\",\"query\":{\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true,\"default_field\":\"*\"}},\"language\":\"lucene\"},\"filter\":[]}" }, "title": "Hosts histogram by CPU usage [Metricbeat System]", - "uiStateJSON": "{\"vis\":{\"defaultColors\":{\"0% - 5%\":\"rgb(247,252,245)\",\"5% - 10%\":\"rgb(199,233,192)\",\"10% - 15%\":\"rgb(116,196,118)\",\"15% - 20%\":\"rgb(35,139,69)\"}}}", + "uiStateJSON": "{\"vis\":{\"defaultColors\":{\"0% - 20%\":\"rgb(247,252,245)\",\"20% - 40%\":\"rgb(199,233,192)\",\"40% - 60%\":\"rgb(116,196,118)\",\"60% - 80%\":\"rgb(35,139,69)\"}}}", "version": 1, - "visState": "{\"title\":\"Hosts histogram by CPU usage [Metricbeat System]\",\"type\":\"heatmap\",\"params\":{\"addTooltip\":true,\"addLegend\":true,\"enableHover\":false,\"legendPosition\":\"right\",\"times\":[],\"colorsNumber\":4,\"colorSchema\":\"Greens\",\"setColorRange\":false,\"colorsRange\":[],\"invertColors\":false,\"percentageMode\":false,\"valueAxes\":[{\"show\":false,\"id\":\"ValueAxis-1\",\"type\":\"value\",\"scale\":{\"type\":\"linear\",\"defaultYExtents\":false},\"labels\":{\"show\":false,\"rotate\":0,\"color\":\"#555\"}}],\"type\":\"heatmap\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"system.cpu.user.pct\",\"customLabel\":\"CPU usage\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"beat.hostname\",\"size\":20,\"order\":\"desc\",\"orderBy\":\"1\",\"customLabel\":\"Hosts\"}}]}" + "visState": "{\"title\":\"Hosts histogram by CPU usage [Metricbeat System]\",\"type\":\"heatmap\",\"params\":{\"addTooltip\":true,\"addLegend\":true,\"enableHover\":false,\"legendPosition\":\"right\",\"times\":[],\"colorsNumber\":4,\"colorSchema\":\"Greens\",\"setColorRange\":false,\"colorsRange\":[],\"invertColors\":false,\"percentageMode\":false,\"valueAxes\":[{\"show\":false,\"id\":\"ValueAxis-1\",\"type\":\"value\",\"scale\":{\"type\":\"linear\",\"defaultYExtents\":false},\"labels\":{\"show\":false,\"rotate\":0,\"color\":\"#555\"}}],\"type\":\"heatmap\"},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"avg\",\"schema\":\"metric\",\"params\":{\"field\":\"system.cpu.user.pct\",\"customLabel\":\"CPU usage\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"@timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"beat.name\",\"size\":20,\"order\":\"desc\",\"orderBy\":\"1\",\"customLabel\":\"Hosts\"}}]}" }, "id": "7cdb1330-4d1a-11e7-a196-69b9a7a020a9", "type": "visualization", @@ -88,7 +88,7 @@ }, "id": "522ee670-1b92-11e7-bec4-a5e9ec5cab8b", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -103,7 +103,7 @@ }, "id": "1aae9140-1b93-11e7-8ada-3df93aab833e", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -118,7 +118,7 @@ }, "id": "825fdb80-4d1d-11e7-b5f2-2b7c1895bf32", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -133,7 +133,7 @@ }, "id": "d3166e80-1b91-11e7-bec4-a5e9ec5cab8b", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { @@ -148,26 +148,26 @@ }, "id": "83e12df0-1b91-11e7-bec4-a5e9ec5cab8b", "type": "visualization", - "version": 3 + "version": 2 }, { "attributes": { "description": "", "hits": 0, "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"filter\":[],\"highlightAll\":true,\"version\":true,\"query\":{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\",\"default_field\":\"*\"}},\"language\":\"lucene\"}}" + "searchSourceJSON": "{\"filter\":[],\"highlightAll\":true,\"version\":true,\"query\":{\"language\":\"lucene\",\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"default_field\":\"*\",\"query\":\"*\"}}}}" }, "optionsJSON": "{\"darkTheme\":false}", "panelsJSON": "[{\"col\":1,\"id\":\"System-Navigation\",\"panelIndex\":9,\"row\":1,\"size_x\":12,\"size_y\":1,\"type\":\"visualization\"},{\"col\":1,\"id\":\"c6f2ffd0-4d17-11e7-a196-69b9a7a020a9\",\"panelIndex\":11,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":7,\"id\":\"fe064790-1b1f-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":12,\"row\":4,\"size_x\":6,\"size_y\":5,\"type\":\"visualization\"},{\"col\":1,\"id\":\"855899e0-1b1c-11e7-b09e-037021c4f8df\",\"panelIndex\":13,\"row\":4,\"size_x\":6,\"size_y\":5,\"type\":\"visualization\"},{\"col\":1,\"id\":\"7cdb1330-4d1a-11e7-a196-69b9a7a020a9\",\"panelIndex\":14,\"row\":9,\"size_x\":12,\"size_y\":6,\"type\":\"visualization\"},{\"col\":9,\"id\":\"522ee670-1b92-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":16,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":11,\"id\":\"1aae9140-1b93-11e7-8ada-3df93aab833e\",\"panelIndex\":17,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":7,\"id\":\"825fdb80-4d1d-11e7-b5f2-2b7c1895bf32\",\"panelIndex\":18,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":5,\"id\":\"d3166e80-1b91-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":19,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"},{\"col\":3,\"id\":\"83e12df0-1b91-11e7-bec4-a5e9ec5cab8b\",\"panelIndex\":20,\"row\":2,\"size_x\":2,\"size_y\":2,\"type\":\"visualization\"}]", "timeRestore": false, "title": "[Metricbeat System] Overview", - "uiStateJSON": "{\"P-11\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-12\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-14\":{\"vis\":{\"defaultColors\":{\"0% - 8.75%\":\"rgb(247,252,245)\",\"17.5% - 26.25%\":\"rgb(116,196,118)\",\"26.25% - 35%\":\"rgb(35,139,69)\",\"8.75% - 17.5%\":\"rgb(199,233,192)\"}}},\"P-16\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-2\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-3\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}}}", + "uiStateJSON": "{\"P-11\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-12\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-14\":{\"vis\":{\"defaultColors\":{\"0% - 20%\":\"rgb(247,252,245)\",\"20% - 40%\":\"rgb(199,233,192)\",\"40% - 60%\":\"rgb(116,196,118)\",\"60% - 80%\":\"rgb(35,139,69)\"}}},\"P-16\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-2\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}},\"P-3\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}}}", "version": 1 }, "id": "Metricbeat-system-overview", "type": "dashboard", - "version": 3 + "version": 2 } ], - "version": "6.0.0-beta1-SNAPSHOT" -} + "version": "6.0.0-rc1-SNAPSHOT" +} \ No newline at end of file diff --git a/metricbeat/module/system/util_test.go b/metricbeat/module/system/util_test.go index 41cf5ff86f3..7d73e36918e 100644 --- a/metricbeat/module/system/util_test.go +++ b/metricbeat/module/system/util_test.go @@ -4,6 +4,8 @@ package system import ( + "bytes" + "io/ioutil" "runtime" "testing" @@ -131,3 +133,17 @@ func TestRound(t *testing.T) { assert.EqualValues(t, 1234.5, Round(1234.50004)) assert.EqualValues(t, 1234.5001, Round(1234.50005)) } + +// Checks that the Host Overview dashboard contains the CHANGEME_HOSTNAME variable +// that the dashboard loader code magically changes to the hostname on which the Beat +// is running. +func TestHostDashboardHasChangeableHost(t *testing.T) { + dashPath := "_meta/kibana/default/dashboard/Metricbeat-host-overview.json" + contents, err := ioutil.ReadFile(dashPath) + if err != nil { + t.Fatalf("Error reading file %s: %v", dashPath, err) + } + if !bytes.Contains(contents, []byte("CHANGEME_HOSTNAME")) { + t.Errorf("Dashboard '%s' doesn't contain string 'CHANGEME_HOSTNAME'. See elastic/beats#5340", dashPath) + } +}