Jolokia2 handles unordered mbean object name properties (#3504)
This commit is contained in:
parent
fb1edd5da3
commit
d9e2599de7
|
@ -127,8 +127,7 @@ func mergeTags(metricTags, outerTags map[string]string) map[string]string {
|
||||||
// of a Metric match the corresponding elements in a ReadResponse object
|
// of a Metric match the corresponding elements in a ReadResponse object
|
||||||
// returned by a Jolokia agent.
|
// returned by a Jolokia agent.
|
||||||
func metricMatchesResponse(metric Metric, response ReadResponse) bool {
|
func metricMatchesResponse(metric Metric, response ReadResponse) bool {
|
||||||
|
if !metric.MatchObjectName(response.RequestMbean) {
|
||||||
if metric.Mbean != response.RequestMbean {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,21 +135,11 @@ func metricMatchesResponse(metric Metric, response ReadResponse) bool {
|
||||||
return len(response.RequestAttributes) == 0
|
return len(response.RequestAttributes) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fullPath := range metric.Paths {
|
for _, attribute := range response.RequestAttributes {
|
||||||
segments := strings.SplitN(fullPath, "/", 2)
|
if metric.MatchAttributeAndPath(attribute, response.RequestPath) {
|
||||||
attribute := segments[0]
|
|
||||||
|
|
||||||
var path string
|
|
||||||
if len(segments) == 2 {
|
|
||||||
path = segments[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rattr := range response.RequestAttributes {
|
|
||||||
if attribute == rattr && path == response.RequestPath {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,6 +481,114 @@ func TestJolokia2_FieldRenaming(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestJolokia2_MetricMbeanMatching(t *testing.T) {
|
||||||
|
config := `
|
||||||
|
[jolokia2_agent]
|
||||||
|
urls = ["%s"]
|
||||||
|
|
||||||
|
[[jolokia2_agent.metric]]
|
||||||
|
name = "mbean_name_and_object_keys"
|
||||||
|
mbean = "test1:foo=bar,fizz=buzz"
|
||||||
|
|
||||||
|
[[jolokia2_agent.metric]]
|
||||||
|
name = "mbean_name_and_unordered_object_keys"
|
||||||
|
mbean = "test2:fizz=buzz,foo=bar"
|
||||||
|
|
||||||
|
[[jolokia2_agent.metric]]
|
||||||
|
name = "mbean_name_and_attributes"
|
||||||
|
mbean = "test3"
|
||||||
|
paths = ["foo", "bar"]
|
||||||
|
|
||||||
|
[[jolokia2_agent.metric]]
|
||||||
|
name = "mbean_name_and_attribute_with_paths"
|
||||||
|
mbean = "test4"
|
||||||
|
paths = ["flavor/chocolate", "flavor/strawberry"]
|
||||||
|
`
|
||||||
|
|
||||||
|
response := `[{
|
||||||
|
"request": {
|
||||||
|
"mbean": "test1:foo=bar,fizz=buzz",
|
||||||
|
"type": "read"
|
||||||
|
},
|
||||||
|
"value": 123,
|
||||||
|
"status": 200
|
||||||
|
}, {
|
||||||
|
"request": {
|
||||||
|
"mbean": "test2:foo=bar,fizz=buzz",
|
||||||
|
"type": "read"
|
||||||
|
},
|
||||||
|
"value": 123,
|
||||||
|
"status": 200
|
||||||
|
}, {
|
||||||
|
"request": {
|
||||||
|
"mbean": "test3",
|
||||||
|
"attribute": "foo",
|
||||||
|
"type": "read"
|
||||||
|
},
|
||||||
|
"value": 123,
|
||||||
|
"status": 200
|
||||||
|
}, {
|
||||||
|
"request": {
|
||||||
|
"mbean": "test3",
|
||||||
|
"attribute": "bar",
|
||||||
|
"type": "read"
|
||||||
|
},
|
||||||
|
"value": 456,
|
||||||
|
"status": 200
|
||||||
|
}, {
|
||||||
|
"request": {
|
||||||
|
"mbean": "test4",
|
||||||
|
"attribute": "flavor",
|
||||||
|
"path": "chocolate",
|
||||||
|
"type": "read"
|
||||||
|
},
|
||||||
|
"value": 123,
|
||||||
|
"status": 200
|
||||||
|
}, {
|
||||||
|
"request": {
|
||||||
|
"mbean": "test4",
|
||||||
|
"attribute": "flavor",
|
||||||
|
"path": "strawberry",
|
||||||
|
"type": "read"
|
||||||
|
},
|
||||||
|
"value": 456,
|
||||||
|
"status": 200
|
||||||
|
}]`
|
||||||
|
|
||||||
|
server := setupServer(http.StatusOK, response)
|
||||||
|
defer server.Close()
|
||||||
|
plugin := setupPlugin(t, fmt.Sprintf(config, server.URL))
|
||||||
|
|
||||||
|
var acc testutil.Accumulator
|
||||||
|
assert.NoError(t, plugin.Gather(&acc))
|
||||||
|
|
||||||
|
acc.AssertContainsTaggedFields(t, "mbean_name_and_object_keys", map[string]interface{}{
|
||||||
|
"value": 123.0,
|
||||||
|
}, map[string]string{
|
||||||
|
"jolokia_agent_url": server.URL,
|
||||||
|
})
|
||||||
|
|
||||||
|
acc.AssertContainsTaggedFields(t, "mbean_name_and_unordered_object_keys", map[string]interface{}{
|
||||||
|
"value": 123.0,
|
||||||
|
}, map[string]string{
|
||||||
|
"jolokia_agent_url": server.URL,
|
||||||
|
})
|
||||||
|
|
||||||
|
acc.AssertContainsTaggedFields(t, "mbean_name_and_attributes", map[string]interface{}{
|
||||||
|
"foo": 123.0,
|
||||||
|
"bar": 456.0,
|
||||||
|
}, map[string]string{
|
||||||
|
"jolokia_agent_url": server.URL,
|
||||||
|
})
|
||||||
|
|
||||||
|
acc.AssertContainsTaggedFields(t, "mbean_name_and_attribute_with_paths", map[string]interface{}{
|
||||||
|
"flavor.chocolate": 123.0,
|
||||||
|
"flavor.strawberry": 456.0,
|
||||||
|
}, map[string]string{
|
||||||
|
"jolokia_agent_url": server.URL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestJolokia2_MetricCompaction(t *testing.T) {
|
func TestJolokia2_MetricCompaction(t *testing.T) {
|
||||||
config := `
|
config := `
|
||||||
[jolokia2_agent]
|
[jolokia2_agent]
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package jolokia2
|
package jolokia2
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
// A MetricConfig represents a TOML form of
|
// A MetricConfig represents a TOML form of
|
||||||
// a Metric with some optional fields.
|
// a Metric with some optional fields.
|
||||||
type MetricConfig struct {
|
type MetricConfig struct {
|
||||||
|
@ -25,6 +27,9 @@ type Metric struct {
|
||||||
FieldSeparator string
|
FieldSeparator string
|
||||||
TagPrefix string
|
TagPrefix string
|
||||||
TagKeys []string
|
TagKeys []string
|
||||||
|
|
||||||
|
mbeanDomain string
|
||||||
|
mbeanProperties []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMetric(config MetricConfig, defaultFieldPrefix, defaultFieldSeparator, defaultTagPrefix string) Metric {
|
func NewMetric(config MetricConfig, defaultFieldPrefix, defaultFieldSeparator, defaultTagPrefix string) Metric {
|
||||||
|
@ -57,5 +62,67 @@ func NewMetric(config MetricConfig, defaultFieldPrefix, defaultFieldSeparator, d
|
||||||
metric.TagPrefix = *config.TagPrefix
|
metric.TagPrefix = *config.TagPrefix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mbeanDomain, mbeanProperties := parseMbeanObjectName(config.Mbean)
|
||||||
|
metric.mbeanDomain = mbeanDomain
|
||||||
|
metric.mbeanProperties = mbeanProperties
|
||||||
|
|
||||||
return metric
|
return metric
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m Metric) MatchObjectName(name string) bool {
|
||||||
|
if name == m.Mbean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
mbeanDomain, mbeanProperties := parseMbeanObjectName(name)
|
||||||
|
if mbeanDomain != m.mbeanDomain {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(mbeanProperties) != len(m.mbeanProperties) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
NEXT_PROPERTY:
|
||||||
|
for _, mbeanProperty := range m.mbeanProperties {
|
||||||
|
for i := range mbeanProperties {
|
||||||
|
if mbeanProperties[i] == mbeanProperty {
|
||||||
|
continue NEXT_PROPERTY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Metric) MatchAttributeAndPath(attribute, innerPath string) bool {
|
||||||
|
path := attribute
|
||||||
|
if innerPath != "" {
|
||||||
|
path = path + "/" + innerPath
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range m.Paths {
|
||||||
|
if path == m.Paths[i] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseMbeanObjectName(name string) (string, []string) {
|
||||||
|
index := strings.Index(name, ":")
|
||||||
|
if index == -1 {
|
||||||
|
return name, []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
domain := name[:index]
|
||||||
|
|
||||||
|
if index+1 > len(name) {
|
||||||
|
return domain, []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return domain, strings.Split(name[index+1:], ",")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue