Skip to content

Commit

Permalink
allow multiple log group names/arns to be set in environmental variab…
Browse files Browse the repository at this point in the history
…les (#218)
  • Loading branch information
pxaws authored Jun 24, 2024
1 parent 82dc971 commit c75e449
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 4 deletions.
7 changes: 5 additions & 2 deletions exporter/awsxrayexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,11 @@ following values that are evaluated in this order:
In the case of multiple values are defined, the value with higher precedence will be used to set the `cloudwatch_logs` AWS Property.

`aws.log.group.arns` and `aws.log.group.names` are slice resource attributes that can be set programmatically.
Alternatively those resource attributes can be set using the [`OTEL_RESOURCE_ATTRIBUTES` environment variable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable). In this case only a single log group/log group arn can
be provided as a string rather than a slice.
Alternatively those resource attributes can be set using the [`OTEL_RESOURCE_ATTRIBUTES` environment variable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable). To set multiple log group names /log group arns, you can use `&`
to separate them. For example, 3 log groups `log-group1`, `log-group2`, and `log-group3` are set in the following command:
```
export OTEL_RESOURCE_ATTRIBUTES="aws.log.group.names=log-group1&log-group2&log-group3"
```

## AWS Credential Configuration

Expand Down
23 changes: 21 additions & 2 deletions exporter/awsxrayexporter/internal/translator/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,16 +272,35 @@ func makeAws(attributes map[string]pcommon.Value, resource pcommon.Resource, log
return filtered, awsData
}

func getLogGroupNamesOrArns(logGroupNamesOrArns string) []string {
// Split the input string by '&'
items := strings.Split(logGroupNamesOrArns, "&")

// Filter out empty strings
var result []string
for _, item := range items {
if item != "" {
result = append(result, item)
}
}

return result
}

// Normalize value to slice.
// 1. String values are converted to a slice of size 1 so that we can also handle resource
// 1. String values are converted to a slice so that we can also handle resource
// attributes that are set using the OTEL_RESOURCE_ATTRIBUTES
// (multiple log group names or arns are separate by & like this "log-group1&log-group2&log-group3")
// 2. Slices are kept as they are
// 3. Other types will result in a empty slice so that we avoid panic.
func normalizeToSlice(v pcommon.Value) pcommon.Slice {
switch v.Type() {
case pcommon.ValueTypeStr:
s := pcommon.NewSlice()
s.AppendEmpty().SetStr(v.Str())
logGroupNamesOrArns := getLogGroupNamesOrArns(v.Str())
for _, logGroupOrArn := range logGroupNamesOrArns {
s.AppendEmpty().SetStr(logGroupOrArn)
}
return s
case pcommon.ValueTypeSlice:
return v.Slice()
Expand Down
81 changes: 81 additions & 0 deletions exporter/awsxrayexporter/internal/translator/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,61 @@ func TestLogGroupsFromStringResourceAttribute(t *testing.T) {
assert.Contains(t, awsData.CWLogs, cwl1)
}

func TestLogGroupsWithAmpersandFromStringResourceAttribute(t *testing.T) {
cwl1 := awsxray.LogGroupMetadata{
LogGroup: awsxray.String("group1"),
}
cwl2 := awsxray.LogGroupMetadata{
LogGroup: awsxray.String("group2"),
}

attributes := make(map[string]pcommon.Value)
resource := pcommon.NewResource()

// normal cases
resource.Attributes().PutStr(conventions.AttributeAWSLogGroupNames, "group1&group2")
filtered, awsData := makeAws(attributes, resource, nil)
assert.NotNil(t, filtered)
assert.NotNil(t, awsData)
assert.Equal(t, 2, len(awsData.CWLogs))
assert.Contains(t, awsData.CWLogs, cwl1)
assert.Contains(t, awsData.CWLogs, cwl2)

// with extra & at end
resource.Attributes().PutStr(conventions.AttributeAWSLogGroupNames, "group1&group2&")
filtered, awsData = makeAws(attributes, resource, nil)
assert.NotNil(t, filtered)
assert.NotNil(t, awsData)
assert.Equal(t, 2, len(awsData.CWLogs))
assert.Contains(t, awsData.CWLogs, cwl1)
assert.Contains(t, awsData.CWLogs, cwl2)

// with extra & in the middle
resource.Attributes().PutStr(conventions.AttributeAWSLogGroupNames, "group1&&group2")
filtered, awsData = makeAws(attributes, resource, nil)
assert.NotNil(t, filtered)
assert.NotNil(t, awsData)
assert.Equal(t, 2, len(awsData.CWLogs))
assert.Contains(t, awsData.CWLogs, cwl1)
assert.Contains(t, awsData.CWLogs, cwl2)

// with extra & at the beginning
resource.Attributes().PutStr(conventions.AttributeAWSLogGroupNames, "&group1&group2")
filtered, awsData = makeAws(attributes, resource, nil)
assert.NotNil(t, filtered)
assert.NotNil(t, awsData)
assert.Equal(t, 2, len(awsData.CWLogs))
assert.Contains(t, awsData.CWLogs, cwl1)
assert.Contains(t, awsData.CWLogs, cwl2)

// with only &
resource.Attributes().PutStr(conventions.AttributeAWSLogGroupNames, "&")
filtered, awsData = makeAws(attributes, resource, nil)
assert.NotNil(t, filtered)
assert.NotNil(t, awsData)
assert.Equal(t, 0, len(awsData.CWLogs))
}

func TestLogGroupsInvalidType(t *testing.T) {
attributes := make(map[string]pcommon.Value)
resource := pcommon.NewResource()
Expand Down Expand Up @@ -508,6 +563,32 @@ func TestLogGroupsArnsFromStringResourceAttributes(t *testing.T) {
assert.Contains(t, awsData.CWLogs, cwl1)
}

func TestLogGroupsArnsWithAmpersandFromStringResourceAttributes(t *testing.T) {
group1 := "arn:aws:logs:us-east-1:123456789123:log-group:group1"
group2 := "arn:aws:logs:us-east-1:123456789123:log-group:group2"

cwl1 := awsxray.LogGroupMetadata{
LogGroup: awsxray.String("group1"),
Arn: awsxray.String(group1),
}
cwl2 := awsxray.LogGroupMetadata{
LogGroup: awsxray.String("group2"),
Arn: awsxray.String(group2),
}

attributes := make(map[string]pcommon.Value)
resource := pcommon.NewResource()
resource.Attributes().PutStr(conventions.AttributeAWSLogGroupARNs, "arn:aws:logs:us-east-1:123456789123:log-group:group1&arn:aws:logs:us-east-1:123456789123:log-group:group2")

filtered, awsData := makeAws(attributes, resource, nil)

assert.NotNil(t, filtered)
assert.NotNil(t, awsData)
assert.Equal(t, 2, len(awsData.CWLogs))
assert.Contains(t, awsData.CWLogs, cwl1)
assert.Contains(t, awsData.CWLogs, cwl2)
}

func TestLogGroupsFromConfig(t *testing.T) {
cwl1 := awsxray.LogGroupMetadata{
LogGroup: awsxray.String("logGroup1"),
Expand Down

0 comments on commit c75e449

Please sign in to comment.