Skip to content
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

Fix setting internal status code in jaeger receivers #1105

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 21 additions & 24 deletions translator/trace/jaeger/jaegerproto_to_traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,42 +208,39 @@ func jTagsToInternalAttributes(tags []model.KeyValue, dest pdata.AttributeMap) {
func setInternalSpanStatus(attrs pdata.AttributeMap, dest pdata.SpanStatus) {
dest.InitEmpty()

var codeSet bool
if codeAttr, ok := attrs.Get(tracetranslator.TagStatusCode); ok {
code, err := getStatusCodeFromAttr(codeAttr)
if err == nil {
codeSet = true
dest.SetCode(code)
attrs.Delete(tracetranslator.TagStatusCode)
}
} else if errorVal, ok := attrs.Get(tracetranslator.TagError); ok {
statusCode := pdata.StatusCode(otlptrace.Status_Ok)

if errorVal, ok := attrs.Get(tracetranslator.TagError); ok {
if errorVal.BoolVal() {
dest.SetCode(pdata.StatusCode(otlptrace.Status_UnknownError))
codeSet = true
statusCode = pdata.StatusCode(otlptrace.Status_UnknownError)
attrs.Delete(tracetranslator.TagError)
}
}

if codeSet {
if codeAttr, ok := attrs.Get(tracetranslator.TagStatusCode); ok {
if code, err := getStatusCodeFromAttr(codeAttr); err == nil {
statusCode = code
attrs.Delete(tracetranslator.TagStatusCode)
}
if msgAttr, ok := attrs.Get(tracetranslator.TagStatusMsg); ok {
dest.SetMessage(msgAttr.StringVal())
attrs.Delete(tracetranslator.TagStatusMsg)
}
attrs.Delete(tracetranslator.TagError)
} else {
httpCodeAttr, ok := attrs.Get(tracetranslator.TagHTTPStatusCode)
if ok {
code, err := getStatusCodeFromHTTPStatusAttr(httpCodeAttr)
if err == nil {
dest.SetCode(code)
} else if httpCodeAttr, ok := attrs.Get(tracetranslator.TagHTTPStatusCode); ok {
if code, err := getStatusCodeFromHTTPStatusAttr(httpCodeAttr); err == nil {

// Do not set status code to OK in case it was set to Unknown based on "error" tag
if code != pdata.StatusCode(otlptrace.Status_Ok) {
statusCode = code
}

if msgAttr, ok := attrs.Get(tracetranslator.TagHTTPStatusMsg); ok {
dest.SetMessage(msgAttr.StringVal())
}
} else {
dest.SetCode(pdata.StatusCode(otlptrace.Status_Ok))
}
if msgAttr, ok := attrs.Get(tracetranslator.TagHTTPStatusMsg); ok {
dest.SetMessage(msgAttr.StringVal())
}
}

dest.SetCode(statusCode)
}

func getStatusCodeFromAttr(attrVal pdata.AttributeValue) (pdata.StatusCode, error) {
Expand Down
115 changes: 115 additions & 0 deletions translator/trace/jaeger/jaegerproto_to_traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,121 @@ func TestProtoBatchToInternalTraces(t *testing.T) {
}
}

func TestSetInternalSpanStatus(t *testing.T) {

okStatus := pdata.NewSpanStatus()
okStatus.InitEmpty()
okStatus.SetCode(pdata.StatusCode(otlptrace.Status_Ok))

unknownStatus := pdata.NewSpanStatus()
unknownStatus.InitEmpty()
unknownStatus.SetCode(pdata.StatusCode(otlptrace.Status_UnknownError))

canceledStatus := pdata.NewSpanStatus()
canceledStatus.InitEmpty()
canceledStatus.SetCode(pdata.StatusCode(otlptrace.Status_Cancelled))

invalidStatusWithMessage := pdata.NewSpanStatus()
invalidStatusWithMessage.InitEmpty()
invalidStatusWithMessage.SetCode(pdata.StatusCode(otlptrace.Status_InvalidArgument))
invalidStatusWithMessage.SetMessage("Error: Invalid argument")

notFoundStatus := pdata.NewSpanStatus()
notFoundStatus.InitEmpty()
notFoundStatus.SetCode(pdata.StatusCode(otlptrace.Status_NotFound))

notFoundStatusWithMessage := pdata.NewSpanStatus()
notFoundStatusWithMessage.InitEmpty()
notFoundStatusWithMessage.SetCode(pdata.StatusCode(otlptrace.Status_NotFound))
notFoundStatusWithMessage.SetMessage("HTTP 404: Not Found")

tests := []struct {
name string
attrs pdata.AttributeMap
status pdata.SpanStatus
attrsModifiedLen int // Length of attributes map after dropping converted fields
}{
{
name: "No tags set -> OK status",
attrs: pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{}),
status: okStatus,
attrsModifiedLen: 0,
},
{
name: "error tag set -> Unknown status",
attrs: pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{
tracetranslator.TagError: pdata.NewAttributeValueBool(true),
}),
status: unknownStatus,
attrsModifiedLen: 0,
},
{
name: "status.code is set as int",
attrs: pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{
tracetranslator.TagStatusCode: pdata.NewAttributeValueInt(1),
}),
status: canceledStatus,
attrsModifiedLen: 0,
},
{
name: "status.code, status.message and error tags are set",
attrs: pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{
tracetranslator.TagError: pdata.NewAttributeValueBool(true),
tracetranslator.TagStatusCode: pdata.NewAttributeValueInt(3),
tracetranslator.TagStatusMsg: pdata.NewAttributeValueString("Error: Invalid argument"),
}),
status: invalidStatusWithMessage,
attrsModifiedLen: 0,
},
{
name: "http.status_code tag is set as string",
attrs: pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{
tracetranslator.TagHTTPStatusCode: pdata.NewAttributeValueString("404"),
}),
status: notFoundStatus,
attrsModifiedLen: 1,
},
{
name: "http.status_code, http.status_message and error tags are set",
attrs: pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{
tracetranslator.TagError: pdata.NewAttributeValueBool(true),
tracetranslator.TagHTTPStatusCode: pdata.NewAttributeValueInt(404),
tracetranslator.TagHTTPStatusMsg: pdata.NewAttributeValueString("HTTP 404: Not Found"),
}),
status: notFoundStatusWithMessage,
attrsModifiedLen: 2,
},
{
name: "status.code has precedence over http.status_code.",
attrs: pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{
tracetranslator.TagStatusCode: pdata.NewAttributeValueInt(1),
tracetranslator.TagHTTPStatusCode: pdata.NewAttributeValueInt(500),
tracetranslator.TagHTTPStatusMsg: pdata.NewAttributeValueString("Server Error"),
}),
status: canceledStatus,
attrsModifiedLen: 2,
},
{
name: "Ignore http.status_code == 200 if error set to true.",
attrs: pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{
tracetranslator.TagError: pdata.NewAttributeValueBool(true),
tracetranslator.TagHTTPStatusCode: pdata.NewAttributeValueInt(200),
}),
status: unknownStatus,
attrsModifiedLen: 1,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
status := pdata.NewSpanStatus()
setInternalSpanStatus(test.attrs, status)
assert.EqualValues(t, test.status, status)
assert.Equal(t, test.attrsModifiedLen, test.attrs.Len())
})
}
}

func TestProtoBatchesToInternalTraces(t *testing.T) {
batches := []*model.Batch{
{
Expand Down