Skip to content
This repository was archived by the owner on Aug 17, 2020. It is now read-only.
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions env/vars.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ var (
ScopeConfiguration = newSliceEnvVar([]string{tags.PlatformName, tags.PlatformArchitecture, tags.GoVersion}, "SCOPE_CONFIGURATION")
ScopeMetadata = newMapEnvVar(nil, "SCOPE_METADATA")
ScopeInstrumentationHttpPayloads = newBooleanEnvVar(false, "SCOPE_INSTRUMENTATION_HTTP_PAYLOADS")
ScopeInstrumentationHttpStacktrace = newBooleanEnvVar(false, "SCOPE_INSTRUMENTATION_HTTP_STACKTRACE")
ScopeInstrumentationDbStatementValues = newBooleanEnvVar(false, "SCOPE_INSTRUMENTATION_DB_STATEMENT_VALUES")
ScopeInstrumentationDbStacktrace = newBooleanEnvVar(false, "SCOPE_INSTRUMENTATION_DB_STACKTRACE")
)
29 changes: 23 additions & 6 deletions errors/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package errors

import (
"fmt"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -57,28 +58,44 @@ func LogErrorInRawSpan(rawSpan *tracer.RawSpan, err **errors.Error) {
}

// Gets the current stack frames array
func GetCurrentStackFrames(skip int) []StackFrames {
func getCurrentStackFrames(skip int) []StackFrames {
skip = skip + 1
err := errors.New(nil)
errStack := err.StackFrames()
nLength := len(errStack) - skip
if nLength < 0 {
return nil
}
stackFrames := make([]StackFrames, nLength)
stackFrames := make([]StackFrames, 0)
for idx, frame := range errStack {
if idx >= skip {
stackFrames[idx-skip] = StackFrames{
File: frame.File,
stackFrames = append(stackFrames, StackFrames{
File: filepath.Clean(frame.File),
LineNumber: frame.LineNumber,
Name: frame.Name,
Package: frame.Package,
}
})
}
}
return stackFrames
}

// Gets the current stacktrace
func GetCurrentStackTrace(skip int) map[string]interface{} {
var exFrames []map[string]interface{}
for _, frame := range getCurrentStackFrames(skip + 1) {
exFrames = append(exFrames, map[string]interface{}{
"name": frame.Name,
"module": frame.Package,
"file": frame.File,
"line": frame.LineNumber,
})
}
return map[string]interface{}{
"frames": exFrames,
}
}

// Get the current error with the fixed stacktrace
func GetCurrentError(recoverData interface{}) *errors.Error {
return errors.Wrap(recoverData, 1)
Expand Down Expand Up @@ -138,7 +155,7 @@ func getExceptionFrameData(errMessage string, errStack []errors.StackFrame) map[
exFrames = append(exFrames, map[string]interface{}{
"name": frame.Name,
"module": frame.Package,
"file": frame.File,
"file": filepath.Clean(frame.File),
"line": frame.LineNumber,
})
}
Expand Down
8 changes: 8 additions & 0 deletions instrumentation/nethttp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/opentracing/opentracing-go/ext"
"github.com/opentracing/opentracing-go/log"

scopeerrors "go.undefinedlabs.com/scopeagent/errors"
"go.undefinedlabs.com/scopeagent/instrumentation"
)

Expand All @@ -35,6 +36,9 @@ type Transport struct {

// Enable payload instrumentation
PayloadInstrumentation bool

// Enable stacktrace
Stacktrace bool
}

type clientOptions struct {
Expand Down Expand Up @@ -178,6 +182,10 @@ func (t *Transport) doRoundTrip(req *http.Request) (*http.Response, error) {

tracer.start(req)

if t.Stacktrace {
tracer.sp.SetTag("stacktrace", scopeerrors.GetCurrentStackTrace(2))
}

ext.HTTPMethod.Set(tracer.sp, req.Method)
ext.HTTPUrl.Set(tracer.sp, req.URL.String())
tracer.opts.spanObserver(tracer.sp, req)
Expand Down
2 changes: 1 addition & 1 deletion instrumentation/nethttp/nethttp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
var r *tracer.InMemorySpanRecorder

func TestMain(m *testing.M) {
PatchHttpDefaultClient(WithPayloadInstrumentation())
PatchHttpDefaultClient(WithPayloadInstrumentation(), WithStacktrace())

// Test tracer
r = tracer.NewInMemoryRecorder()
Expand Down
8 changes: 8 additions & 0 deletions instrumentation/nethttp/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ func WithPayloadInstrumentation() Option {
}
}

// Enables stacktrace
func WithStacktrace() Option {
return func(t *Transport) {
t.Stacktrace = true
}
}

// Patches the default http client with the instrumented transport
func PatchHttpDefaultClient(options ...Option) {
once.Do(func() {
Expand All @@ -25,6 +32,7 @@ func PatchHttpDefaultClient(options ...Option) {
option(transport)
}
transport.PayloadInstrumentation = transport.PayloadInstrumentation || env.ScopeInstrumentationHttpPayloads.Value
transport.Stacktrace = transport.Stacktrace || env.ScopeInstrumentationHttpStacktrace.Value
http.DefaultClient = &http.Client{Transport: transport}
})
}
21 changes: 19 additions & 2 deletions instrumentation/sql/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import (
"database/sql/driver"
"errors"
"fmt"
"reflect"
"strings"

"github.com/opentracing/opentracing-go"

"go.undefinedlabs.com/scopeagent/env"
scopeerrors "go.undefinedlabs.com/scopeagent/errors"
"go.undefinedlabs.com/scopeagent/instrumentation"
"reflect"
"strings"
)

type (
Expand All @@ -22,6 +25,7 @@ type (
driverConfiguration struct {
t opentracing.Tracer
statementValues bool
stacktrace bool
connString string
componentName string
peerService string
Expand All @@ -41,6 +45,13 @@ func WithStatementValues() Option {
}
}

// Enable span stacktrace
func WithStacktrace() Option {
return func(d *instrumentedDriver) {
d.configuration.stacktrace = true
}
}

// Wraps the current sql driver to add instrumentation
func WrapDriver(d driver.Driver, options ...Option) driver.Driver {
wrapper := &instrumentedDriver{
Expand All @@ -54,6 +65,7 @@ func WrapDriver(d driver.Driver, options ...Option) driver.Driver {
option(wrapper)
}
wrapper.configuration.statementValues = wrapper.configuration.statementValues || env.ScopeInstrumentationDbStatementValues.Value
wrapper.configuration.stacktrace = wrapper.configuration.stacktrace || env.ScopeInstrumentationDbStacktrace.Value
return wrapper
}

Expand Down Expand Up @@ -106,6 +118,11 @@ func (t *driverConfiguration) newSpan(operationName string, query string, args [
"db.instance": c.instance,
"peer.hostname": c.host,
})
if t.stacktrace {
opts = append(opts, opentracing.Tags{
"stacktrace": scopeerrors.GetCurrentStackTrace(2),
})
}
if query != "" {
stIndex := strings.IndexRune(query, ' ')
var method string
Expand Down