Skip to content

Commit

Permalink
Merge in latest semconv for awsxrayexporter.
Browse files Browse the repository at this point in the history
  • Loading branch information
zzhlogin committed Dec 19, 2024
1 parent 017b3d4 commit df4429c
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 92 deletions.
Empty file.
3 changes: 2 additions & 1 deletion exporter/awsxrayexporter/internal/translator/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"go.opentelemetry.io/collector/pdata/pcommon"
conventions "go.opentelemetry.io/collector/semconv/v1.12.0"
conventionsv127 "go.opentelemetry.io/collector/semconv/v1.27.0"

awsxray "github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/xray"
)
Expand Down Expand Up @@ -90,7 +91,7 @@ func makeAws(attributes map[string]pcommon.Value, resource pcommon.Resource, log
sdkLanguage = value.Str()
case conventions.AttributeTelemetrySDKVersion:
sdkVersion = value.Str()
case conventions.AttributeTelemetryAutoVersion:
case conventions.AttributeTelemetryAutoVersion, conventionsv127.AttributeTelemetryDistroVersion:
autoVersion = value.Str()
case conventions.AttributeContainerID:
containerID = value.Str()
Expand Down
33 changes: 33 additions & 0 deletions exporter/awsxrayexporter/internal/translator/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/assert"
"go.opentelemetry.io/collector/pdata/pcommon"
conventions "go.opentelemetry.io/collector/semconv/v1.12.0"
conventionsv127 "go.opentelemetry.io/collector/semconv/v1.27.0"

awsxray "github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/xray"
)
Expand Down Expand Up @@ -360,6 +361,23 @@ func TestJavaAutoInstrumentation(t *testing.T) {
assert.True(t, *awsData.XRay.AutoInstrumentation)
}

func TestJavaAutoInstrumentationStable(t *testing.T) {
attributes := make(map[string]pcommon.Value)
resource := pcommon.NewResource()
resource.Attributes().PutStr(conventionsv127.AttributeTelemetrySDKName, "opentelemetry")
resource.Attributes().PutStr(conventionsv127.AttributeTelemetrySDKLanguage, "java")
resource.Attributes().PutStr(conventionsv127.AttributeTelemetrySDKVersion, "1.2.3")
resource.Attributes().PutStr(conventionsv127.AttributeTelemetryDistroVersion, "3.4.5")

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

assert.NotNil(t, filtered)
assert.NotNil(t, awsData)
assert.Equal(t, "opentelemetry for java", *awsData.XRay.SDK)
assert.Equal(t, "1.2.3", *awsData.XRay.SDKVersion)
assert.True(t, *awsData.XRay.AutoInstrumentation)
}

func TestGoSDK(t *testing.T) {
attributes := make(map[string]pcommon.Value)
resource := pcommon.NewResource()
Expand Down Expand Up @@ -390,6 +408,21 @@ func TestCustomSDK(t *testing.T) {
assert.Equal(t, "2.0.3", *awsData.XRay.SDKVersion)
}

func TestCustomSDKForLanguage(t *testing.T) {
attributes := make(map[string]pcommon.Value)
resource := pcommon.NewResource()
resource.Attributes().PutStr(conventions.AttributeTelemetrySDKName, "test for java")
resource.Attributes().PutStr(conventions.AttributeTelemetrySDKLanguage, "java")
resource.Attributes().PutStr(conventions.AttributeTelemetrySDKVersion, "2.0.3")

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

assert.NotNil(t, filtered)
assert.NotNil(t, awsData)
assert.Equal(t, "test for java", *awsData.XRay.SDK)
assert.Equal(t, "2.0.3", *awsData.XRay.SDKVersion)
}

func TestLogGroups(t *testing.T) {
cwl1 := awsxray.LogGroupMetadata{
LogGroup: awsxray.String("group1"),
Expand Down
7 changes: 5 additions & 2 deletions exporter/awsxrayexporter/internal/translator/cause.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/ptrace"
conventions "go.opentelemetry.io/collector/semconv/v1.12.0"
conventionsv127 "go.opentelemetry.io/collector/semconv/v1.27.0"

awsxray "github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/xray"
)
Expand All @@ -25,7 +26,6 @@ const (
ExceptionEventName = "exception"
AwsIndividualHTTPEventName = "HTTP request failure"
AwsIndividualHTTPErrorEventType = "aws.http.error.event"
AwsIndividualHTTPErrorCodeAttr = "http.response.status_code"
AwsIndividualHTTPErrorMsgAttr = "aws.http.error_message"
)

Expand Down Expand Up @@ -91,7 +91,7 @@ func makeCause(span ptrace.Span, attributes map[string]pcommon.Value, resource p
parsed := parseException(exceptionType, message, stacktrace, isRemote, language)
exceptions = append(exceptions, parsed...)
} else if isAwsSdkSpan && event.Name() == AwsIndividualHTTPEventName {
errorCode, ok1 := event.Attributes().Get(AwsIndividualHTTPErrorCodeAttr)
errorCode, ok1 := event.Attributes().Get(conventionsv127.AttributeHTTPResponseStatusCode)
errorMessage, ok2 := event.Attributes().Get(AwsIndividualHTTPErrorMsgAttr)
if ok1 && ok2 {
eventEpochTime := event.Timestamp().AsTime().UnixMicro()
Expand Down Expand Up @@ -155,6 +155,9 @@ func makeCause(span ptrace.Span, attributes map[string]pcommon.Value, resource p
}

val, ok := span.Attributes().Get(conventions.AttributeHTTPStatusCode)
if !ok {
val, ok = span.Attributes().Get(conventionsv127.AttributeHTTPResponseStatusCode)
}

// The segment status for http spans will be based on their http.statuscode as we found some http
// spans does not fill with status.Code() but always filled with http.statuscode
Expand Down
143 changes: 142 additions & 1 deletion exporter/awsxrayexporter/internal/translator/cause_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"go.opentelemetry.io/collector/pdata/pcommon"
"go.opentelemetry.io/collector/pdata/ptrace"
conventions "go.opentelemetry.io/collector/semconv/v1.12.0"
conventionsv127 "go.opentelemetry.io/collector/semconv/v1.27.0"
)

func TestCauseWithExceptions(t *testing.T) {
Expand Down Expand Up @@ -69,7 +70,7 @@ func TestMakeCauseAwsSdkSpan(t *testing.T) {

event1 := span.Events().AppendEmpty()
event1.SetName(AwsIndividualHTTPEventName)
event1.Attributes().PutStr(AwsIndividualHTTPErrorCodeAttr, "503")
event1.Attributes().PutStr(conventionsv127.AttributeHTTPResponseStatusCode, "503")
event1.Attributes().PutStr(AwsIndividualHTTPErrorMsgAttr, "service is temporarily unavailable")
timestamp := pcommon.NewTimestampFromTime(time.UnixMicro(1696954761000001))
event1.SetTimestamp(timestamp)
Expand Down Expand Up @@ -197,6 +198,31 @@ func TestCauseWithStatusMessage(t *testing.T) {
assert.Contains(t, jsonStr, errorMsg)
}

func TestCauseWithStatusMessageStable(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
attributes[conventionsv127.AttributeHTTPRequestMethod] = http.MethodPost
attributes[conventionsv127.AttributeURLFull] = "https://api.example.com/widgets"
attributes[conventionsv127.AttributeHTTPResponseStatusCode] = 500
span := constructExceptionServerSpan(attributes, ptrace.StatusCodeError)
span.Status().SetMessage(errorMsg)
filtered, _ := makeHTTP(span)

res := pcommon.NewResource()
isError, isFault, isThrottle, filtered, cause := makeCause(span, filtered, res)

assert.True(t, isFault)
assert.False(t, isError)
assert.False(t, isThrottle)
assert.NotNil(t, filtered)
assert.NotNil(t, cause)
w := testWriters.borrow()
require.NoError(t, w.Encode(cause))
jsonStr := w.String()
testWriters.release(w)
assert.Contains(t, jsonStr, errorMsg)
}

func TestCauseWithHttpStatusMessage(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
Expand All @@ -222,6 +248,31 @@ func TestCauseWithHttpStatusMessage(t *testing.T) {
assert.Contains(t, jsonStr, errorMsg)
}

func TestCauseWithHttpStatusMessageStable(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
attributes[conventions.AttributeHTTPMethod] = http.MethodPost
attributes[conventions.AttributeHTTPURL] = "https://api.example.com/widgets"
attributes[conventionsv127.AttributeHTTPResponseStatusCode] = 500
attributes["http.status_text"] = errorMsg
span := constructExceptionServerSpan(attributes, ptrace.StatusCodeError)
filtered, _ := makeHTTP(span)

res := pcommon.NewResource()
isError, isFault, isThrottle, filtered, cause := makeCause(span, filtered, res)

assert.True(t, isFault)
assert.False(t, isError)
assert.False(t, isThrottle)
assert.NotNil(t, filtered)
assert.NotNil(t, cause)
w := testWriters.borrow()
require.NoError(t, w.Encode(cause))
jsonStr := w.String()
testWriters.release(w)
assert.Contains(t, jsonStr, errorMsg)
}

func TestCauseWithZeroStatusMessageAndFaultHttpCode(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
Expand All @@ -246,6 +297,30 @@ func TestCauseWithZeroStatusMessageAndFaultHttpCode(t *testing.T) {
assert.Nil(t, cause)
}

func TestCauseWithZeroStatusMessageAndFaultHttpCodeStable(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
attributes[conventionsv127.AttributeHTTPRequestMethod] = http.MethodPost
attributes[conventionsv127.AttributeURLFull] = "https://api.example.com/widgets"
attributes[conventionsv127.AttributeHTTPResponseStatusCode] = 500
attributes["http.status_text"] = errorMsg

span := constructExceptionServerSpan(attributes, ptrace.StatusCodeUnset)
filtered, _ := makeHTTP(span)
// Status is used to determine whether an error or not.
// This span illustrates incorrect instrumentation,
// marking a success status with an error http status code, and status wins.
// We do not expect to see such spans in practice.
res := pcommon.NewResource()
isError, isFault, isThrottle, filtered, cause := makeCause(span, filtered, res)

assert.False(t, isError)
assert.True(t, isFault)
assert.False(t, isThrottle)
assert.NotNil(t, filtered)
assert.Nil(t, cause)
}

func TestNonHttpUnsetCodeSpan(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
Expand Down Expand Up @@ -339,6 +414,30 @@ func TestCauseWithZeroStatusMessageAndFaultErrorCode(t *testing.T) {
assert.Nil(t, cause)
}

func TestCauseWithZeroStatusMessageAndFaultErrorCodeStable(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
attributes[conventionsv127.AttributeHTTPRequestMethod] = http.MethodPost
attributes[conventionsv127.AttributeURLFull] = "https://api.example.com/widgets"
attributes[conventionsv127.AttributeHTTPResponseStatusCode] = 400
attributes["http.status_text"] = errorMsg

span := constructExceptionServerSpan(attributes, ptrace.StatusCodeUnset)
filtered, _ := makeHTTP(span)
// Status is used to determine whether an error or not.
// This span illustrates incorrect instrumentation,
// marking a success status with an error http status code, and status wins.
// We do not expect to see such spans in practice.
res := pcommon.NewResource()
isError, isFault, isThrottle, filtered, cause := makeCause(span, filtered, res)

assert.True(t, isError)
assert.False(t, isFault)
assert.False(t, isThrottle)
assert.NotNil(t, filtered)
assert.Nil(t, cause)
}

func TestCauseWithClientErrorMessage(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
Expand All @@ -360,6 +459,27 @@ func TestCauseWithClientErrorMessage(t *testing.T) {
assert.NotNil(t, cause)
}

func TestCauseWithClientErrorMessageStable(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
attributes[conventionsv127.AttributeHTTPRequestMethod] = http.MethodPost
attributes[conventionsv127.AttributeURLFull] = "https://api.example.com/widgets"
attributes[conventionsv127.AttributeHTTPResponseStatusCode] = 499
attributes["http.status_text"] = errorMsg

span := constructExceptionServerSpan(attributes, ptrace.StatusCodeError)
filtered, _ := makeHTTP(span)

res := pcommon.NewResource()
isError, isFault, isThrottle, filtered, cause := makeCause(span, filtered, res)

assert.True(t, isError)
assert.False(t, isFault)
assert.False(t, isThrottle)
assert.NotNil(t, filtered)
assert.NotNil(t, cause)
}

func TestCauseWithThrottled(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
Expand All @@ -381,6 +501,27 @@ func TestCauseWithThrottled(t *testing.T) {
assert.NotNil(t, cause)
}

func TestCauseWithThrottledStable(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
attributes[conventionsv127.AttributeHTTPRequestMethod] = http.MethodPost
attributes[conventionsv127.AttributeURLFull] = "https://api.example.com/widgets"
attributes[conventionsv127.AttributeHTTPResponseStatusCode] = 429
attributes["http.status_text"] = errorMsg

span := constructExceptionServerSpan(attributes, ptrace.StatusCodeError)
filtered, _ := makeHTTP(span)

res := pcommon.NewResource()
isError, isFault, isThrottle, filtered, cause := makeCause(span, filtered, res)

assert.True(t, isError)
assert.False(t, isFault)
assert.True(t, isThrottle)
assert.NotNil(t, filtered)
assert.NotNil(t, cause)
}

func constructExceptionServerSpan(attributes map[string]any, statuscode ptrace.StatusCode) ptrace.Span {
endTime := time.Now().Round(time.Second)
startTime := endTime.Add(-90 * time.Second)
Expand Down
Loading

0 comments on commit df4429c

Please sign in to comment.