@@ -15,6 +15,7 @@ use aws_sdk_cloudwatch::{
15
15
use aws_smithy_types:: DateTime as AwsDateTime ;
16
16
use futures:: { FutureExt , SinkExt , stream} ;
17
17
use futures_util:: { future, future:: BoxFuture } ;
18
+ use indexmap:: IndexMap ;
18
19
use tower:: Service ;
19
20
use vector_lib:: {
20
21
ByteSizeOf , EstimatedJsonEncodedSizeOf , configurable:: configurable_component, sink:: VectorSink ,
@@ -113,6 +114,14 @@ pub struct CloudWatchMetricsSinkConfig {
113
114
skip_serializing_if = "crate::serde::is_default"
114
115
) ]
115
116
acknowledgements : AcknowledgementsConfig ,
117
+
118
+ /// A map from metric name to AWS storage resolution.
119
+ /// Valid values are 1 (high resolution) and 60 (standard resolution).
120
+ /// If unset, the AWS SDK default of 60 (standard resolution) is used.
121
+ /// See [AWS Metrics Resolution](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html#Resolution_definition)
122
+ /// See [MetricDatum::storage_resolution()](https://docs.rs/aws-sdk-cloudwatch/1.91.0/aws_sdk_cloudwatch/types/struct.MetricDatum.html#structfield.storage_resolution)
123
+ #[ serde( default ) ]
124
+ pub storage_resolution : IndexMap < String , i32 > ,
116
125
}
117
126
118
127
impl_generate_config_from_default ! ( CloudWatchMetricsSinkConfig ) ;
@@ -223,6 +232,7 @@ fn tags_to_dimensions(tags: &MetricTags) -> Vec<Dimension> {
223
232
#[ derive( Clone ) ]
224
233
pub struct CloudWatchMetricsSvc {
225
234
client : CloudwatchClient ,
235
+ storage_resolution : IndexMap < String , i32 > ,
226
236
}
227
237
228
238
impl CloudWatchMetricsSvc {
@@ -234,7 +244,10 @@ impl CloudWatchMetricsSvc {
234
244
let batch = config. batch . into_batch_settings ( ) ?;
235
245
let request_settings = config. request . into_settings ( ) ;
236
246
237
- let service = CloudWatchMetricsSvc { client } ;
247
+ let service = CloudWatchMetricsSvc {
248
+ client,
249
+ storage_resolution : config. storage_resolution ,
250
+ } ;
238
251
let buffer = PartitionBuffer :: new ( MetricsBuffer :: new ( batch. size ) ) ;
239
252
let mut normalizer = MetricNormalizer :: < AwsCloudwatchMetricNormalize > :: default ( ) ;
240
253
@@ -263,6 +276,7 @@ impl CloudWatchMetricsSvc {
263
276
}
264
277
265
278
fn encode_events ( & mut self , events : Vec < Metric > ) -> Vec < MetricDatum > {
279
+ let resolutions = & self . storage_resolution ;
266
280
events
267
281
. into_iter ( )
268
282
. filter_map ( |event| {
@@ -271,6 +285,7 @@ impl CloudWatchMetricsSvc {
271
285
. timestamp ( )
272
286
. map ( |x| AwsDateTime :: from_millis ( x. timestamp_millis ( ) ) ) ;
273
287
let dimensions = event. tags ( ) . map ( tags_to_dimensions) ;
288
+ let resolution = resolutions. get ( & metric_name) . map ( |x| * x) ;
274
289
// AwsCloudwatchMetricNormalize converts these to the right MetricKind
275
290
match event. value ( ) {
276
291
MetricValue :: Counter { value } => Some (
@@ -279,6 +294,7 @@ impl CloudWatchMetricsSvc {
279
294
. value ( * value)
280
295
. set_timestamp ( timestamp)
281
296
. set_dimensions ( dimensions)
297
+ . set_storage_resolution ( resolution)
282
298
. build ( ) ,
283
299
) ,
284
300
MetricValue :: Distribution {
@@ -291,6 +307,7 @@ impl CloudWatchMetricsSvc {
291
307
. set_counts ( Some ( samples. iter ( ) . map ( |s| s. rate as f64 ) . collect ( ) ) )
292
308
. set_timestamp ( timestamp)
293
309
. set_dimensions ( dimensions)
310
+ . set_storage_resolution ( resolution)
294
311
. build ( ) ,
295
312
) ,
296
313
MetricValue :: Set { values } => Some (
@@ -299,6 +316,7 @@ impl CloudWatchMetricsSvc {
299
316
. value ( values. len ( ) as f64 )
300
317
. set_timestamp ( timestamp)
301
318
. set_dimensions ( dimensions)
319
+ . set_storage_resolution ( resolution)
302
320
. build ( ) ,
303
321
) ,
304
322
MetricValue :: Gauge { value } => Some (
@@ -307,6 +325,7 @@ impl CloudWatchMetricsSvc {
307
325
. value ( * value)
308
326
. set_timestamp ( timestamp)
309
327
. set_dimensions ( dimensions)
328
+ . set_storage_resolution ( resolution)
310
329
. build ( ) ,
311
330
) ,
312
331
_ => None ,
0 commit comments