Skip to content

Commit

Permalink
contrib/go-chi: Apply DD_TRACE_HTTP_SERVER_ERROR_STATUSES (#2960)
Browse files Browse the repository at this point in the history
  • Loading branch information
mtoffl01 authored Nov 6, 2024
1 parent c9fc691 commit 5dd43b0
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 18 deletions.
36 changes: 36 additions & 0 deletions contrib/go-chi/chi.v5/chi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"testing"

pappsec "gopkg.in/DataDog/dd-trace-go.v1/appsec"
"gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/httptrace"
"gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/namingschematest"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/mocktracer"
Expand Down Expand Up @@ -207,6 +208,41 @@ func TestError(t *testing.T) {
wantErr := fmt.Sprintf("%d: %s", code, http.StatusText(code))
assert.Equal(wantErr, span.Tag(ext.Error).(error).Error())
})
t.Run("envvar", func(t *testing.T) {
assert := assert.New(t)
t.Setenv("DD_TRACE_HTTP_SERVER_ERROR_STATUSES", "200")
mt := mocktracer.Start()
defer mt.Stop()

// re-run config defaults based on new DD_TRACE_HTTP_SERVER_ERROR_STATUSES value
httptrace.ResetCfg()

router := chi.NewRouter()
router.Use(Middleware(
WithServiceName("foobar")))
code := 200
// a handler with an error and make the requests
router.Get("/err", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("%d!", code), code)
})
r := httptest.NewRequest("GET", "/err", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, r)
response := w.Result()
defer response.Body.Close()
assert.Equal(response.StatusCode, code)

spans := mt.FinishedSpans()
assert.Len(spans, 1)
span := spans[0]
if span.Tag(ext.Error) == nil {
t.Fatal("Span missing error tags")
}
assertSpan(assert, span, code)
wantErr := fmt.Sprintf("%d: %s", code, http.StatusText(code))
assert.Equal(wantErr, span.Tag(ext.Error).(error).Error())

})
t.Run("integration overrides global", func(t *testing.T) {
assert := assert.New(t)
mt := mocktracer.Start()
Expand Down
5 changes: 0 additions & 5 deletions contrib/go-chi/chi.v5/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ func defaults(cfg *config) {
cfg.analyticsRate = globalconfig.AnalyticsRate()
}
cfg.headerTags = globalconfig.HeaderTagMap()
cfg.isStatusError = isServerError
cfg.ignoreRequest = func(_ *http.Request) bool { return false }
cfg.modifyResourceName = func(s string) string { return s }
// for backward compatibility with modifyResourceName, initialize resourceName as nil.
Expand Down Expand Up @@ -97,10 +96,6 @@ func WithStatusCheck(fn func(statusCode int) bool) Option {
}
}

func isServerError(statusCode int) bool {
return statusCode >= 500 && statusCode < 600
}

// WithIgnoreRequest specifies a function to use for determining if the
// incoming HTTP request tracing should be skipped.
func WithIgnoreRequest(fn func(r *http.Request) bool) Option {
Expand Down
35 changes: 35 additions & 0 deletions contrib/go-chi/chi/chi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"testing"

pappsec "gopkg.in/DataDog/dd-trace-go.v1/appsec"
"gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/httptrace"
"gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/namingschematest"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/mocktracer"
Expand Down Expand Up @@ -179,6 +180,40 @@ func TestError(t *testing.T) {
wantErr := fmt.Sprintf("%d: %s", code, http.StatusText(code))
assert.Equal(wantErr, span.Tag(ext.Error).(error).Error())
})
t.Run("envvar", func(t *testing.T) {
assert := assert.New(t)
t.Setenv("DD_TRACE_HTTP_SERVER_ERROR_STATUSES", "200")
mt := mocktracer.Start()
defer mt.Stop()

// re-run config defaults based on new DD_TRACE_HTTP_SERVER_ERROR_STATUSES value
httptrace.ResetCfg()

router := chi.NewRouter()
router.Use(Middleware(
WithServiceName("foobar")))
code := 200
// a handler with an error and make the requests
router.Get("/err", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("%d!", code), code)
})
r := httptest.NewRequest("GET", "/err", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, r)
response := w.Result()
defer response.Body.Close()
assert.Equal(response.StatusCode, code)

spans := mt.FinishedSpans()
assert.Len(spans, 1)
span := spans[0]
if span.Tag(ext.Error) == nil {
t.Fatal("Span missing error tags")
}
assertSpan(assert, span, code)
wantErr := fmt.Sprintf("%d: %s", code, http.StatusText(code))
assert.Equal(wantErr, span.Tag(ext.Error).(error).Error())
})
t.Run("integration overrides global", func(t *testing.T) {
assert := assert.New(t)
mt := mocktracer.Start()
Expand Down
5 changes: 0 additions & 5 deletions contrib/go-chi/chi/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func defaults(cfg *config) {
cfg.analyticsRate = globalconfig.AnalyticsRate()
}
cfg.headerTags = globalconfig.HeaderTagMap()
cfg.isStatusError = isServerError
cfg.ignoreRequest = func(_ *http.Request) bool { return false }
cfg.resourceNamer = func(r *http.Request) string {
resourceName := chi.RouteContext(r.Context()).RoutePattern()
Expand Down Expand Up @@ -99,10 +98,6 @@ func WithStatusCheck(fn func(statusCode int) bool) Option {
}
}

func isServerError(statusCode int) bool {
return statusCode >= 500 && statusCode < 600
}

// WithHeaderTags enables the integration to attach HTTP request headers as span tags.
// Warning:
// Using this feature can risk exposing sensitive data such as authorization tokens to Datadog.
Expand Down
5 changes: 5 additions & 0 deletions contrib/internal/httptrace/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ type config struct {
isStatusError func(statusCode int) bool
}

// ResetCfg sets local variable cfg back to its defaults (mainly useful for testing)
func ResetCfg() {
cfg = newConfig()
}

func newConfig() config {
c := config{
queryString: !internal.BoolEnv(envQueryStringDisabled, false),
Expand Down
12 changes: 4 additions & 8 deletions contrib/internal/httptrace/httptrace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,8 @@ func TestConfiguredErrorStatuses(t *testing.T) {

os.Setenv("DD_TRACE_HTTP_SERVER_ERROR_STATUSES", "199-399,400,501")

// reset config based on new DD_TRACE_HTTP_SERVER_ERROR_STATUSES value
oldConfig := cfg
defer func() { cfg = oldConfig }()
cfg = newConfig()
// re-run config defaults based on new DD_TRACE_HTTP_SERVER_ERROR_STATUSES value
ResetCfg()

statuses := []int{0, 200, 400, 500}
r := httptest.NewRequest(http.MethodGet, "/test", nil)
Expand Down Expand Up @@ -123,10 +121,8 @@ func TestConfiguredErrorStatuses(t *testing.T) {

os.Setenv("DD_TRACE_HTTP_SERVER_ERROR_STATUSES", "0")

// reset config based on new DD_TRACE_HTTP_SERVER_ERROR_STATUSES value
oldConfig := cfg
defer func() { cfg = oldConfig }()
cfg = newConfig()
// re-run config defaults based on new DD_TRACE_HTTP_SERVER_ERROR_STATUSES value
ResetCfg()

r := httptest.NewRequest(http.MethodGet, "/test", nil)
sp, _ := StartRequestSpan(r)
Expand Down

0 comments on commit 5dd43b0

Please sign in to comment.