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 support for 1-second Storage Resolution in the AWS EMF Exporter #36057

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

jpbarto
Copy link

@jpbarto jpbarto commented Oct 29, 2024

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.

…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.
@jpbarto jpbarto requested a review from a team as a code owner October 29, 2024 11:09
Copy link

linux-foundation-easycla bot commented Oct 29, 2024

CLA Signed

The committers listed above are authorized under a signed CLA.

Comment on lines 104 to 105
// 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"`
Copy link
Member

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.

Copy link
Author

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
Copy link
Member

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
}

Copy link
Author

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.

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
@jpbarto
Copy link
Author

jpbarto commented Nov 6, 2024

@Aneurysm9 are you able to approve the change in its current form which now uses metric attributes to define storage resolution?

Comment on lines 224 to 226

fmt.Printf("##--## Dim Set: %+v\n", dimSet)

Copy link
Member

@mxiamxia mxiamxia Nov 12, 2024

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

Comment on lines 506 to 511
emfAttributeFilterRE := regexp.MustCompile(emfAttributeFilter)
for labelName := range labels {
if !emfAttributeFilterRE.MatchString(labelName) {
filteredLabels[labelName] = labels[labelName]
}
}
Copy link
Member

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)
Copy link
Member

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)
Copy link
Member

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_]*$"
Copy link
Member

@mxiamxia mxiamxia Nov 12, 2024

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_]*$?

Copy link
Author

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.

Copy link
Member

@mxiamxia mxiamxia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. ty!

@jpbarto
Copy link
Author

jpbarto commented Nov 13, 2024

@andrzej-stencel good morning, are you able to review this pull request please?

@andrzej-stencel
Copy link
Member

@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.

@jpbarto
Copy link
Author

jpbarto commented Nov 14, 2024

@andrzej-stencel the changelog has been updated as requested.

@jpbarto
Copy link
Author

jpbarto commented Nov 14, 2024

@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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[exporter/awsemf] Add StorageResolution config to support high-resolution metrics
5 participants