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

Add cumulative to delta conversion for JMX metrics. #1264

Merged
merged 1 commit into from
Jul 30, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ processors:
match_type: ""
initial_value: 0
max_staleness: 0s
cumulativetodelta/jmx:
exclude:
match_type: ""
include:
match_type: ""
initial_value: 0
max_staleness: 0s
ec2tagger:
ec2_instance_tag_keys:
- AutoScalingGroupName
Expand Down Expand Up @@ -384,6 +391,7 @@ service:
processors:
- filter/jmx/0
- resource/jmx
- cumulativetodelta/jmx
- transform/jmx/0
- ec2tagger
receivers:
Expand All @@ -394,6 +402,7 @@ service:
processors:
- filter/jmx/1
- resource/jmx
- cumulativetodelta/jmx
- transform/jmx/1
- ec2tagger
receivers:
Expand Down
8 changes: 8 additions & 0 deletions translator/tocwconfig/sampleConfig/jmx_config_linux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ extensions:
mode: EC2
region_type: ACJ
processors:
cumulativetodelta/jmx:
exclude:
match_type: ""
include:
match_type: ""
initial_value: 0
max_staleness: 0s
filter/jmx:
error_mode: propagate
logs: {}
Expand Down Expand Up @@ -106,6 +113,7 @@ service:
processors:
- filter/jmx
- resource/jmx
- cumulativetodelta/jmx
- transform/jmx
receivers:
- jmx
Expand Down
10 changes: 10 additions & 0 deletions translator/translate/otel/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,3 +392,13 @@ func GetMeasurements(m map[string]any) []string {
}
return results
}

// IsAnySet checks if any of the provided keys are present in the configuration.
func IsAnySet(conf *confmap.Conf, keys []string) bool {
for _, key := range keys {
if conf.IsSet(key) {
return true
}
}
return false
}
69 changes: 48 additions & 21 deletions translator/translate/otel/common/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestConfigKeys(t *testing.T) {
}

func TestGetString(t *testing.T) {
conf := confmap.NewFromStringMap(map[string]interface{}{"int": 10, "string": "test"})
conf := confmap.NewFromStringMap(map[string]any{"int": 10, "string": "test"})
got, ok := GetString(conf, "int")
require.True(t, ok)
// converts int to string
Expand Down Expand Up @@ -69,7 +69,7 @@ func TestGetArray(t *testing.T) {
}

func TestGetBool(t *testing.T) {
conf := confmap.NewFromStringMap(map[string]interface{}{"int": 10, "string": "test", "bool1": false, "bool2": true})
conf := confmap.NewFromStringMap(map[string]any{"int": 10, "string": "test", "bool1": false, "bool2": true})
got, ok := GetBool(conf, "int")
require.False(t, ok)
require.False(t, got)
Expand All @@ -88,7 +88,7 @@ func TestGetBool(t *testing.T) {
}

func TestGetOrDefaultBool(t *testing.T) {
conf := confmap.NewFromStringMap(map[string]interface{}{"int": 10, "string": "test", "bool1": false, "bool2": true})
conf := confmap.NewFromStringMap(map[string]any{"int": 10, "string": "test", "bool1": false, "bool2": true})
got := GetOrDefaultBool(conf, "int", false)
require.False(t, got)

Expand All @@ -106,10 +106,10 @@ func TestGetOrDefaultBool(t *testing.T) {
}

func TestGetNumber(t *testing.T) {
test := map[string]interface{}{"int": 10, "string": "test", "bool": false, "float": 1.3}
test := map[string]any{"int": 10, "string": "test", "bool": false, "float": 1.3}
marshalled, err := json.Marshal(test)
require.NoError(t, err)
var unmarshalled map[string]interface{}
var unmarshalled map[string]any
require.NoError(t, json.Unmarshal(marshalled, &unmarshalled))

conf := confmap.NewFromStringMap(unmarshalled)
Expand All @@ -131,7 +131,7 @@ func TestGetNumber(t *testing.T) {
}

func TestGetDuration(t *testing.T) {
conf := confmap.NewFromStringMap(map[string]interface{}{"invalid": "invalid", "valid": 1, "zero": 0})
conf := confmap.NewFromStringMap(map[string]any{"invalid": "invalid", "valid": 1, "zero": 0})
got, ok := GetDuration(conf, "invalid")
require.False(t, ok)
require.Equal(t, time.Duration(0), got)
Expand All @@ -145,7 +145,7 @@ func TestGetDuration(t *testing.T) {

func TestParseDuration(t *testing.T) {
testCases := map[string]struct {
input interface{}
input any
want time.Duration
wantErr bool
}{
Expand Down Expand Up @@ -201,50 +201,50 @@ func TestMissingKeyError(t *testing.T) {
func TestGetOrDefaultDuration(t *testing.T) {
sectionKeys := []string{"section::metrics_collection_interval", "backup::metrics_collection_interval"}
testCases := map[string]struct {
input map[string]interface{}
input map[string]any
want time.Duration
}{
"WithDefault": {
input: map[string]interface{}{},
input: map[string]any{},
want: time.Minute,
},
"WithZeroInterval": {
input: map[string]interface{}{
"backup": map[string]interface{}{
input: map[string]any{
"backup": map[string]any{
"metrics_collection_interval": 0,
},
"section": map[string]interface{}{
"section": map[string]any{
"metrics_collection_interval": 0,
},
},
want: time.Minute,
},
"WithoutSectionOverride": {
input: map[string]interface{}{
"backup": map[string]interface{}{
input: map[string]any{
"backup": map[string]any{
"metrics_collection_interval": 10,
},
"section": map[string]interface{}{},
"section": map[string]any{},
},
want: 10 * time.Second,
},
"WithInvalidSectionOverride": {
input: map[string]interface{}{
"backup": map[string]interface{}{
input: map[string]any{
"backup": map[string]any{
"metrics_collection_interval": 10,
},
"section": map[string]interface{}{
"section": map[string]any{
"metrics_collection_interval": "invalid",
},
},
want: 10 * time.Second,
},
"WithSectionOverride": {
input: map[string]interface{}{
"backup": map[string]interface{}{
input: map[string]any{
"backup": map[string]any{
"metrics_collection_interval": 10,
},
"section": map[string]interface{}{
"section": map[string]any{
"metrics_collection_interval": 120,
},
},
Expand Down Expand Up @@ -357,3 +357,30 @@ func TestGetMeasurements(t *testing.T) {
})
}
}

func TestIsAnySet(t *testing.T) {
conf := confmap.NewFromStringMap(map[string]any{
"one": map[string]any{
"endpoint": "test",
},
"two": map[string]any{},
})
testCases := map[string]struct {
keys []string
want bool
}{
"NotSet": {
keys: []string{"test"},
want: false,
},
"Set": {
keys: []string{"test", "one::endpoint"},
want: true,
},
}
for name, testCase := range testCases {
t.Run(name, func(t *testing.T) {
assert.Equal(t, testCase.want, IsAnySet(conf, testCase.keys))
})
}
}
30 changes: 30 additions & 0 deletions translator/translate/otel/common/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package common

type TranslatorOption func(any)

type NameSetter interface {
SetName(string)
}

func WithName(name string) TranslatorOption {
return func(target any) {
if setter, ok := target.(NameSetter); ok {
setter.SetName(name)
}
}
}

type NameProvider struct {
name string
}

func (p *NameProvider) Name() string {
return p.name
}

func (p *NameProvider) SetName(name string) {
p.name = name
}
17 changes: 17 additions & 0 deletions translator/translate/otel/common/options_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package common

import (
"testing"

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

func TestWithName(t *testing.T) {
p := &NameProvider{name: "a"}
opt := WithName("b")
opt(p)
assert.Equal(t, "b", p.Name())
}
2 changes: 1 addition & 1 deletion translator/translate/otel/pipeline/host/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (t translator) Translate(conf *confmap.Conf) (*common.ComponentTranslators,
// we need to add delta processor because (only) diskio and net input plugins report delta metric
if common.PipelineNameHostDeltaMetrics == t.name {
log.Printf("D! delta processor required because metrics with diskio or net are set")
translators.Processors.Set(cumulativetodeltaprocessor.NewTranslatorWithName(t.name))
translators.Processors.Set(cumulativetodeltaprocessor.NewTranslator(common.WithName(t.name), cumulativetodeltaprocessor.WithDiskIONetKeys()))
}

if conf.IsSet(common.ConfigKey(common.MetricsKey, common.AppendDimensionsKey)) {
Expand Down
2 changes: 2 additions & 0 deletions translator/translate/otel/pipeline/jmx/translator.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/common"
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/exporter/awscloudwatch"
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/extension/agenthealth"
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/cumulativetodeltaprocessor"
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/ec2taggerprocessor"
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/filterprocessor"
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/metricsdecorator"
Expand Down Expand Up @@ -76,6 +77,7 @@ func (t *translator) Translate(conf *confmap.Conf) (*common.ComponentTranslators
Processors: common.NewTranslatorMap(
filterprocessor.NewTranslator(filterprocessor.WithName(common.PipelineNameJmx), filterprocessor.WithIndex(t.index)),
resourceprocessor.NewTranslator(resourceprocessor.WithName(common.PipelineNameJmx)),
cumulativetodeltaprocessor.NewTranslator(common.WithName(common.PipelineNameJmx), cumulativetodeltaprocessor.WithConfigKeys(common.JmxConfigKey)),
),
Exporters: common.NewTranslatorMap(awscloudwatch.NewTranslator()),
Extensions: common.NewTranslatorMap(agenthealth.NewTranslator(component.DataTypeMetrics, []string{agenthealth.OperationPutMetricData})),
Expand Down
6 changes: 3 additions & 3 deletions translator/translate/otel/pipeline/jmx/translator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func TestTranslator(t *testing.T) {
want: &want{
pipelineID: "metrics/jmx",
receivers: []string{"jmx"},
processors: []string{"filter/jmx", "resource/jmx"},
processors: []string{"filter/jmx", "resource/jmx", "cumulativetodelta/jmx"},
exporters: []string{"awscloudwatch"},
extensions: []string{"agenthealth/metrics"},
},
Expand Down Expand Up @@ -151,7 +151,7 @@ func TestTranslator(t *testing.T) {
want: &want{
pipelineID: "metrics/jmx",
receivers: []string{"jmx"},
processors: []string{"filter/jmx", "resource/jmx", "transform/jmx"},
processors: []string{"filter/jmx", "resource/jmx", "cumulativetodelta/jmx", "transform/jmx"},
exporters: []string{"awscloudwatch"},
extensions: []string{"agenthealth/metrics"},
},
Expand Down Expand Up @@ -185,7 +185,7 @@ func TestTranslator(t *testing.T) {
want: &want{
pipelineID: "metrics/jmx/0",
receivers: []string{"jmx/0"},
processors: []string{"filter/jmx/0", "resource/jmx", "transform/jmx/0", "ec2tagger"},
processors: []string{"filter/jmx/0", "resource/jmx", "cumulativetodelta/jmx", "transform/jmx/0", "ec2tagger"},
exporters: []string{"awscloudwatch"},
extensions: []string{"agenthealth/metrics"},
},
Expand Down
Loading
Loading