Skip to content

Commit

Permalink
Merge pull request #149 from appoptics/handle-opentracing-error
Browse files Browse the repository at this point in the history
Handle OpenTracing SetTag with "error"
  • Loading branch information
cce authored Jul 9, 2020
2 parents cbc9e78 + 17805c2 commit 404258e
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
35 changes: 33 additions & 2 deletions v1/ao/opentracing/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
package opentracing

import (
"fmt"
"reflect"
"sync"

"github.com/appoptics/appoptics-apm-go/v1/ao"
ot "github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"
)

Expand Down Expand Up @@ -199,16 +202,44 @@ func (s *spanImpl) SetTag(key string, value interface{}) ot.Span {
s.Lock()
defer s.Unlock()
// if transaction name is passed, set on the span
if tagName := translateTagName(key); tagName == "TransactionName" {
tagName := translateTagName(key)
switch tagName {
case "TransactionName":
if txnName, ok := value.(string); ok {
s.context.span.SetTransactionName(txnName)
}
} else {
case string(ext.Error):
s.setErrorTag(value)
default:
s.context.span.AddEndArgs(tagName, value)
}
return s
}

// setErrorTag passes an OT error to the AO span.Error method.
func (s *spanImpl) setErrorTag(value interface{}) {
switch v := value.(type) {
case bool:
// OpenTracing spec defines bool value
if v {
s.context.span.Error(string(ext.Error), "true")
}
case error:
// handle error if provided
s.context.span.Error(reflect.TypeOf(v).String(), v.Error())
case string:
// error string provided
s.context.span.Error(string(ext.Error), v)
case fmt.Stringer:
s.context.span.Error(string(ext.Error), v.String())
case nil:
// no error, ignore
default:
// an unknown error type, assume an error
s.context.span.Error(string(ext.Error), reflect.TypeOf(v).String())
}
}

// LogEvent logs a event to the span.
//
// Deprecated: this method is deprecated.
Expand Down
58 changes: 58 additions & 0 deletions v1/ao/opentracing/tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package opentracing

import (
"fmt"
"testing"

g "github.com/appoptics/appoptics-apm-go/v1/ao/internal/graphtest"
Expand Down Expand Up @@ -56,3 +57,60 @@ func TestOTSetTransactionName(t *testing.T) {
func TestOTSetResourceName(t *testing.T) {
testTransactionName(t, "resource.name", "myTxn2")
}

type customStringer struct{}

func (customStringer) String() string { return "custom" }

type weirdType struct{}

func TestSetErrorTags(t *testing.T) {
// test a bunch of different args to SetTag("error", ...) and how they show up in trace event KVs
for _, tc := range []struct{ errorTagVal, errorClass, errorMsg interface{} }{
{fmt.Errorf("An error!"), "*errors.errorString", "An error!"},
{true, "error", "true"},
{"error string", "error", "error string"},
{customStringer{}, "error", "custom"},
{weirdType{}, "error", "opentracing.weirdType"},
} {
t.Run(fmt.Sprintf("Error tagval %v, errClass %v, errMsg %v", tc.errorTagVal, tc.errorClass, tc.errorMsg), func(t *testing.T) {
r := reporter.SetTestReporter() // set up test reporter
tr := NewTracer()

span := tr.StartSpan("op")
assert.NotNil(t, span)
span.SetTag("error", tc.errorTagVal)
span.Finish()

r.Close(3)
g.AssertGraph(t, r.EventBufs, 3, g.AssertNodeMap{
{"op", "entry"}: {},
{"op", "error"}: {Edges: g.Edges{{"op", "entry"}}, Callback: func(n g.Node) {
assert.Equal(t, tc.errorClass, n.Map["ErrorClass"])
assert.Equal(t, tc.errorMsg, n.Map["ErrorMsg"])
}},
{"op", "exit"}: {Edges: g.Edges{{"op", "error"}}, Callback: func(n g.Node) {}},
})
})
}

// test a couple of cases where no error is reported
for _, tc := range []struct{ errorTagVal interface{} }{
{false},
{nil},
} {
r := reporter.SetTestReporter() // set up test reporter
tr := NewTracer()

span := tr.StartSpan("op")
assert.NotNil(t, span)
span.SetTag("error", tc.errorTagVal)
span.Finish()

r.Close(2)
g.AssertGraph(t, r.EventBufs, 2, g.AssertNodeMap{
{"op", "entry"}: {},
{"op", "exit"}: {Edges: g.Edges{{"op", "entry"}}, Callback: func(n g.Node) {}},
})
}
}

0 comments on commit 404258e

Please sign in to comment.