-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Unify zipkin v1 and v2 annotation/tag parsing logic #1002
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
Changes from 1 commit
2080cdc
45c7df8
5acb4a0
bbd9ad3
2cdac1b
937621f
56a079d
945fe81
0ea765f
1470dca
8d07b93
d08da47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,8 @@ type statusMapper struct { | |
| fromCensus status | ||
| // oc status code extracted from "http.status_code" tags | ||
| fromHTTP status | ||
| // oc status code extracted from "error" tags | ||
| fromErrorTag status | ||
| } | ||
|
|
||
| // ocStatus returns an OC status from the best possible extraction source. | ||
|
|
@@ -45,13 +47,6 @@ type statusMapper struct { | |
| // and finally fallback on code extracted and translated from "http.status_code" | ||
| // ocStatus must be called after all tags/attributes are processed with the `fromAttribute` method. | ||
| func (m *statusMapper) ocStatus() *tracepb.Status { | ||
|
|
||
| noKnownCode := m.fromCensus.codePtr == nil && m.fromHTTP.codePtr == nil && m.fromStatus.codePtr == nil | ||
| if noKnownCode && m.fromCensus.message != "" { | ||
| unknown := int32(2) | ||
| m.fromCensus.codePtr = &unknown | ||
| } | ||
|
|
||
| var s status | ||
| switch { | ||
| case m.fromCensus.codePtr != nil: | ||
|
|
@@ -62,6 +57,21 @@ func (m *statusMapper) ocStatus() *tracepb.Status { | |
| s = m.fromHTTP | ||
| } | ||
|
|
||
| // If no codePtr was provided, fallback to the first source with a message | ||
| // and use the error tag code | ||
| if s.codePtr == nil { | ||
| switch { | ||
| case m.fromCensus.message != "": | ||
| s = m.fromCensus | ||
| case m.fromStatus.message != "": | ||
| s = m.fromStatus | ||
| default: | ||
| s = m.fromHTTP | ||
| } | ||
|
|
||
| s.codePtr = m.fromErrorTag.codePtr | ||
|
||
| } | ||
|
|
||
| if s.codePtr != nil || s.message != "" { | ||
| code := int32(0) | ||
| if s.codePtr != nil { | ||
|
|
@@ -84,12 +94,6 @@ func (m *statusMapper) fromAttribute(key string, attrib *tracepb.AttributeValue) | |
| } | ||
| return true | ||
|
|
||
| case tracetranslator.TagError: | ||
| codePtr := extractStatusFromError(attrib) | ||
| if codePtr != nil { | ||
| m.fromCensus.codePtr = codePtr | ||
| } | ||
|
|
||
| case tracetranslator.TagZipkinCensusMsg, tracetranslator.TagZipkinOpenCensusMsg: | ||
| m.fromCensus.message = attrib.GetStringValue().GetValue() | ||
| return true | ||
|
|
@@ -114,6 +118,9 @@ func (m *statusMapper) fromAttribute(key string, attrib *tracepb.AttributeValue) | |
|
|
||
| case tracetranslator.TagHTTPStatusMsg: | ||
| m.fromHTTP.message = attrib.GetStringValue().GetValue() | ||
|
|
||
| case tracetranslator.TagError: | ||
| m.fromErrorTag.codePtr = extractStatusFromError(attrib) | ||
| } | ||
| return false | ||
| } | ||
|
|
@@ -148,15 +155,23 @@ func toInt32(i int) (int32, error) { | |
| func extractStatusFromError(attrib *tracepb.AttributeValue) *int32 { | ||
| // The status is stored with the "error" key | ||
| // See https://github.com/census-instrumentation/opencensus-go/blob/1eb9a13c7dd02141e065a665f6bf5c99a090a16a/exporter/zipkin/zipkin.go#L160-L165 | ||
| canonicalCodeStr := attrib.GetStringValue().GetValue() | ||
| if canonicalCodeStr == "" { | ||
| return nil | ||
| } | ||
| code, set := canonicalCodesMap[canonicalCodeStr] | ||
| if set { | ||
| return &code | ||
| var unknown int32 = 2 | ||
|
|
||
| switch val := attrib.Value.(type) { | ||
| case *tracepb.AttributeValue_StringValue: | ||
| canonicalCodeStr := val.StringValue.GetValue() | ||
| if canonicalCodeStr == "" { | ||
| return &unknown | ||
chris-smith-zocdoc marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| code, set := canonicalCodesMap[canonicalCodeStr] | ||
| if set { | ||
| return &code | ||
|
||
| } | ||
| default: | ||
| break | ||
| } | ||
| return nil | ||
|
|
||
| return &unknown | ||
| } | ||
|
|
||
| var canonicalCodesMap = map[string]int32{ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -161,8 +161,8 @@ func TestStatusCodeMapperCases(t *testing.T) { | |
| }, | ||
|
|
||
| { | ||
| name: "oc: description only, use unknown code", | ||
| expected: &tracepb.Status{Code: 2, Message: "a description"}, | ||
| name: "oc: description only, status ok", | ||
| expected: &tracepb.Status{Code: 0, Message: "a description"}, | ||
| attributes: map[string]string{ | ||
| "opencensus.status_description": "a description", | ||
| }, | ||
|
|
@@ -181,12 +181,36 @@ func TestStatusCodeMapperCases(t *testing.T) { | |
| }, | ||
|
|
||
| { | ||
| name: "error only", | ||
| expected: nil, | ||
| name: "error only: string description", | ||
| expected: &tracepb.Status{Code: 2}, | ||
| attributes: map[string]string{ | ||
| "error": "a description", | ||
| }, | ||
| }, | ||
|
|
||
| { | ||
| name: "error only: true", | ||
| expected: &tracepb.Status{Code: 2}, | ||
| attributes: map[string]string{ | ||
| "error": "true", | ||
| }, | ||
| }, | ||
|
|
||
| { | ||
| name: "error only: false", | ||
| expected: &tracepb.Status{Code: 2}, | ||
| attributes: map[string]string{ | ||
| "error": "false", | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This case is still weird to me, I looked through our data and we do have spans with this being reported 🙄 How do you feel about treating a boolean attribute with a value There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the instrumentation on your end producing this kind of spans? It looks like OpenTracing convention, but should not be reported by zipkin instrumentation. If the instrumentation and spans are valid we probably should handle this edge case and make it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I looked into this more, I don't think we need to make any changes. Originally I was looking at our exported data in honeycomb where this was accidentally reported as a boolean instead of a string, causing some type conversion problems. |
||
| }, | ||
| }, | ||
|
|
||
| { | ||
| name: "error only: 1", | ||
| expected: &tracepb.Status{Code: 2}, | ||
| attributes: map[string]string{ | ||
| "error": "1", | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| for _, test := range tests { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
applying this default caused this test to fail
opentelemetry-collector/translator/trace/zipkin/zipkinv1_thrift_to_protospan_test.go
Lines 166 to 175 in 665d64e
The jaeger behavior matches the previous zipkin behavior https://github.com/open-telemetry/opentelemetry-collector/blob/master/translator/trace/jaeger/jaegerthrift_to_protospan.go#L262-L265
Do you think I should update the tests or modify the behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change behavior . We should not set any error status based on "status.message" only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this only apply to that specific open census attribute? I ask because the existing code will return a tracepb.Status when either a code or message is set
if s.codePtr != nil || s.message != "". Because of the way it is currently implemented, this would only ever apply to fromHTTP though.On master, the current behavior is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. we should not set error status code based only on an error message attribute such as
http.status_messageorstatus.message(hopefully I don't miss any other message attribute)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@chris-smith-zocdoc could you apply this approach ^ and make sure tests pass?