1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-11-25 22:41:46 +02:00

Support capturing stack trace (#2163)

* capturing stack trace support

* added changelog entry

* remove error package stack trace support

* modified unnecessary changes to go.sum files

* added EventOption to enable stack trace capturing

* added tests

* added runtime.Stack method and minor changes

* minor changes

* remove redundant line

* fix gihub check on linter

* fix tests

* fix tests

* Update sdk/trace/trace_test.go

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>

* Update sdk/trace/trace_test.go

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>
This commit is contained in:
Bhautik Pipaliya
2021-08-13 14:44:18 -07:00
committed by GitHub
parent 41588fea26
commit dfc866bd03
5 changed files with 168 additions and 5 deletions

View File

@@ -1154,6 +1154,58 @@ func TestRecordError(t *testing.T) {
}
}
func TestRecordErrorWithStackTrace(t *testing.T) {
err := ottest.NewTestError("test error")
typ := "go.opentelemetry.io/otel/internal/internaltest.TestError"
msg := "test error"
te := NewTestExporter()
tp := NewTracerProvider(WithSyncer(te), WithResource(resource.Empty()))
span := startSpan(tp, "RecordError")
errTime := time.Now()
span.RecordError(err, trace.WithTimestamp(errTime), trace.WithStackTrace(true))
got, err := endSpan(te, span)
if err != nil {
t.Fatal(err)
}
want := &snapshot{
spanContext: trace.NewSpanContext(trace.SpanContextConfig{
TraceID: tid,
TraceFlags: 0x1,
}),
parent: sc.WithRemote(true),
name: "span0",
status: Status{Code: codes.Unset},
spanKind: trace.SpanKindInternal,
events: []Event{
{
Name: semconv.ExceptionEventName,
Time: errTime,
Attributes: []attribute.KeyValue{
semconv.ExceptionTypeKey.String(typ),
semconv.ExceptionMessageKey.String(msg),
},
},
},
instrumentationLibrary: instrumentation.Library{Name: "RecordError"},
}
assert.Equal(t, got.spanContext, want.spanContext)
assert.Equal(t, got.parent, want.parent)
assert.Equal(t, got.name, want.name)
assert.Equal(t, got.status, want.status)
assert.Equal(t, got.spanKind, want.spanKind)
assert.Equal(t, got.events[0].Attributes[0].Value.AsString(), want.events[0].Attributes[0].Value.AsString())
assert.Equal(t, got.events[0].Attributes[1].Value.AsString(), want.events[0].Attributes[1].Value.AsString())
gotStackTraceFunctionName := strings.Split(got.events[0].Attributes[2].Value.AsString(), "\n")
assert.True(t, strings.HasPrefix(gotStackTraceFunctionName[1], "go.opentelemetry.io/otel/sdk/trace.recordStackTrace"))
assert.True(t, strings.HasPrefix(gotStackTraceFunctionName[3], "go.opentelemetry.io/otel/sdk/trace.(*span).RecordError"))
}
func TestRecordErrorNil(t *testing.T) {
te := NewTestExporter()
tp := NewTracerProvider(WithSyncer(te), WithResource(resource.Empty()))
@@ -1361,6 +1413,32 @@ func TestSpanCapturesPanic(t *testing.T) {
})
}
func TestSpanCapturesPanicWithStackTrace(t *testing.T) {
te := NewTestExporter()
tp := NewTracerProvider(WithSyncer(te), WithResource(resource.Empty()))
_, span := tp.Tracer("CatchPanic").Start(
context.Background(),
"span",
)
f := func() {
defer span.End(trace.WithStackTrace(true))
panic(errors.New("error message"))
}
require.PanicsWithError(t, "error message", f)
spans := te.Spans()
require.Len(t, spans, 1)
require.Len(t, spans[0].Events(), 1)
assert.Equal(t, spans[0].Events()[0].Name, semconv.ExceptionEventName)
assert.Equal(t, spans[0].Events()[0].Attributes[0].Value.AsString(), "*errors.errorString")
assert.Equal(t, spans[0].Events()[0].Attributes[1].Value.AsString(), "error message")
gotStackTraceFunctionName := strings.Split(spans[0].Events()[0].Attributes[2].Value.AsString(), "\n")
fmt.Println(strings.Split(gotStackTraceFunctionName[1], "(0x")[0])
assert.True(t, strings.HasPrefix(gotStackTraceFunctionName[1], "go.opentelemetry.io/otel/sdk/trace.recordStackTrace"))
assert.True(t, strings.HasPrefix(gotStackTraceFunctionName[3], "go.opentelemetry.io/otel/sdk/trace.(*span).End"))
}
func TestReadOnlySpan(t *testing.T) {
kv := attribute.String("foo", "bar")