-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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 support for 1-second Storage Resolution in the AWS EMF Exporter #36057
base: main
Are you sure you want to change the base?
Conversation
…porter This change implements the capability for users of the AWS EMF Exporter to specify which metrics they would like to have sent to CloudWatch with a 1 second Storage Resolution. The EMF Exporter now explicitly states the Storage Resolution for each metric as 60 seconds, the previous implicit default, so there is no behavior change. If the user specifies a metric to have 1 second resolution it will be sent to CloudWatch EMF with the Storage Resolution set accordingly. Previously the AWS EMF Exporter sent metric data into CloudWatch without specifying the storage resolution. CloudWatch would then default to a 60 second storage resolution, even if metrics are sent more frequently than every 60 seconds. This would confuse users when they try to apply functions like AVG, SUM, MAX, or MIN to their metrics with a period of 5 seconds. The function would be applied by CloudWatch to 60 seconds worth of data and produced unexpected results and confusion for the user. This commit makes this 60 second resolution explicit in the messages sent to CloudWatch by the EMF Exporter and also gives the user the option to specify a more granular 1 second resolution per metric in the configuration file of the AWS EMF Exporter.
exporter/awsemfexporter/config.go
Outdated
// Set the storage resolution for this metric in AWS Embedded Metric Format (EMF). Valid values are 1 (for 1 second resolution) and 60 (for 60 second resolution). | ||
StorageResolution int `mapstructure:"storage_resolution"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The MetricDescriptor
configuration is extremely limited and can be accomplished through generally-applicable processors. I think it should be deprecated and slated for removal at some point in the future so we should not expand its surface area any further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latest update instead looks for a metric attribute named aws.emf.storage_resolution
which can be applied either in the application's code or using the Attribute Processor in the collector itself.
@@ -48,7 +48,7 @@ type cWMetrics struct { | |||
type cWMeasurement struct { | |||
Namespace string | |||
Dimensions [][]string | |||
Metrics []map[string]string | |||
Metrics []map[string]any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the use of any
here. Use the type system to prevent invalid data from being represented. If that means a new type needs to be created then a new type will need to be created. Rather than []map[string]any
this should be something like []metricDefinition
with metricDefinition
defined like this:
type metricDefinition struct {
Name string
Unit string
StorageResolution int
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latest update creates a cWMetricInfo
struct in the translator to mimic the metricInfo
struct in grouped_metric.go, replacing the use of map[string]any
in the translator.
04304bc
to
8dc339a
Compare
This commit addresses comments in PR#36057 where it was suggested that metric description for the EMF Exporter should be deprecated and metric attributes used to specify the storage resolution for each metric. The code has been modified to remove the original changes and instead have the exporter look for a metric attribute named `aws.emf.storage_resolution` and use its value for the storage resolution when sending a message to CloudWatch EMF. The code has also added a new struct `cWMetricInfo` to hold the metric name, unit, and storage resolution where previously this was a `[]map[string]string` type. removed unnecessary changes
8dc339a
to
a29de76
Compare
@Aneurysm9 are you able to approve the change in its current form which now uses metric attributes to define storage resolution? |
|
||
fmt.Printf("##--## Dim Set: %+v\n", dimSet) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the debug logs
emfAttributeFilterRE := regexp.MustCompile(emfAttributeFilter) | ||
for labelName := range labels { | ||
if !emfAttributeFilterRE.MatchString(labelName) { | ||
filteredLabels[labelName] = labels[labelName] | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about the performance impact of applying regex matching on every metric attribute for each grouped metric data point.
Is there any requirement to add more aws.emf.*
attribute patterns? Could you perform an exact match for labelname == "aws.emf.storage_resolution"
and break the loop once it's found?
dimensions := [][]string{dimSet} | ||
|
||
fmt.Printf("##--## Dimensions: %+v", dimensions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
@@ -228,14 +246,22 @@ func groupedMetricToCWMeasurement(groupedMetric *groupedMetric, config *Config) | |||
// Add on rolled-up dimensions | |||
dimensions = append(dimensions, rollupDimensionArray...) | |||
|
|||
metrics := make([]map[string]string, len(groupedMetric.metrics)) | |||
fmt.Printf("##--## Post Dimensions: %+v", dimensions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
|
||
// metric attributes for AWS EMF, not to be treated as metric labels | ||
// emfAttributeFilterRE = regexp.MustCompile("^awsemf.[A-Za-z_]*$") | ||
emfAttributeFilter = "^awsemf.[A-Za-z_]*$" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
q: why regex rule is ^awsemf.[A-Za-z_]*$
instead of ^aws.emf.[A-Za-z_]*$
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @mxiamxia - I've swapped the more complex regex for a simpler comparison operator. As new metric attributes are added this can be expanded to a switch statement which will likely still perform better than a compiled regex.
…erformant comparison operator
…ution' into awsemf_storageresolution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. ty!
@andrzej-stencel good morning, are you able to review this pull request please? |
@jpbarto this probably deserves a changelog entry? Can you add one please https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md#changelog. |
@andrzej-stencel the changelog has been updated as requested. |
@andrzej-stencel @mxiamxia the PR requires a second reviewer to approve the pull request. This is currently assigned to @bryan-aguilar. Bryan was involved with the original issue raised last year and has been idle on GitHub since June of this year. Can I please ask that this PR be assigned to an alternate reviewer? |
This change implements the capability for users of the AWS EMF Exporter to specify which metrics they would like to have sent to CloudWatch with a 1 second Storage Resolution. The EMF Exporter now explicitly states the Storage Resolution for each metric as 60 seconds, the previous implicit default, so there is no behavior change. If the user specifies a metric to have 1 second resolution it will be sent to CloudWatch EMF with the Storage Resolution set accordingly.
Description
Previously the AWS EMF Exporter sent metric data into CloudWatch without specifying the storage resolution. CloudWatch would then default to a 60 second storage resolution, even if metrics are sent more frequently than every 60 seconds. This would confuse users when they try to apply functions like AVG, SUM, MAX, or MIN to their metrics with a period of 5 seconds. The function would be applied by CloudWatch to 60 seconds worth of data and produced unexpected results and confusion for the user. This commit makes this 60 second resolution explicit in the messages sent to CloudWatch by the EMF Exporter and also gives the user the option to specify a more granular 1 second resolution per metric in the configuration file of the AWS EMF Exporter.
Link to tracking issue
Fixes #29506
Testing
Added tests to verify that config file parsing validates a metric descriptor that specifies either a valid unit, valid storage resolution, or both and rejects other invalid metric descriptors.
Added tests that the translation from metric data to CW EMF carries a storage resolution with it, defaulting to a value of 60 (current behavior) if no storage resolution valid is explicitly set in the configuration.
Documentation
Comments added in the code but have not updated the README.md pending acceptance of the PR.