Skip to content

Commit

Permalink
Support new sematic conventions.
Browse files Browse the repository at this point in the history
  • Loading branch information
zzhlogin committed Dec 18, 2024
1 parent 8e059f1 commit 831e4d6
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 6 deletions.
6 changes: 5 additions & 1 deletion exporter/awsxrayexporter/internal/translator/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
awsxray "github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/xray"
)

const (
AttributeTelemetryDistroVersion = "telemetry.distro.version"
)

func makeAws(attributes map[string]pcommon.Value, resource pcommon.Resource, logGroupNames []string) (map[string]pcommon.Value, *awsxray.AWSData) {
var (
cloud string
Expand Down Expand Up @@ -90,7 +94,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, AttributeTelemetryDistroVersion:
autoVersion = value.Str()
case conventions.AttributeContainerID:
containerID = value.Str()
Expand Down
17 changes: 17 additions & 0 deletions exporter/awsxrayexporter/internal/translator/aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,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(conventions.AttributeTelemetrySDKName, "opentelemetry")
resource.Attributes().PutStr(conventions.AttributeTelemetrySDKLanguage, "java")
resource.Attributes().PutStr(conventions.AttributeTelemetrySDKVersion, "1.2.3")
resource.Attributes().PutStr(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
3 changes: 3 additions & 0 deletions exporter/awsxrayexporter/internal/translator/cause.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,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(AwsIndividualHTTPErrorCodeAttr)
}

switch {
// The segment status for http spans will be based on their http.statuscode as we found some http
Expand Down
140 changes: 140 additions & 0 deletions exporter/awsxrayexporter/internal/translator/cause_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,31 @@ func TestCauseWithStatusMessage(t *testing.T) {
assert.True(t, strings.Contains(jsonStr, errorMsg))
}

func TestCauseWithStatusMessageStable(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
attributes[conventions.AttributeHTTPMethod] = "POST"
attributes[conventions.AttributeHTTPURL] = "https://api.example.com/widgets"
attributes[AwsIndividualHTTPErrorCodeAttr] = 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.True(t, strings.Contains(jsonStr, errorMsg))
}

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

func TestCauseWithHttpStatusMessageStable(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
attributes[conventions.AttributeHTTPMethod] = "POST"
attributes[conventions.AttributeHTTPURL] = "https://api.example.com/widgets"
attributes[AwsIndividualHTTPErrorCodeAttr] = 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.True(t, strings.Contains(jsonStr, errorMsg))
}

func TestCauseWithZeroStatusMessageAndFaultHttpCode(t *testing.T) {
errorMsg := "this is a test"
attributes := make(map[string]any)
Expand All @@ -245,6 +295,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[conventions.AttributeHTTPMethod] = "POST"
attributes[conventions.AttributeHTTPURL] = "https://api.example.com/widgets"
attributes[AwsIndividualHTTPErrorCodeAttr] = 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 @@ -338,6 +412,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[conventions.AttributeHTTPMethod] = "POST"
attributes[conventions.AttributeHTTPURL] = "https://api.example.com/widgets"
attributes[AwsIndividualHTTPErrorCodeAttr] = 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 @@ -359,6 +457,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[conventions.AttributeHTTPMethod] = "POST"
attributes[conventions.AttributeHTTPURL] = "https://api.example.com/widgets"
attributes[AwsIndividualHTTPErrorCodeAttr] = 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 @@ -380,6 +499,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[conventions.AttributeHTTPMethod] = "POST"
attributes[conventions.AttributeHTTPURL] = "https://api.example.com/widgets"
attributes[AwsIndividualHTTPErrorCodeAttr] = 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
5 changes: 3 additions & 2 deletions exporter/awsxrayexporter/internal/translator/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const (
AttributeURLScheme = "url.scheme"
AttributeURLFull = "url.full"
AttributeURLPath = "url.path"
AttributeURLQuery = "url.query"
AttributeUserAgentOriginal = "user_agent.original"
)

Expand Down Expand Up @@ -71,8 +72,8 @@ func makeHTTP(span ptrace.Span) (map[string]pcommon.Value, *awsxray.HTTPData) {
urlParts[key] = value.Str()
hasHTTP = true
hasHTTPRequestURLAttributes = true
case conventions.AttributeHTTPTarget:
urlParts[key] = value.Str()
case conventions.AttributeHTTPTarget, AttributeURLQuery:
urlParts[conventions.AttributeHTTPTarget] = value.Str()
hasHTTP = true
case conventions.AttributeHTTPServerName:
urlParts[key] = value.Str()
Expand Down
27 changes: 24 additions & 3 deletions exporter/awsxrayexporter/internal/translator/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,27 @@ func TestClientSpanWithSchemeHostTargetAttributes(t *testing.T) {
assert.True(t, strings.Contains(jsonStr, "https://api.example.com/users/junit"))
}

func TestClientSpanWithSchemeHostTargetAttributesStable(t *testing.T) {
attributes := make(map[string]any)
attributes[conventions.AttributeHTTPMethod] = "GET"
attributes[conventions.AttributeHTTPScheme] = "https"
attributes[conventions.AttributeHTTPHost] = "api.example.com"
attributes[AttributeURLQuery] = "/users/junit"
attributes[conventions.AttributeHTTPStatusCode] = 200
attributes["user.id"] = "junit"
span := constructHTTPClientSpan(attributes)

filtered, httpData := makeHTTP(span)

assert.NotNil(t, httpData)
assert.NotNil(t, filtered)
w := testWriters.borrow()
require.NoError(t, w.Encode(httpData))
jsonStr := w.String()
testWriters.release(w)
assert.True(t, strings.Contains(jsonStr, "https://api.example.com/users/junit"))
}

func TestClientSpanWithPeerAttributes(t *testing.T) {
attributes := make(map[string]any)
attributes[conventions.AttributeHTTPMethod] = "GET"
Expand Down Expand Up @@ -106,7 +127,7 @@ func TestClientSpanWithPeerAttributesStable(t *testing.T) {
attributes[conventions.AttributeNetPeerName] = "kb234.example.com"
attributes[conventions.AttributeNetPeerPort] = 8080
attributes[conventions.AttributeNetPeerIP] = "10.8.17.36"
attributes[conventions.AttributeHTTPTarget] = "/users/junit"
attributes[AttributeURLQuery] = "/users/junit"
attributes[conventions.AttributeHTTPStatusCode] = 200
span := constructHTTPClientSpan(attributes)

Expand Down Expand Up @@ -257,7 +278,7 @@ func TestServerSpanWithSchemeHostTargetAttributesStable(t *testing.T) {
attributes[AttributeHTTPRequestMethod] = "GET"
attributes[AttributeURLScheme] = "https"
attributes[AttributeServerAddress] = "api.example.com"
attributes[AttributeURLPath] = "/users/junit"
attributes[AttributeURLQuery] = "/users/junit"
attributes[AttributeClientAddress] = "192.168.15.32"
attributes[AttributeHTTPResponseStatusCode] = 200
span := constructHTTPServerSpan(attributes)
Expand Down Expand Up @@ -301,7 +322,7 @@ func TestServerSpanWithSchemeServernamePortTargetAttributesStable(t *testing.T)
attributes[AttributeURLScheme] = "https"
attributes[AttributeServerAddress] = "api.example.com"
attributes[AttributeServerPort] = 443
attributes[AttributeURLPath] = "/users/junit"
attributes[AttributeURLQuery] = "/users/junit"
attributes[AttributeClientAddress] = "192.168.15.32"
attributes[AttributeHTTPResponseStatusCode] = 200
span := constructHTTPServerSpan(attributes)
Expand Down

0 comments on commit 831e4d6

Please sign in to comment.