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

Added 'query' parameter to metricbeats global configuration #8292

Merged
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ https://github.com/elastic/beats/compare/v6.4.0...master[Check the HEAD diff]
- Allow TCP helper to support delimiters and graphite module to accept multiple metrics in a single payload. {pull}8278[8278]
- Added 'died' PID state to process_system metricset on system module{pull}8275[8275]
- Added `ccr` metricset to Elasticsearch module. {pull}8335[8335]
- Added support for query params in configuration {pull}8286[8286]
Copy link
Member

Choose a reason for hiding this comment

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

Oh, the referenced issue here is the bug report, but the tag is for pull. You can reference any of them here, or both, but use pull for the pull request and issue for the issue. Usually the PR is always referenced and sometimes also the issue.


*Packetbeat*

Expand Down
38 changes: 36 additions & 2 deletions metricbeat/mb/mb.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ to implement Modules and their associated MetricSets.
package mb

import (
"encoding/json"
"fmt"
"net/url"
"time"

"github.com/elastic/beats/libbeat/common"
Expand Down Expand Up @@ -306,17 +308,49 @@ type ModuleConfig struct {
MetricSets []string `config:"metricsets"`
Enabled bool `config:"enabled"`
Raw bool `config:"raw"`
Query QueryParams `config:"query"`
}

func (c ModuleConfig) String() string {
return fmt.Sprintf(`{Module:"%v", MetricSets:%v, Enabled:%v, `+
`Hosts:[%v hosts], Period:"%v", Timeout:"%v", Raw:%v}`,
`Hosts:[%v hosts], Period:"%v", Timeout:"%v", Raw:%v, Query:%v}`,
c.Module, c.MetricSets, c.Enabled, len(c.Hosts), c.Period, c.Timeout,
c.Raw)
c.Raw, c.Query)
}

func (c ModuleConfig) GoString() string { return c.String() }

// QueryParams is a convenient map[string]interface{} wrapper to implement the String interface which returns the
// values in common query params format (key=value&key2=value2) which is the way that the url package expects this
// params (without the initial '?')
type QueryParams map[string]interface{}

// String returns the values in common query params format (key=value&key2=value2) which is the way that the url
// package expects this params (without the initial '?')
func (q QueryParams) String() (s string) {
u := url.Values{}

for k, v := range q {
Copy link
Contributor

Choose a reason for hiding this comment

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

You could also use url.Values for this

if values, ok := v.([]interface{}); ok {
for _, innerValue := range values {
u.Add(k, fmt.Sprintf("%v", innerValue))
}
} else {
//nil values in YAML shouldn't be stringified anyhow
if v == nil {
u.Add(k, "")
} else {
u.Add(k, fmt.Sprintf("%v", v))
sayden marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

byt, _ := json.MarshalIndent(u, "", " ")
fmt.Println(string(byt), u.Encode())
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess you want to remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OMG, yes, sorry about this.


return u.Encode()
}

// defaultModuleConfig contains the default values for ModuleConfig instances.
var defaultModuleConfig = ModuleConfig{
Enabled: true,
Expand Down
25 changes: 24 additions & 1 deletion metricbeat/mb/mb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func TestNewModulesHostParser(t *testing.T) {
r := newTestRegistry(t)

factory := func(base BaseMetricSet) (MetricSet, error) {
return &testMetricSet{base}, nil
return &testMetricSet{BaseMetricSet: base}, nil
}

hostParser := func(m Module, rawHost string) (HostData, error) {
Expand Down Expand Up @@ -375,3 +375,26 @@ func newConfig(t testing.TB, moduleConfig interface{}) *common.Config {
}
return config
}

func Test_QueryParams_String(t *testing.T) {
sayden marked this conversation as resolved.
Show resolved Hide resolved
qp := QueryParams{
"stringKey": "value",
"intKey": 10,
"floatKey": 11.5,
"boolKey": true,
"nullKey": nil,
"arKey": []interface{}{1, 2},
}

res := qp.String()

expectedValues := []string{"stringKey=value", "intKey=10", "floatKey=11.5", "boolKey=true", "nullKey=", "arKey=1", "arKey=2"}
for _, expected := range expectedValues {
assert.Contains(t, res, expected)
}

assert.NotContains(t, res, "?")
assert.NotContains(t, res, "%")
assert.NotEqual(t, "&", res[0])
assert.NotEqual(t, "&", res[len(res)-1])
}
10 changes: 10 additions & 0 deletions metricbeat/mb/parse/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ func (b URLHostParserBuilder) Build() mb.HostParser {
return mb.HostData{}, err
}

query, ok := conf["query"]
if ok {
queryMap, ok := query.(map[string]interface{})
if !ok {
return mb.HostData{}, errors.Errorf("'query' config for module %v is not a map", module.Name())
}

b.QueryParams = mb.QueryParams(queryMap).String()
}

var user, pass, path, basePath string
t, ok := conf["username"]
if ok {
Expand Down
3 changes: 3 additions & 0 deletions metricbeat/mb/parse/url_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ package parse
import (
"testing"

"github.com/elastic/beats/metricbeat/mb"

mbtest "github.com/elastic/beats/metricbeat/mb/testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -118,6 +120,7 @@ func TestURLHostParserBuilder(t *testing.T) {
{map[string]interface{}{"basepath": "foo/"}, URLHostParserBuilder{DefaultPath: "/default"}, "http://example.com/foo/default"},
{map[string]interface{}{"basepath": "/foo/"}, URLHostParserBuilder{DefaultPath: "/default"}, "http://example.com/foo/default"},
{map[string]interface{}{"basepath": "foo"}, URLHostParserBuilder{DefaultPath: "/default"}, "http://example.com/foo/default"},
{map[string]interface{}{"basepath": "foo"}, URLHostParserBuilder{DefaultPath: "/queryParams", QueryParams: mb.QueryParams{"key": "value"}.String()}, "http://example.com/foo/queryParams?key=value"},
sayden marked this conversation as resolved.
Show resolved Hide resolved
}

for _, test := range cases {
Expand Down