Skip to content

Commit f7bcd28

Browse files
Paramadonagarakan
authored andcommitted
Adding cloudwatch as destination for prometheus (#1742)
1 parent 6bbcaf5 commit f7bcd28

File tree

11 files changed

+302
-13
lines changed

11 files changed

+302
-13
lines changed

translator/tocwconfig/sampleConfig/prometheus_combined_config_linux.yaml

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
11
exporters:
2+
awscloudwatch:
3+
force_flush_interval: 1m0s
4+
max_datums_per_call: 1000
5+
max_values_per_datum: 150
6+
middleware: agenthealth/metrics
7+
namespace: CWAgent
8+
region: us-west-2
9+
resource_to_telemetry_conversion:
10+
enabled: true
211
awsemf/prometheus:
312
add_entity: false
413
certificate_file_path: ""
@@ -107,6 +116,14 @@ extensions:
107116
usage_flags:
108117
mode: EC2
109118
region_type: ACJ
119+
agenthealth/metrics:
120+
is_usage_data_enabled: true
121+
stats:
122+
operations:
123+
- PutMetricData
124+
usage_flags:
125+
mode: EC2
126+
region_type: ACJ
110127
agenthealth/statuscode:
111128
is_status_code_enabled: true
112129
is_usage_data_enabled: true
@@ -127,11 +144,23 @@ processors:
127144
send_batch_max_size: 0
128145
send_batch_size: 8192
129146
timeout: 1m0s
147+
batch/prometheus/cloudwatch:
148+
metadata_cardinality_limit: 1000
149+
send_batch_max_size: 0
150+
send_batch_size: 8192
151+
timeout: 1m0s
130152
batch/prometheus/cloudwatchlogs:
131153
metadata_cardinality_limit: 1000
132154
send_batch_max_size: 0
133155
send_batch_size: 8192
134156
timeout: 30s
157+
cumulativetodelta/prometheus/cloudwatch:
158+
exclude:
159+
match_type: ""
160+
include:
161+
match_type: ""
162+
initial_value: 2
163+
max_staleness: 0s
135164
deltatocumulative/prometheus/amp:
136165
max_stale: 336h0m0s
137166
max_streams: 9223372036854775807
@@ -213,9 +242,10 @@ receivers:
213242
use_start_time_metric: false
214243
service:
215244
extensions:
216-
- agenthealth/logs
245+
- agenthealth/metrics
217246
- agenthealth/statuscode
218247
- sigv4auth
248+
- agenthealth/logs
219249
- entitystore
220250
pipelines:
221251
metrics/prometheus/amp:
@@ -226,6 +256,14 @@ service:
226256
- deltatocumulative/prometheus/amp
227257
receivers:
228258
- prometheus
259+
metrics/prometheus/cloudwatch:
260+
exporters:
261+
- awscloudwatch
262+
processors:
263+
- batch/prometheus/cloudwatch
264+
- cumulativetodelta/prometheus/cloudwatch
265+
receivers:
266+
- prometheus
229267
metrics/prometheus/cloudwatchlogs:
230268
exporters:
231269
- awsemf/prometheus
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
global:
2+
scrape_interval: 5s
3+
scrape_timeout: 5s
4+
scrape_configs:
5+
- job_name: 'prometheus_test_job'
6+
static_configs:
7+
- targets: ['localhost:8101']
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[agent]
2+
collection_jitter = "0s"
3+
debug = false
4+
flush_interval = "1s"
5+
flush_jitter = "0s"
6+
hostname = "host_name_from_env"
7+
interval = "15s"
8+
logfile = ""
9+
logtarget = "lumberjack"
10+
metric_batch_size = 1000
11+
metric_buffer_limit = 10000
12+
omit_hostname = false
13+
precision = ""
14+
quiet = false
15+
round_interval = false
16+
17+
[outputs]
18+
19+
[[outputs.cloudwatch]]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 15
4+
},
5+
"metrics": {
6+
"namespace": "CWAgent",
7+
"metrics_destinations": {
8+
"cloudwatch": {}
9+
},
10+
"metrics_collected": {
11+
"prometheus": {
12+
"prometheus_config_path": "{prometheusFileName}"
13+
}
14+
},
15+
"append_dimensions": {
16+
"ImageId": "${aws:ImageId}",
17+
"InstanceId": "${aws:InstanceId}",
18+
"InstanceType": "${aws:InstanceType}",
19+
"AutoScalingGroupName": "${aws:AutoScalingGroupName}"
20+
},
21+
"aggregation_dimensions": [
22+
[
23+
"InstanceId",
24+
"InstanceType"
25+
]
26+
]
27+
}
28+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
exporters:
2+
awscloudwatch:
3+
force_flush_interval: 1m0s
4+
max_datums_per_call: 1000
5+
max_values_per_datum: 150
6+
middleware: agenthealth/metrics
7+
namespace: CWAgent
8+
region: us-west-2
9+
resource_to_telemetry_conversion:
10+
enabled: true
11+
rollup_dimensions:
12+
- - InstanceId
13+
- InstanceType
14+
extensions:
15+
agenthealth/metrics:
16+
is_usage_data_enabled: true
17+
stats:
18+
operations:
19+
- PutMetricData
20+
usage_flags:
21+
mode: EC2
22+
region_type: ACJ
23+
agenthealth/statuscode:
24+
is_status_code_enabled: true
25+
is_usage_data_enabled: true
26+
stats:
27+
usage_flags:
28+
mode: EC2
29+
region_type: ACJ
30+
entitystore:
31+
mode: ec2
32+
region: us-west-2
33+
processors:
34+
batch/prometheus/cloudwatch:
35+
metadata_cardinality_limit: 1000
36+
send_batch_max_size: 0
37+
send_batch_size: 8192
38+
timeout: 1m0s
39+
cumulativetodelta/prometheus/cloudwatch:
40+
exclude:
41+
match_type: ""
42+
include:
43+
match_type: ""
44+
initial_value: 2
45+
max_staleness: 0s
46+
ec2tagger:
47+
ec2_instance_tag_keys:
48+
- AutoScalingGroupName
49+
ec2_metadata_tags:
50+
- InstanceType
51+
- ImageId
52+
- InstanceId
53+
imds_retries: 1
54+
middleware: agenthealth/statuscode
55+
refresh_tags_interval: 0s
56+
refresh_volumes_interval: 0s
57+
rollup:
58+
attribute_groups:
59+
- - InstanceId
60+
- InstanceType
61+
cache_size: 1000
62+
receivers:
63+
prometheus:
64+
config:
65+
global:
66+
evaluation_interval: 1m
67+
scrape_interval: 5s
68+
scrape_protocols:
69+
- OpenMetricsText1.0.0
70+
- OpenMetricsText0.0.1
71+
- PrometheusText1.0.0
72+
- PrometheusText0.0.4
73+
scrape_timeout: 5s
74+
scrape_configs:
75+
- enable_compression: true
76+
enable_http2: true
77+
fallback_scrape_protocol: PrometheusText0.0.4
78+
follow_redirects: true
79+
honor_timestamps: true
80+
job_name: prometheus_test_job
81+
metrics_path: /metrics
82+
scheme: http
83+
scrape_interval: 5s
84+
scrape_protocols:
85+
- OpenMetricsText1.0.0
86+
- OpenMetricsText0.0.1
87+
- PrometheusText1.0.0
88+
- PrometheusText0.0.4
89+
scrape_timeout: 5s
90+
static_configs:
91+
- targets:
92+
- localhost:8101
93+
track_timestamps_staleness: false
94+
report_extra_scrape_metrics: false
95+
start_time_metric_regex: ""
96+
trim_metric_suffixes: false
97+
use_start_time_metric: false
98+
service:
99+
extensions:
100+
- agenthealth/metrics
101+
- agenthealth/statuscode
102+
- entitystore
103+
pipelines:
104+
metrics/prometheus/cloudwatch:
105+
exporters:
106+
- awscloudwatch
107+
processors:
108+
- batch/prometheus/cloudwatch
109+
- cumulativetodelta/prometheus/cloudwatch
110+
- rollup
111+
- ec2tagger
112+
receivers:
113+
- prometheus
114+
telemetry:
115+
logs:
116+
encoding: console
117+
level: info
118+
sampling:
119+
enabled: true
120+
initial: 2
121+
thereafter: 500
122+
tick: 10s
123+
metrics:
124+
level: None
125+
traces:
126+
level: None

translator/tocwconfig/tocwconfig_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ const (
5151
//go:embed sampleConfig/prometheus_config.yaml
5252
var prometheusConfig string
5353

54+
//go:embed sampleConfig/prometheus_cwa_config.yaml
55+
var prometheusPMDConfig string
56+
5457
type testCase struct {
5558
filename string
5659
targetPlatform string
@@ -439,6 +442,26 @@ func TestPrometheusConfig(t *testing.T) {
439442
checkTranslation(t, "prometheus_config_linux", "linux", expectedEnvVars, "", tokenReplacements)
440443
checkTranslation(t, "prometheus_config_windows", "windows", nil, "", tokenReplacements)
441444
}
445+
446+
func TestPrometheusPMDConfig(t *testing.T) {
447+
resetContext(t)
448+
context.CurrentContext().SetRunInContainer(true)
449+
context.CurrentContext().SetMode(config.ModeEC2)
450+
t.Setenv(config.HOST_NAME, "host_name_from_env")
451+
452+
temp := t.TempDir()
453+
prometheusConfigFileName := filepath.Join(temp, "prometheus.yaml")
454+
err := os.WriteFile(prometheusConfigFileName, []byte(prometheusPMDConfig), 0600)
455+
require.NoError(t, err)
456+
457+
tokenReplacements := map[string]string{
458+
prometheusFileNameToken: strings.ReplaceAll(prometheusConfigFileName, "\\", "\\\\"),
459+
}
460+
461+
expectedEnvVars := map[string]string{}
462+
checkTranslation(t, "prometheus_pmd_config", "linux", expectedEnvVars, "", tokenReplacements)
463+
}
464+
442465
func TestPrometheusConfigwithTargetAllocator(t *testing.T) {
443466
resetContext(t)
444467
context.CurrentContext().SetRunInContainer(true)

translator/translate/otel/pipeline/prometheus/translator.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,21 @@ package prometheus
55

66
import (
77
"fmt"
8+
"log"
89

910
"go.opentelemetry.io/collector/confmap"
1011
"go.opentelemetry.io/collector/pipeline"
1112

1213
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/common"
14+
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/exporter/awscloudwatch"
1315
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/exporter/awsemf"
1416
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/exporter/prometheusremotewrite"
1517
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/extension/agenthealth"
1618
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/extension/sigv4auth"
1719
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/batchprocessor"
20+
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/cumulativetodeltaprocessor"
1821
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/deltatocumulativeprocessor"
22+
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/ec2taggerprocessor"
1923
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/prometheusadapter"
2024
"github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/processor/rollupprocessor"
2125
otelprom "github.com/aws/amazon-cloudwatch-agent/translator/translate/otel/receiver/prometheus"
@@ -56,10 +60,38 @@ func (t *translator) Translate(conf *confmap.Conf) (*common.ComponentTranslators
5660
}
5761

5862
// return pipeline based on destination to keep source/destination combinations clearly separated
63+
// otel_prometheus - cloudwatch
5964
// telegraf_prometheus - cloudwatch
6065
// otel_prometheus - AMP
6166
// this could change in future releases to support different source/destination combinations
6267
switch t.Destination() {
68+
case common.DefaultDestination, common.CloudWatchKey:
69+
if !conf.IsSet(MetricsKey) {
70+
return nil, fmt.Errorf("pipeline (%s) is missing prometheus configuration under metrics section with destination (%s)", t.name, t.Destination())
71+
}
72+
translators := &common.ComponentTranslators{
73+
Receivers: common.NewTranslatorMap(otelprom.NewTranslator()),
74+
Processors: common.NewTranslatorMap(
75+
batchprocessor.NewTranslatorWithNameAndSection(t.name, common.MetricsKey),
76+
cumulativetodeltaprocessor.NewTranslator(common.WithName(t.name), cumulativetodeltaprocessor.WithDefaultKeys()),
77+
),
78+
Exporters: common.NewTranslatorMap(awscloudwatch.NewTranslator()),
79+
Extensions: common.NewTranslatorMap(
80+
agenthealth.NewTranslator(agenthealth.MetricsName, []string{agenthealth.OperationPutMetricData}),
81+
agenthealth.NewTranslatorWithStatusCode(agenthealth.StatusCodeName, nil, true),
82+
),
83+
}
84+
85+
if conf.IsSet(common.MetricsAggregationDimensionsKey) {
86+
translators.Processors.Set(rollupprocessor.NewTranslator())
87+
}
88+
89+
if conf.IsSet(common.ConfigKey(common.MetricsKey, common.AppendDimensionsKey)) {
90+
log.Printf("D! ec2tagger processor required because append_dimensions is set")
91+
translators.Processors.Set(ec2taggerprocessor.NewTranslator())
92+
}
93+
94+
return translators, nil
6395
case common.CloudWatchLogsKey:
6496
if !conf.IsSet(LogsKey) {
6597
return nil, fmt.Errorf("pipeline (%s) is missing prometheus configuration under logs section with destination (%s)", t.name, t.Destination())

translator/translate/otel/pipeline/prometheus/translators.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@ import (
1212

1313
func NewTranslators(conf *confmap.Conf) common.PipelineTranslatorMap {
1414
translators := common.NewTranslatorMap[*common.ComponentTranslators, pipeline.ID]()
15-
var destinations []string
15+
16+
destinations := common.GetMetricsDestinations(conf)
1617
if conf.IsSet(LogsKey) {
1718
destinations = append(destinations, common.CloudWatchLogsKey)
1819
}
19-
if conf.IsSet(MetricsKey) {
20-
destinations = append(destinations, common.AMPKey)
21-
}
2220

2321
for _, destination := range destinations {
2422
translators.Set(NewTranslator(common.WithDestination(destination)))

0 commit comments

Comments
 (0)