Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements and fixes to the Host Overview dashboard #5340

Merged
merged 3 commits into from
Oct 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ 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]

*Packetbeat*

Expand Down Expand Up @@ -81,6 +82,7 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di
- Add system uptime metricset. {issue}[4848[4848]
- Add experimental `queue` metricset to RabbitMQ module. {pull}4788[4788]
- Add additional php-fpm pool status kpis for Metricbeat module {pull}5287[5287]
- Auto-select a hostname (based on the host on which the Beat is running) in the Host Overview dashboard. {pull}5340[5340]

*Packetbeat*

Expand Down
2 changes: 1 addition & 1 deletion libbeat/cmd/instance/beat.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions libbeat/dashboards/dashboards.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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)
}
Expand Down
17 changes: 12 additions & 5 deletions libbeat/dashboards/kibana_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -35,6 +36,7 @@ func NewKibanaLoader(cfg *common.Config, dashboardsConfig *Config, msgOutputter
client: client,
config: dashboardsConfig,
version: client.GetVersion(),
hostname: hostname,
msgOutputter: msgOutputter,
}

Expand All @@ -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)
Expand All @@ -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)
}

Expand Down
14 changes: 14 additions & 0 deletions libbeat/dashboards/modify_json.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dashboards

import (
"bytes"
"encoding/json"
"fmt"

Expand Down Expand Up @@ -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
}
54 changes: 54 additions & 0 deletions libbeat/dashboards/modify_json_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"id": "Container-CPU-usage",
"type": "visualization",
"version": 2
"version": 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do these version changes mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think they can be ignored, it seems that the version is incremented everytime you save a dashboard in Kibana, but I don't think they have a relevance beyond that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we can ignore that for now.

},
{
"attributes": {
Expand All @@ -28,7 +28,7 @@
},
"id": "System-Navigation",
"type": "visualization",
"version": 6
"version": 3
},
{
"attributes": {
Expand All @@ -43,7 +43,7 @@
},
"id": "Container-Memory-stats",
"type": "visualization",
"version": 2
"version": 1
},
{
"attributes": {
Expand All @@ -58,7 +58,7 @@
},
"id": "Container-Block-IO",
"type": "visualization",
"version": 3
"version": 1
},
{
"attributes": {
Expand All @@ -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"
}
Loading