forked from open-telemetry/opentelemetry-collector-contrib
-
Notifications
You must be signed in to change notification settings - Fork 40
[OCB] Copy+Update CWAgent's awsapplicationsignals into the processor/ directory
#247
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
Merged
Merged
Changes from 2 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
78e95a0
copy appsignals processor with zero changes
jj22ee 56852fa
rename package directory to awsapplicationsignalsprocessor
jj22ee 7855533
update dependency locations, remove CWAgent dependencies and copied n…
jj22ee 9041f2e
run common make commands, update license check for appsignals
jj22ee b81daa4
fix data races in tests and cardinality control
jj22ee 751437b
fix linting
jj22ee 0e7bbb3
update README
jj22ee File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| # AWS AppSignals Processor for Amazon Cloudwatch Agent | ||
|
|
||
| The AWS AppSignals processor is used to reduce the cardinality of telemetry metrics and traces before exporting them to CloudWatch Logs via [EMF](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/awsemfexporter) and [X-Ray](github.com/open-telemetry/opentelemetry-collector-contrib/exporter/awsxrayexporter) respectively. | ||
| It reduces the cardinality of metrics/traces via 3 types of actions, `keep`, `drop` and `replace`, which are configured by users. CloudWatch Agent(CWA) customers will configure these rules with their CWA configurations. | ||
|
|
||
| Note: Traces support only `replace` actions and are implicitly pulled from the logs section of the CWA configuration | ||
|
|
||
| | Status | | | ||
| | ------------------------ |---------------------------| | ||
| | Stability | [beta] | | ||
| | Supported pipeline types | metrics, traces | | ||
| | Distributions | [amazon-cloudwatch-agent] | | ||
|
|
||
| ## Exporter Configuration | ||
|
|
||
| The following exporter configuration parameters are supported. | ||
|
|
||
| | Name | Description | Default | | ||
| |:---------------------------------------------|:------------------------------------------------------------------------------------------------------------------|---------| | ||
| | `resolvers` | Platform processor is being configured for. Currently supports EKS. EC2 platform will be supported in the future. | [eks] | | ||
| | `rules` | Custom configuration rules used for filtering metrics/traces. Can be of type `drop`, `keep`, `replace`. | [] | | ||
|
|
||
| ### rules | ||
| The rules section defines the rules (filters) to be applied | ||
|
|
||
| | Name | Description | Default | | ||
| |:---------------|:-------------------------------------------------------------------------------------------------------------------------| --- | | ||
| | `selectors` | List of metrics/traces dimension matchers. | [] | | ||
| | `action` | Action being applied for the specified selector. `keep`, `drop`, `replace` | "" | | ||
| | `rule_name` | (Optional) Name of rule. | [] | | ||
| | `replacements` | (Optional) List of metrics/traces replacements to be executed. Based on specified selectors. requires `action = replace` | [] | | ||
|
|
||
| #### selectors | ||
| A selectors section defines a matching against the dimensions of incoming metrics/traces. | ||
|
|
||
| | Name | Description | Default | | ||
| |:------------|:--------------------------------------------------------------| ------ | | ||
| | `dimension` | Dimension of metrics/traces | "" | | ||
| | `match` | glob used for matching values of dimensions | "" | | ||
|
|
||
| ### replacements | ||
| A replacements section defines a matching against the dimensions of incoming metrics/traces for which value replacements will be done. action must be `replace` | ||
|
|
||
| | Name | Description | Default | | ||
| |:-------------------|:----------------------------------------------| ------ | | ||
| | `target_dimension` | Dimension to replace | "" | | ||
| | `value` | Value to replace current dimension value with | "" | | ||
|
|
||
|
|
||
| ## AWS AppSignals Processor Configuration Example | ||
|
|
||
| ```yaml | ||
| awsapplicationsignals: | ||
| resolvers: ["eks"] | ||
| rules: | ||
| - selectors: | ||
| - dimension: Operation | ||
| match: "POST *" | ||
| - dimension: RemoteService | ||
| match: "*" | ||
| action: keep | ||
| rule_name: "keep01" | ||
| - selectors: | ||
| - dimension: Operation | ||
| match: "GET *" | ||
| - dimension: RemoteService | ||
| match: "*" | ||
| action: keep | ||
| rule_name: "keep02" | ||
| - selectors: | ||
| - dimension: Operation | ||
| match: "POST *" | ||
| action: drop | ||
| rule_name: "drop01" | ||
| - selectors: | ||
| - dimension: Operation | ||
| match: "*" | ||
| replacements: | ||
| - target_dimension: RemoteOperation | ||
| value: "This is a test string" | ||
| action: replace | ||
| rule_name: "replace01" | ||
| ``` | ||
|
|
||
| ## Amazon CloudWatch Agent Configuration Example | ||
|
|
||
| ```json | ||
| { | ||
| "agent": { | ||
| "region": "us-west-2", | ||
| "debug": true | ||
| }, | ||
| "traces": { | ||
| "traces_collected": { | ||
| "app_signals": {} | ||
| } | ||
| }, | ||
| "logs": { | ||
| "metrics_collected": { | ||
| "app_signals": { | ||
| "rules": [ | ||
| { | ||
| "selectors": [ | ||
| { | ||
| "dimension": "Service", | ||
| "match": "pet-clinic-frontend" | ||
| }, | ||
| { | ||
| "dimension": "RemoteService", | ||
| "match": "customers-service" | ||
| } | ||
| ], | ||
| "action": "keep", | ||
| "rule_name": "keep01" | ||
| }, | ||
| { | ||
| "selectors": [ | ||
| { | ||
| "dimension": "Operation", | ||
| "match": "GET *" | ||
| } | ||
| ], | ||
| "action": "drop", | ||
| "rule_name": "drop01" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| package common | ||
|
|
||
| // Metric attribute used as CloudWatch metric dimension. | ||
| const ( | ||
| CWMetricAttributeLocalService = "Service" | ||
| CWMetricAttributeLocalOperation = "Operation" | ||
| CWMetricAttributeEnvironment = "Environment" | ||
| CWMetricAttributeRemoteService = "RemoteService" | ||
| CWMetricAttributeRemoteEnvironment = "RemoteEnvironment" | ||
| CWMetricAttributeRemoteOperation = "RemoteOperation" | ||
| CWMetricAttributeRemoteResourceIdentifier = "RemoteResourceIdentifier" | ||
| CWMetricAttributeRemoteResourceType = "RemoteResourceType" | ||
| ) | ||
|
|
||
| // Platform attribute used as CloudWatch EMF log field and X-Ray trace annotation. | ||
| const ( | ||
| AttributePlatformType = "PlatformType" | ||
| AttributeEKSClusterName = "EKS.Cluster" | ||
| AttributeK8SClusterName = "K8s.Cluster" | ||
| AttributeK8SNamespace = "K8s.Namespace" | ||
| AttributeK8SWorkload = "K8s.Workload" | ||
| AttributeK8SPod = "K8s.Pod" | ||
| AttributeEC2AutoScalingGroup = "EC2.AutoScalingGroup" | ||
| AttributeEC2InstanceId = "EC2.InstanceId" | ||
| AttributeHost = "Host" | ||
| ) | ||
|
|
||
| // Platform attribute used as CloudWatch EMF log field. | ||
| const ( | ||
| MetricAttributeECSCluster = "ECS.Cluster" | ||
| MetricAttributeECSTaskId = "ECS.TaskId" | ||
| MetricAttributeECSTaskDefinitionFamily = "ECS.TaskDefinitionFamily" | ||
| MetricAttributeECSTaskDefinitionRevision = "ECS.TaskDefinitionRevision" | ||
| ) | ||
|
|
||
| // Telemetry attributes used as CloudWatch EMF log fields. | ||
| const ( | ||
| MetricAttributeTelemetrySDK = "Telemetry.SDK" | ||
| MetricAttributeTelemetryAgent = "Telemetry.Agent" | ||
| MetricAttributeTelemetrySource = "Telemetry.Source" | ||
| ) | ||
|
|
||
| // Resource attributes used as CloudWatch EMF log fields. | ||
| const ( | ||
| MetricAttributeRemoteDbUser = "RemoteDbUser" | ||
| MetricAttributeRemoteResourceCfnPrimaryIdentifier = "RemoteResourceCfnPrimaryIdentifier" | ||
| ) | ||
|
|
||
| const ( | ||
| AttributeTmpReserved = "aws.tmp.reserved" | ||
| ) | ||
|
|
||
| var CWMetricAttributes = []string{ | ||
| CWMetricAttributeLocalService, | ||
| CWMetricAttributeLocalOperation, | ||
| CWMetricAttributeEnvironment, | ||
| CWMetricAttributeRemoteService, | ||
| CWMetricAttributeRemoteEnvironment, | ||
| CWMetricAttributeRemoteOperation, | ||
| CWMetricAttributeRemoteResourceIdentifier, | ||
| CWMetricAttributeRemoteResourceType, | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| package config | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "time" | ||
|
|
||
| "github.com/aws/amazon-cloudwatch-agent/plugins/processors/awsapplicationsignals/rules" | ||
| ) | ||
|
|
||
| type Config struct { | ||
| Resolvers []Resolver `mapstructure:"resolvers"` | ||
| Rules []rules.Rule `mapstructure:"rules"` | ||
| Limiter *LimiterConfig `mapstructure:"limiter"` | ||
| } | ||
|
|
||
| type LimiterConfig struct { | ||
| Threshold int `mapstructure:"drop_threshold"` | ||
| Disabled bool `mapstructure:"disabled"` | ||
| LogDroppedMetrics bool `mapstructure:"log_dropped_metrics"` | ||
| RotationInterval time.Duration `mapstructure:"rotation_interval"` | ||
| GarbageCollectionInterval time.Duration `mapstructure:"garbage_collection_interval"` | ||
| ParentContext context.Context `mapstructure:"-"` | ||
| } | ||
|
|
||
| const ( | ||
| DefaultThreshold = 500 | ||
| DefaultRotationInterval = 1 * time.Hour | ||
| DefaultGCInterval = 10 * time.Minute | ||
| ) | ||
|
|
||
| func NewDefaultLimiterConfig() *LimiterConfig { | ||
| return &LimiterConfig{ | ||
| Threshold: DefaultThreshold, | ||
| Disabled: false, | ||
| LogDroppedMetrics: false, | ||
| RotationInterval: DefaultRotationInterval, | ||
| GarbageCollectionInterval: DefaultGCInterval, | ||
| } | ||
| } | ||
|
|
||
| func (lc *LimiterConfig) Validate() { | ||
| if lc.GarbageCollectionInterval == 0 { | ||
| lc.GarbageCollectionInterval = DefaultGCInterval | ||
| } | ||
| } | ||
|
|
||
| func (cfg *Config) Validate() error { | ||
| if len(cfg.Resolvers) == 0 { | ||
| return errors.New("resolvers must not be empty") | ||
| } | ||
| for _, resolver := range cfg.Resolvers { | ||
| switch resolver.Platform { | ||
| case PlatformEKS: | ||
| if resolver.Name == "" { | ||
| return errors.New("name must not be empty for eks resolver") | ||
| } | ||
| case PlatformK8s: | ||
| if resolver.Name == "" { | ||
| return errors.New("name must not be empty for k8s resolver") | ||
| } | ||
| case PlatformEC2, PlatformECS, PlatformGeneric: | ||
| default: | ||
| return errors.New("unknown resolver") | ||
| } | ||
| } | ||
|
|
||
| if cfg.Limiter != nil { | ||
| cfg.Limiter.Validate() | ||
| } | ||
| return nil | ||
| } |
82 changes: 82 additions & 0 deletions
82
processor/awsapplicationsignalsprocessor/config/config_test.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| package config | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| func TestValidatePassed(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| resolver Resolver | ||
| }{ | ||
| { | ||
| "testEKS", | ||
| NewEKSResolver("test"), | ||
| }, | ||
| { | ||
| "testK8S", | ||
| NewK8sResolver("test"), | ||
| }, | ||
| { | ||
| "testEC2", | ||
| NewEC2Resolver("test"), | ||
| }, | ||
| { | ||
| "testECS", | ||
| NewECSResolver("test"), | ||
| }, | ||
| { | ||
| "testGeneric", | ||
| NewGenericResolver("test"), | ||
| }, | ||
| } | ||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| config := Config{ | ||
| Resolvers: []Resolver{tt.resolver}, | ||
| Rules: nil, | ||
| } | ||
| assert.Nil(t, config.Validate()) | ||
|
|
||
| }) | ||
| } | ||
| } | ||
|
|
||
| func TestValidateFailedOnEmptyResolver(t *testing.T) { | ||
| config := Config{ | ||
| Resolvers: []Resolver{}, | ||
| Rules: nil, | ||
| } | ||
| assert.NotNil(t, config.Validate()) | ||
| } | ||
|
|
||
| func TestValidateFailedOnEmptyResolverName(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| resolver Resolver | ||
| }{ | ||
| { | ||
| "testEKS", | ||
| NewEKSResolver(""), | ||
| }, | ||
| { | ||
| "testK8S", | ||
| NewK8sResolver(""), | ||
| }, | ||
| } | ||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| config := Config{ | ||
| Resolvers: []Resolver{tt.resolver}, | ||
| Rules: nil, | ||
| } | ||
| assert.NotNil(t, config.Validate()) | ||
|
|
||
| }) | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.