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

Allow auto-configuration of Metricbeat stack modules for stack monitoring #17609

Merged
merged 40 commits into from
Apr 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9120a25
Add ability to reconfigure a module
ycombinator Apr 8, 2020
145ad5a
Reconfigure Logstash module with required metricsets for xpack.enabled
ycombinator Apr 8, 2020
6d0468d
Replace assert with require
ycombinator Apr 8, 2020
a974bb2
Adding CHANGELOG entry
ycombinator Apr 8, 2020
5c45893
Update default configuration files
ycombinator Apr 8, 2020
bed90d1
Auto-configure beat module metricsets when xpack.enabled = true
ycombinator Apr 8, 2020
85d2246
Refactoring common code into helper function
ycombinator Apr 8, 2020
22d0b81
Adding tests for ReConfigure() / making it part of Module interface
ycombinator Apr 8, 2020
73f6c49
Moving comments
ycombinator Apr 8, 2020
9a5d27c
Fixing infinite recursion :facepalm:
ycombinator Apr 8, 2020
1fb0c1c
Implement for kibana module
ycombinator Apr 8, 2020
aedd301
Implementing for elasticsearch module
ycombinator Apr 8, 2020
2e0a57a
Moving ReConfigure method to BaseModule from Module
ycombinator Apr 9, 2020
2b2bab7
Fixing test function name
ycombinator Apr 9, 2020
ac6ddad
Use errors.Wrapf
ycombinator Apr 9, 2020
422558b
Logging config change
ycombinator Apr 9, 2020
406f994
Adding comment about intent of use.
ycombinator Apr 9, 2020
3edc026
s/ReConfigure/Reconfigure/
ycombinator Apr 9, 2020
a2a835f
Don't pass registry
ycombinator Apr 9, 2020
fb6578e
Return copy of reconfigured module
ycombinator Apr 9, 2020
eee7a6e
Updating module docs to clarify auto-configuration
ycombinator Apr 9, 2020
86a75c2
Fixing test
ycombinator Apr 14, 2020
7f08a20
Trying out docs for `beat` module
ycombinator Apr 14, 2020
645aaec
Fixing tests
ycombinator Apr 15, 2020
ee8ef67
Uppercasing start of log message
ycombinator Apr 15, 2020
de14adf
Adding tests for ReConfigure() / making it part of Module interface
ycombinator Apr 8, 2020
e2c165f
Moving comments
ycombinator Apr 8, 2020
9003ce4
Fixing infinite recursion :facepalm:
ycombinator Apr 8, 2020
4f56434
Implement for kibana module
ycombinator Apr 8, 2020
d85376a
Implementing for elasticsearch module
ycombinator Apr 8, 2020
c137447
Moving ReConfigure method to BaseModule from Module
ycombinator Apr 9, 2020
c5806c6
Logging config change
ycombinator Apr 9, 2020
d442118
Return copy of reconfigured module
ycombinator Apr 9, 2020
7a2c2cc
Updating module docs to clarify auto-configuration
ycombinator Apr 9, 2020
22b0abe
Fixing test
ycombinator Apr 14, 2020
e2e8431
Trying out docs for `beat` module
ycombinator Apr 14, 2020
b9c5fd3
Update metricbeat/docs/modules/beat.asciidoc
ycombinator Apr 15, 2020
87a0070
Updating all stack modules' docs
ycombinator Apr 15, 2020
f21f36a
Reodering imports
ycombinator Apr 15, 2020
a0d2bb1
Fixing rebase error
ycombinator Apr 15, 2020
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
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Add test for documented fields check for metricsets without a http input. {issue}17315[17315] {pull}17334[17334]
- Add final tests and move label to GA for the azure module in metricbeat. {pull}17319[17319]
- Reference kubernetes manifests mount data directory from the host when running metricbeat as daemonset, so data persist between executions in the same node. {pull}17429[17429]
- Stack Monitoring modules now auto-configure required metricsets when `xpack.enabled: true` is set. {issue}16471[[16471] {pull}17609[17609]

*Packetbeat*

Expand Down
16 changes: 10 additions & 6 deletions metricbeat/docs/modules/beat.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ This file is generated! See scripts/mage/docs_collector.go
[[metricbeat-module-beat]]
== Beat module

The Beat module contains a minimal set of metrics to enable monitoring of any Beat or other software based on libbeat across
multiple versions. To monitor more Beat metrics, use our {stack}
{monitor-features}.

The default metricsets are `state` and `stats`.
The `beat` module collects metrics about any Beat or other software based on libbeat.

[float]
=== Compatibility

The Beat module works with Beats 7.3.0 and later.
The `beat` module works with {beats} 7.3.0 and later.

[float]
=== Usage for Stack Monitoring

The `beat` module can be used to collect metrics shown in our {stack} {monitor-features}
UI in {kib}. To enable this usage, set `xpack.enabled: true` and remove any `metricsets`
from the module's configuration. Alternatively, run `metricbeat modules disable beat` and
`metricbeat modules enable beat-xpack`.


[float]
Expand Down
20 changes: 10 additions & 10 deletions metricbeat/docs/modules/elasticsearch.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ This file is generated! See scripts/mage/docs_collector.go
[[metricbeat-module-elasticsearch]]
== Elasticsearch module

There are two modules that collect metrics about {es}:

* The Elasticsearch module contains a minimal set of metrics to enable
monitoring of Elasticsearch across multiple versions. The default metricsets in
this module are `node` and `node_stats`.
* The Elasticsearch X-Pack module enables you to monitor more Elasticsearch
metrics with our {stack} {monitor-features}. The default metricsets in this
module are `ccr`, `cluster_stats`, `enrich`, ``index`, `index_recovery`,
`index_summary`, `ml_job`, `node_stats`, and `shard`.
The `elasticsearch` module collects metrics about {es}.

[float]
=== Compatibility

The Elasticsearch module works with Elasticsearch 6.7.0 and later.
The `elasticsearch` module works with {es} 6.7.0 and later.

[float]
=== Usage for Stack Monitoring

The `elasticsearch` module can be used to collect metrics shown in our {stack} {monitor-features}
UI in {kib}. To enable this usage, set `xpack.enabled: true` and remove any `metricsets`
from the module's configuration. Alternatively, run `metricbeat modules disable elasticsearch` and
`metricbeat modules enable elasticsearch-xpack`.


[float]
Expand Down
17 changes: 10 additions & 7 deletions metricbeat/docs/modules/kibana.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ This file is generated! See scripts/mage/docs_collector.go
[[metricbeat-module-kibana]]
== Kibana module

There are two modules that collect metrics about {kib}:

* The Kibana module tracks only the high-level metrics. The default metricset in
this module is `status`.
* The Kibana X-Pack module enables you to monitor more Kibana metrics with our
{stack} {monitor-features}. The default metricset in this module is `stats`.
The `kibana` module collects metrics about {kib}.

[float]
=== Compatibility

The Kibana module works with Kibana 6.7.0 and later.
The `kibana` module works with {kib} 6.7.0 and later.

[float]
=== Usage for Stack Monitoring

The `kibana` module can be used to collect metrics shown in our {stack} {monitor-features}
UI in {kib}. To enable this usage, set `xpack.enabled: true` and remove any `metricsets`
from the module's configuration. Alternatively, run `metricbeat modules disable kibana` and
`metricbeat modules enable kibana-xpack`.


[float]
Expand Down
14 changes: 10 additions & 4 deletions metricbeat/docs/modules/logstash.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ This file is generated! See scripts/mage/docs_collector.go
[[metricbeat-module-logstash]]
== Logstash module

This is the Logstash module.

The default metricsets are `node` and `node_stats`.
The `logstash` module collects metrics about {ls}.

[float]
=== Compatibility

The Logstash module works with Logstash 7.3.0 and later.
The `logstash` module works with {ls} 7.3.0 and later.

[float]
=== Usage for Stack Monitoring

The `logstash` module can be used to collect metrics shown in our {stack} {monitor-features}
UI in {kib}. To enable this usage, set `xpack.enabled: true` and remove any `metricsets`
from the module's configuration. Alternatively, run `metricbeat modules disable logstash` and
`metricbeat modules enable logstash-xpack`.


[float]
Expand Down
41 changes: 41 additions & 0 deletions metricbeat/helper/elastic/elastic.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"fmt"
"strings"

"github.com/pkg/errors"

"github.com/elastic/beats/v7/libbeat/logp"

"github.com/elastic/beats/v7/libbeat/common"
Expand Down Expand Up @@ -127,3 +129,42 @@ func FixTimestampField(m common.MapStr, field string) error {
}
return nil
}

// NewModule returns a new Elastic stack module with the appropriate metricsets configured.
func NewModule(base *mb.BaseModule, xpackEnabledMetricsets []string, logger *logp.Logger) (*mb.BaseModule, error) {
moduleName := base.Name()

config := struct {
XPackEnabled bool `config:"xpack.enabled"`
}{}
if err := base.UnpackConfig(&config); err != nil {
return nil, errors.Wrapf(err, "could not unpack configuration for module %v", moduleName)
}

// No special configuration is needed if xpack.enabled != true
if !config.XPackEnabled {
return base, nil
}

var raw common.MapStr
if err := base.UnpackConfig(&raw); err != nil {
return nil, errors.Wrapf(err, "could not unpack configuration for module %v", moduleName)
}

// These metricsets are exactly the ones required if xpack.enabled == true
raw["metricsets"] = xpackEnabledMetricsets
jsoriano marked this conversation as resolved.
Show resolved Hide resolved

newConfig, err := common.NewConfigFrom(raw)
if err != nil {
return nil, errors.Wrapf(err, "could not create new configuration for module %v", moduleName)
}

newModule, err := base.WithConfig(*newConfig)
if err != nil {
return nil, errors.Wrapf(err, "could not reconfigure module %v", moduleName)
}

jsoriano marked this conversation as resolved.
Show resolved Hide resolved
logger.Debugf("Configuration for module %v modified because xpack.enabled was set to true", moduleName)

return newModule, nil
}
88 changes: 87 additions & 1 deletion metricbeat/helper/elastic/elastic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/logp"
"github.com/elastic/beats/v7/metricbeat/mb"
)

Expand Down Expand Up @@ -97,7 +100,7 @@ func TestFixTimestampField(t *testing.T) {
{
"converts float64s in scientific notation to ints",
map[string]interface{}{
"foo": 1.571284349E12,
"foo": 1.571284349e12,
},
map[string]interface{}{
"foo": 1571284349000,
Expand Down Expand Up @@ -140,3 +143,86 @@ func TestFixTimestampField(t *testing.T) {
})
}
}

func TestConfigureModule(t *testing.T) {
mockRegistry := mb.NewRegister()

const moduleName = "test_module"

err := mockRegistry.AddMetricSet(moduleName, "foo", mockMetricSetFactory)
require.NoError(t, err)
err = mockRegistry.AddMetricSet(moduleName, "bar", mockMetricSetFactory)
require.NoError(t, err)
err = mockRegistry.AddMetricSet(moduleName, "qux", mockMetricSetFactory)
require.NoError(t, err)
err = mockRegistry.AddMetricSet(moduleName, "baz", mockMetricSetFactory)
require.NoError(t, err)

tests := map[string]struct {
initConfig metricSetConfig
xpackEnabledMetricsets []string
newConfig metricSetConfig
}{
"no_xpack_enabled": {
metricSetConfig{
Module: moduleName,
MetricSets: []string{"foo", "bar"},
},
[]string{"baz", "qux", "foo"},
metricSetConfig{
Module: moduleName,
MetricSets: []string{"foo", "bar"},
},
},
"xpack_enabled": {
metricSetConfig{
Module: moduleName,
XPackEnabled: true,
MetricSets: []string{"foo", "bar"},
},
[]string{"baz", "qux", "foo"},
metricSetConfig{
Module: moduleName,
XPackEnabled: true,
MetricSets: []string{"baz", "qux", "foo"},
},
},
}

for name, test := range tests {
t.Run(name, func(t *testing.T) {
cfg := common.MustNewConfigFrom(test.initConfig)
m, _, err := mb.NewModule(cfg, mockRegistry)
require.NoError(t, err)

bm, ok := m.(*mb.BaseModule)
if !ok {
require.Fail(t, "expecting module to be base module")
}

newM, err := NewModule(bm, test.xpackEnabledMetricsets, logp.L())
require.NoError(t, err)

var newConfig metricSetConfig
err = newM.UnpackConfig(&newConfig)
require.NoError(t, err)
require.Equal(t, test.newConfig, newConfig)
})
}
}

type mockMetricSet struct {
mb.BaseMetricSet
}

func (m *mockMetricSet) Fetch(r mb.ReporterV2) error { return nil }

type metricSetConfig struct {
Module string `config:"module"`
MetricSets []string `config:"metricsets"`
XPackEnabled bool `config:"xpack.enabled"`
}

func mockMetricSetFactory(base mb.BaseMetricSet) (mb.MetricSet, error) {
return &mockMetricSet{base}, nil
}
36 changes: 36 additions & 0 deletions metricbeat/mb/mb.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"net/url"
"time"

"github.com/pkg/errors"

"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/logp"
"github.com/elastic/beats/v7/libbeat/monitoring"
Expand Down Expand Up @@ -94,6 +96,40 @@ func (m *BaseModule) UnpackConfig(to interface{}) error {
return m.rawConfig.Unpack(to)
}

// WithConfig re-configures the module with the given raw configuration and returns a
// copy of the module.
// Intended to be called from module factories. Note that if metricsets are specified
// in the new configuration, those metricsets must already be registered with
// mb.Registry.
func (m *BaseModule) WithConfig(config common.Config) (*BaseModule, error) {
var chkConfig struct {
Module string `config:"module"`
}
if err := config.Unpack(&chkConfig); err != nil {
return nil, errors.Wrap(err, "error parsing new module configuration")
}

// Don't allow module name change
if chkConfig.Module != "" && chkConfig.Module != m.name {
return nil, fmt.Errorf("cannot change module name from %v to %v", m.name, chkConfig.Module)
}

if err := config.SetString("module", -1, m.name); err != nil {
return nil, errors.Wrap(err, "unable to set existing module name in new configuration")
}

newBM := &BaseModule{
name: m.name,
rawConfig: &config,
}

if err := config.Unpack(&newBM.config); err != nil {
return nil, errors.Wrap(err, "error parsing new module configuration")
}

return newBM, nil
}

// MetricSet interfaces

// MetricSet is the common interface for all MetricSet implementations. In
Expand Down
Loading