Skip to content

Commit 64ea958

Browse files
hannahkmkakkoyun
andauthored
feat: do not report error stack for status code errors (#3837)
Co-authored-by: kakkoyun <[email protected]>
1 parent e2c8d45 commit 64ea958

File tree

7 files changed

+58
-27
lines changed

7 files changed

+58
-27
lines changed

contrib/gofiber/fiber.v2/fiber.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func Middleware(opts ...Option) func(c *fiber.Ctx) error {
9898
span.SetTag(ext.Error, err)
9999
} else if cfg.isStatusError(status) {
100100
// mark 5xx server error
101-
span.SetTag(ext.Error, fmt.Errorf("%d: %s", status, http.StatusText(status)))
101+
span.SetTag(ext.ErrorNoStackTrace, fmt.Errorf("%d: %s", status, http.StatusText(status)))
102102
}
103103
return err
104104
}

contrib/net/http/internal/wrap/roundtrip.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ func ObserveRoundTrip(cfg *config.RoundTripperConfig, req *http.Request) (*http.
174174
span.SetTag(ext.HTTPCode, strconv.Itoa(resp.StatusCode))
175175
if cfg.IsStatusError(resp.StatusCode) {
176176
span.SetTag("http.errors", resp.Status)
177-
span.SetTag(ext.Error, fmt.Errorf("%d: %s", resp.StatusCode, http.StatusText(resp.StatusCode)))
177+
span.SetTag(ext.ErrorNoStackTrace, fmt.Errorf("%d: %s", resp.StatusCode, http.StatusText(resp.StatusCode)))
178178
}
179179
}
180180

contrib/valyala/fasthttp/fasthttp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func WrapHandler(h fasthttp.RequestHandler, opts ...Option) fasthttp.RequestHand
5555
span.SetTag(ext.ResourceName, cfg.resourceNamer(fctx))
5656
status := fctx.Response.StatusCode()
5757
if cfg.isStatusError(status) {
58-
span.SetTag(ext.Error, fmt.Errorf("%d: %s", status, string(fctx.Response.Body())))
58+
span.SetTag(ext.ErrorNoStackTrace, fmt.Errorf("%d: %s", status, string(fctx.Response.Body())))
5959
}
6060
span.SetTag(ext.HTTPCode, strconv.Itoa(status))
6161
}

ddtrace/ext/tags.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,19 @@ const (
8787
// ErrorType specifies the error type.
8888
ErrorType = "error.type"
8989

90-
// ErrorStack specifies the stack dump.
90+
// ErrorStack specifies the stack dump when the error is thrown.
9191
ErrorStack = "error.stack"
9292

93+
// ErrorHandlingStack specifies the stack dump when the error is captured.
94+
ErrorHandlingStack = "error.handling_stack"
95+
9396
// ErrorDetails holds details about an error which implements a formatter.
97+
// Deprecated: Use ErrorStack instead. This tag is not supported by Error Tracking.
9498
ErrorDetails = "error.details"
9599

100+
// ErrorNoStackTrace is a tag that specifies that the error stack trace should not be captured.
101+
ErrorNoStackTrace = "error.no_stack_trace"
102+
96103
// Environment specifies the environment to use with a trace.
97104
Environment = "env"
98105

ddtrace/tracer/span.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ func (s *Span) SetTag(key string, value interface{}) {
197197
noDebugStack: s.noDebugStack,
198198
})
199199
return
200+
case ext.ErrorNoStackTrace:
201+
s.setTagError(value, errorConfig{
202+
noDebugStack: true,
203+
})
204+
return
200205
case ext.Component:
201206
integration, ok := value.(string)
202207
if ok {
@@ -430,23 +435,23 @@ func (s *Span) setTagError(value interface{}, cfg errorConfig) {
430435
setError(true)
431436
s.setMeta(ext.ErrorMsg, v.Error())
432437
s.setMeta(ext.ErrorType, reflect.TypeOf(v).String())
438+
if cfg.noDebugStack {
439+
return
440+
}
433441
switch err := v.(type) {
434442
case xerrors.Formatter:
435-
s.setMeta(ext.ErrorDetails, fmt.Sprintf("%+v", v))
443+
s.setMeta(ext.ErrorStack, fmt.Sprintf("%+v", v))
436444
case fmt.Formatter:
437445
// pkg/errors approach
438-
s.setMeta(ext.ErrorDetails, fmt.Sprintf("%+v", v))
446+
s.setMeta(ext.ErrorStack, fmt.Sprintf("%+v", v))
439447
case *errortrace.TracerError:
440448
// instrumentation/errortrace approach
441-
s.setMeta(ext.ErrorDetails, fmt.Sprintf("%+v", v))
442-
if !cfg.noDebugStack {
443-
s.setMeta(ext.ErrorStack, err.Format())
444-
}
449+
s.setMeta(ext.ErrorStack, fmt.Sprintf("%+v", v))
450+
s.setMeta(ext.ErrorHandlingStack, err.Format())
445451
return
446452
}
447-
if !cfg.noDebugStack {
448-
s.setMeta(ext.ErrorStack, takeStacktrace(cfg.stackFrames, cfg.stackSkip))
449-
}
453+
stack := takeStacktrace(cfg.stackFrames, cfg.stackSkip)
454+
s.setMeta(ext.ErrorHandlingStack, stack)
450455
case nil:
451456
// no error
452457
setError(false)

ddtrace/tracer/span_test.go

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ func TestSpanFinishWithError(t *testing.T) {
339339
assert.Equal(int32(1), span.error)
340340
assert.Equal("test error", span.meta[ext.ErrorMsg])
341341
assert.Equal("*errors.errorString", span.meta[ext.ErrorType])
342-
assert.NotEmpty(span.meta[ext.ErrorStack])
342+
assert.NotEmpty(span.meta[ext.ErrorHandlingStack])
343343
}
344344

345345
func TestSpanFinishWithErrorNoDebugStack(t *testing.T) {
@@ -365,9 +365,9 @@ func TestSpanFinishWithErrorStackFrames(t *testing.T) {
365365
assert.Equal(int32(1), span.error)
366366
assert.Equal("test error", span.meta[ext.ErrorMsg])
367367
assert.Equal("*errors.errorString", span.meta[ext.ErrorType])
368-
assert.Contains(span.meta[ext.ErrorStack], "tracer.TestSpanFinishWithErrorStackFrames")
369-
assert.Contains(span.meta[ext.ErrorStack], "tracer.(*Span).Finish")
370-
assert.Equal(strings.Count(span.meta[ext.ErrorStack], "\n\t"), 2)
368+
assert.Contains(span.meta[ext.ErrorHandlingStack], "tracer.TestSpanFinishWithErrorStackFrames")
369+
assert.Contains(span.meta[ext.ErrorHandlingStack], "tracer.(*Span).Finish")
370+
assert.Equal(strings.Count(span.meta[ext.ErrorHandlingStack], "\n\t"), 2)
371371
}
372372

373373
// nilStringer is used to test nil detection when setting tags.
@@ -413,7 +413,7 @@ func TestSpanSetTag(t *testing.T) {
413413
assert.Equal(int32(1), span.error)
414414
assert.Equal("abc", span.meta[ext.ErrorMsg])
415415
assert.Equal("*errors.errorString", span.meta[ext.ErrorType])
416-
assert.NotEmpty(span.meta[ext.ErrorStack])
416+
assert.NotEmpty(span.meta[ext.ErrorHandlingStack])
417417

418418
span.SetTag(ext.Error, "something else")
419419
assert.Equal(int32(1), span.error)
@@ -523,7 +523,7 @@ func TestSpanSetTagError(t *testing.T) {
523523
t.Run("on", func(t *testing.T) {
524524
span := newBasicSpan("web.request")
525525
span.setTagError(errors.New("error value with trace"), errorConfig{noDebugStack: false})
526-
assert.NotEmpty(t, span.meta[ext.ErrorStack])
526+
assert.NotEmpty(t, span.meta[ext.ErrorHandlingStack])
527527
})
528528
}
529529

@@ -793,10 +793,11 @@ func TestErrorStack(t *testing.T) {
793793
assert.Equal("Something wrong", span.meta[ext.ErrorMsg])
794794
assert.Equal("*errortrace.TracerError", span.meta[ext.ErrorType])
795795

796-
stack := span.meta[ext.ErrorStack]
796+
stack := span.meta[ext.ErrorHandlingStack]
797797
assert.NotEqual("", stack)
798798
assert.Contains(stack, "tracer.TestErrorStack")
799799
assert.Contains(stack, "tracer.createErrorTrace")
800+
800801
span.Finish()
801802
})
802803

@@ -813,10 +814,11 @@ func TestErrorStack(t *testing.T) {
813814
assert.Equal("Something wrong", span.meta[ext.ErrorMsg])
814815
assert.Equal("*errors.errorString", span.meta[ext.ErrorType])
815816

816-
stack := span.meta[ext.ErrorStack]
817+
stack := span.meta[ext.ErrorHandlingStack]
817818
assert.NotEqual("", stack)
818819
assert.Contains(stack, "tracer.TestErrorStack")
819-
assert.NotContains(stack, "tracer.createTestError") // this checks our old behavior
820+
assert.NotContains(stack, "tracer.createTestError")
821+
820822
span.Finish()
821823
})
822824
}
@@ -835,7 +837,7 @@ func TestSpanError(t *testing.T) {
835837
assert.Equal(int32(1), span.error)
836838
assert.Equal("Something wrong", span.meta[ext.ErrorMsg])
837839
assert.Equal("*errors.errorString", span.meta[ext.ErrorType])
838-
assert.NotEqual("", span.meta[ext.ErrorStack])
840+
assert.NotEqual("", span.meta[ext.ErrorHandlingStack])
839841
span.Finish()
840842

841843
// operating on a finished span is a no-op
@@ -866,7 +868,7 @@ func TestSpanError_Typed(t *testing.T) {
866868
assert.Equal(int32(1), span.error)
867869
assert.Equal("boom", span.meta[ext.ErrorMsg])
868870
assert.Equal("*tracer.boomError", span.meta[ext.ErrorType])
869-
assert.NotEqual("", span.meta[ext.ErrorStack])
871+
assert.NotEqual("", span.meta[ext.ErrorHandlingStack])
870872
}
871873

872874
func TestSpanErrorNil(t *testing.T) {
@@ -978,7 +980,6 @@ func TestSpanErrorStackMetrics(t *testing.T) {
978980
}
979981

980982
assert.Equal(0.0, telemetryClient.Count(telemetry.NamespaceTracers, "errorstack.source", []string{"source:takeStacktrace"}).Get())
981-
assert.Equal(0.0, telemetryClient.Distribution(telemetry.NamespaceTracers, "errorstack.duration", []string{"source:takeStacktrace"}).Get())
982983

983984
assert.Equal(5.0, telemetryClient.Count(telemetry.NamespaceTracers, "errorstack.source", []string{"source:TracerError"}).Get())
984985
if !windows {
@@ -987,6 +988,24 @@ func TestSpanErrorStackMetrics(t *testing.T) {
987988
})
988989
}
989990

991+
func TestSpanErrorNoStackTrace(t *testing.T) {
992+
t.Run("default", func(t *testing.T) {
993+
assert := assert.New(t)
994+
tracer, _, _, stop, err := startTestTracer(t, WithDebugStack(true))
995+
assert.Nil(err)
996+
defer stop()
997+
998+
span := tracer.StartSpan("operation")
999+
span.SetTag(ext.ErrorNoStackTrace, errors.New("test"))
1000+
span.Finish()
1001+
1002+
assert.Equal(int32(1), span.error)
1003+
assert.Equal("", span.meta[ext.ErrorStack])
1004+
assert.Equal("test", span.meta[ext.ErrorMsg])
1005+
assert.Equal("*errors.errorString", span.meta[ext.ErrorType])
1006+
})
1007+
}
1008+
9901009
func TestUniqueTagKeys(t *testing.T) {
9911010
assert := assert.New(t)
9921011
span := newBasicSpan("web.request")

instrumentation/httptrace/httptrace.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,14 @@ func FinishRequestSpan(s *tracer.Span, status int, errorFn func(int) bool, opts
161161
if status == 0 {
162162
if fn(status) {
163163
statusStr = "0"
164-
s.SetTag(ext.Error, fmt.Errorf("%s: %s", statusStr, http.StatusText(status)))
164+
s.SetTag(ext.ErrorNoStackTrace, fmt.Errorf("%s: %s", statusStr, http.StatusText(status)))
165165
} else {
166166
statusStr = "200"
167167
}
168168
} else {
169169
statusStr = strconv.Itoa(status)
170170
if fn(status) {
171-
s.SetTag(ext.Error, fmt.Errorf("%s: %s", statusStr, http.StatusText(status)))
171+
s.SetTag(ext.ErrorNoStackTrace, fmt.Errorf("%s: %s", statusStr, http.StatusText(status)))
172172
}
173173
}
174174
fc := &tracer.FinishConfig{}

0 commit comments

Comments
 (0)