Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2: migrate grpc contrib to new instrumentation api #2827

Closed
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: 1 addition & 1 deletion appsec/appsec.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import (
"github.com/DataDog/dd-trace-go/v2/ddtrace/ext"
"github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
"github.com/DataDog/dd-trace-go/v2/instrumentation/appsec/emitter/httpsec"
"github.com/DataDog/dd-trace-go/v2/instrumentation/appsec/emitter/sharedsec"
"github.com/DataDog/dd-trace-go/v2/internal/appsec"
"github.com/DataDog/dd-trace-go/v2/internal/appsec/emitter/sharedsec"
"github.com/DataDog/dd-trace-go/v2/internal/log"
)

Expand Down
4 changes: 2 additions & 2 deletions contrib/cloud.google.com/go/pubsub.v1/pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import (
"github.com/DataDog/dd-trace-go/v2/instrumentation"
)

const componentName = instrumentation.PackageCloudGoogleComPubsub
const componentName = instrumentation.PackageGCPPubsub

var instr *instrumentation.Instrumentation

func init() {
instr = instrumentation.Load(instrumentation.PackageCloudGoogleComPubsub)
instr = instrumentation.Load(instrumentation.PackageGCPPubsub)
}

// Publish publishes a message on the specified topic and returns a PublishResult.
Expand Down
2 changes: 1 addition & 1 deletion contrib/gin-gonic/gin/gintrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const componentName = "gin-gonic/gin"
var instr *instrumentation.Instrumentation

func init() {
instr = instrumentation.Load(instrumentation.PackageGinGonicGin)
instr = instrumentation.Load(instrumentation.PackageGin)
}

// Middleware returns middleware that will trace incoming requests. If service is empty then the
Expand Down
15 changes: 7 additions & 8 deletions contrib/go-chi/chi.v5/chi.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,20 @@ import (

"github.com/DataDog/dd-trace-go/v2/ddtrace/ext"
"github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
"github.com/DataDog/dd-trace-go/v2/instrumentation"
"github.com/DataDog/dd-trace-go/v2/instrumentation/httptrace"
"github.com/DataDog/dd-trace-go/v2/instrumentation/options"
"github.com/DataDog/dd-trace-go/v2/internal/appsec"
"github.com/DataDog/dd-trace-go/v2/internal/contrib/httptrace"
"github.com/DataDog/dd-trace-go/v2/internal/log"
"github.com/DataDog/dd-trace-go/v2/internal/telemetry"

"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)

const componentName = "go-chi/chi.v5"

var instr *instrumentation.Instrumentation

func init() {
telemetry.LoadIntegration(componentName)
tracer.MarkIntegrationImported("github.com/go-chi/chi/v5")
instr = instrumentation.Load(instrumentation.PackageChiV5)
}

// Middleware returns middleware that will trace incoming requests.
Expand All @@ -37,7 +36,7 @@ func Middleware(opts ...Option) func(next http.Handler) http.Handler {
for _, fn := range opts {
fn.apply(cfg)
}
log.Debug("contrib/go-chi/chi.v5: Configuring Middleware: %#v", cfg)
instr.Logger().Debug("contrib/go-chi/chi.v5: Configuring Middleware: %#v", cfg)
spanOpts := append(cfg.spanOpts, tracer.ServiceName(cfg.serviceName),
tracer.Tag(ext.Component, componentName),
tracer.Tag(ext.SpanKind, ext.SpanKindServer))
Expand Down Expand Up @@ -67,7 +66,7 @@ func Middleware(opts ...Option) func(next http.Handler) http.Handler {
r = r.WithContext(ctx)

next := next // avoid modifying the value of next in the outer closure scope
if appsec.Enabled() && !cfg.appsecDisabled {
if instr.AppSecEnabled() && !cfg.appsecDisabled {
next = withAppsec(next, r, span, &cfg.appsecConfig)
// Note that the following response writer passed to the handler
// implements the `interface { Status() int }` expected by httpsec.
Expand Down
80 changes: 23 additions & 57 deletions contrib/go-chi/chi.v5/chi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ import (
"sync"
"testing"

pappsec "github.com/DataDog/dd-trace-go/v2/appsec"
"github.com/DataDog/dd-trace-go/v2/appsec"
"github.com/DataDog/dd-trace-go/v2/ddtrace/ext"
"github.com/DataDog/dd-trace-go/v2/ddtrace/mocktracer"
"github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
"github.com/DataDog/dd-trace-go/v2/internal/appsec"
"github.com/DataDog/dd-trace-go/v2/internal/contrib/namingschematest"
"github.com/DataDog/dd-trace-go/v2/internal/globalconfig"
"github.com/DataDog/dd-trace-go/v2/internal/normalizer"
"github.com/DataDog/dd-trace-go/v2/instrumentation"
"github.com/DataDog/dd-trace-go/v2/instrumentation/testutils"

"github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -279,9 +277,7 @@ func TestAnalyticsSettings(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

rate := globalconfig.AnalyticsRate()
defer globalconfig.SetAnalyticsRate(rate)
globalconfig.SetAnalyticsRate(0.4)
testutils.SetGlobalAnalyticsRate(t, 0.4)

assertRate(t, mt, 0.4)
})
Expand All @@ -304,9 +300,7 @@ func TestAnalyticsSettings(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

rate := globalconfig.AnalyticsRate()
defer globalconfig.SetAnalyticsRate(rate)
globalconfig.SetAnalyticsRate(0.4)
testutils.SetGlobalAnalyticsRate(t, 0.4)

assertRate(t, mt, 0.23, WithAnalyticsRate(0.23))
})
Expand Down Expand Up @@ -342,10 +336,9 @@ func TestIgnoreRequest(t *testing.T) {
}

func TestAppSec(t *testing.T) {
appsec.Start()
defer appsec.Stop()
testutils.StartAppSec(t)

if !appsec.Enabled() {
if !instr.AppSecEnabled() {
t.Skip("appsec disabled")
}

Expand All @@ -360,7 +353,7 @@ func TestAppSec(t *testing.T) {
require.NoError(t, err)
})
router.HandleFunc("/body", func(w http.ResponseWriter, r *http.Request) {
pappsec.MonitorParsedHTTPBody(r.Context(), "$globals")
appsec.MonitorParsedHTTPBody(r.Context(), "$globals")
_, err := w.Write([]byte("Hello Body!\n"))
require.NoError(t, err)
})
Expand Down Expand Up @@ -478,90 +471,63 @@ func TestWithHeaderTags(t *testing.T) {
assert := assert.New(t)
assert.Equal(len(spans), 1)
s := spans[0]
for _, arg := range htArgs {
_, tag := normalizer.HeaderTag(arg)

instrumentation.NewHeaderTags(htArgs).Iter(func(_ string, tag string) {
assert.NotContains(s.Tags(), tag)
}
})
})

t.Run("integration", func(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

htArgs := []string{"[email protected]*r", "2header:tag"}
r := setupReq(WithHeaderTags(htArgs))
_ = setupReq(WithHeaderTags(htArgs))
spans := mt.FinishedSpans()
assert := assert.New(t)
assert.Equal(len(spans), 1)
s := spans[0]

for _, arg := range htArgs {
header, tag := normalizer.HeaderTag(arg)
assert.Equal(strings.Join(r.Header.Values(header), ","), s.Tags()[tag])
}
assert.Equal("val,val2", s.Tags()["http.request.headers.h_e_a-d_e_r"])
assert.Equal("2val", s.Tags()["tag"])
assert.NotContains(s.Tags(), "http.headers.x-datadog-header")
})

t.Run("global", func(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

header, tag := normalizer.HeaderTag("3header")
globalconfig.SetHeaderTag(header, tag)
testutils.SetGlobalHeaderTags(t, "3header")

r := setupReq()
_ = setupReq()
spans := mt.FinishedSpans()
assert := assert.New(t)
assert.Equal(len(spans), 1)
s := spans[0]

assert.Equal(strings.Join(r.Header.Values(header), ","), s.Tags()[tag])
assert.Equal("3val", s.Tags()["http.request.headers.3header"])
assert.NotContains(s.Tags(), "http.request.headers.other")
assert.NotContains(s.Tags(), "http.headers.x-datadog-header")
})

t.Run("override", func(t *testing.T) {
mt := mocktracer.Start()
defer mt.Stop()

globalH, globalT := normalizer.HeaderTag("3header")
globalconfig.SetHeaderTag(globalH, globalT)
testutils.SetGlobalHeaderTags(t, "3header")

htArgs := []string{"[email protected]*r", "2header:tag"}
r := setupReq(WithHeaderTags(htArgs))
_ = setupReq(WithHeaderTags(htArgs))
spans := mt.FinishedSpans()
assert := assert.New(t)
assert.Equal(len(spans), 1)
s := spans[0]

for _, arg := range htArgs {
header, tag := normalizer.HeaderTag(arg)
assert.Equal(strings.Join(r.Header.Values(header), ","), s.Tags()[tag])
}
assert.Equal("val,val2", s.Tags()["http.request.headers.h_e_a-d_e_r"])
assert.Equal("2val", s.Tags()["tag"])
assert.NotContains(s.Tags(), "http.headers.x-datadog-header")
assert.NotContains(s.Tags(), globalT)
})
}
func TestNamingSchema(t *testing.T) {
genSpans := namingschematest.GenSpansFn(func(t *testing.T, serviceOverride string) []*mocktracer.Span {
var opts []Option
if serviceOverride != "" {
opts = append(opts, WithService(serviceOverride))
}
mt := mocktracer.Start()
defer mt.Stop()

mux := chi.NewRouter().With(Middleware(opts...))
mux.HandleFunc("/200", func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("ok"))
require.NoError(t, err)
})
r := httptest.NewRequest("GET", "/200", nil)
w := httptest.NewRecorder()
mux.ServeHTTP(w, r)

return mt.FinishedSpans()
assert.NotContains(s.Tags(), "http.request.headers.3header")
})
namingschematest.NewHTTPServerTest(genSpans, "chi.router")(t)
}

func TestCustomResourceName(t *testing.T) {
Expand Down
22 changes: 6 additions & 16 deletions contrib/go-chi/chi.v5/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,18 @@ import (
"net/http"

"github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
"github.com/DataDog/dd-trace-go/v2/instrumentation"
"github.com/DataDog/dd-trace-go/v2/instrumentation/appsec/emitter/httpsec"
"github.com/DataDog/dd-trace-go/v2/internal"
"github.com/DataDog/dd-trace-go/v2/internal/globalconfig"
"github.com/DataDog/dd-trace-go/v2/internal/namingschema"
"github.com/DataDog/dd-trace-go/v2/internal/normalizer"
)

const defaultServiceName = "chi.router"

type config struct {
serviceName string
spanOpts []tracer.StartSpanOption // additional span options to be applied
analyticsRate float64
isStatusError func(statusCode int) bool
ignoreRequest func(r *http.Request) bool
modifyResourceName func(resourceName string) string
headerTags *internal.LockMap
headerTags instrumentation.HeaderTags
resourceNamer func(r *http.Request) string
appsecDisabled bool
appsecConfig httpsec.Config
Expand All @@ -45,13 +40,9 @@ func (fn OptionFn) apply(cfg *config) {
}

func defaults(cfg *config) {
cfg.serviceName = namingschema.ServiceName(defaultServiceName)
if internal.BoolEnv("DD_TRACE_CHI_ANALYTICS_ENABLED", false) {
cfg.analyticsRate = 1.0
} else {
cfg.analyticsRate = globalconfig.AnalyticsRate()
}
cfg.headerTags = globalconfig.HeaderTagMap()
cfg.serviceName = instr.ServiceName(instrumentation.ComponentServer, nil)
cfg.analyticsRate = instr.AnalyticsRate(true)
cfg.headerTags = instr.HTTPHeadersAsTags()
cfg.isStatusError = isServerError
cfg.ignoreRequest = func(_ *http.Request) bool { return false }
cfg.modifyResourceName = func(s string) string { return s }
Expand Down Expand Up @@ -130,9 +121,8 @@ func WithModifyResourceName(fn func(resourceName string) string) OptionFn {
// Using this feature can risk exposing sensitive data such as authorization tokens to Datadog.
// Special headers can not be sub-selected. E.g., an entire Cookie header would be transmitted, without the ability to choose specific Cookies.
func WithHeaderTags(headers []string) OptionFn {
headerTagsMap := normalizer.HeaderTagSlice(headers)
return func(cfg *config) {
cfg.headerTags = internal.NewLockMap(headerTagsMap)
cfg.headerTags = instrumentation.NewHeaderTags(headers)
}
}

Expand Down
15 changes: 7 additions & 8 deletions contrib/go-chi/chi/chi.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,20 @@ import (

"github.com/DataDog/dd-trace-go/v2/ddtrace/ext"
"github.com/DataDog/dd-trace-go/v2/ddtrace/tracer"
"github.com/DataDog/dd-trace-go/v2/instrumentation"
"github.com/DataDog/dd-trace-go/v2/instrumentation/httptrace"
"github.com/DataDog/dd-trace-go/v2/instrumentation/options"
"github.com/DataDog/dd-trace-go/v2/internal/appsec"
"github.com/DataDog/dd-trace-go/v2/internal/contrib/httptrace"
"github.com/DataDog/dd-trace-go/v2/internal/log"
"github.com/DataDog/dd-trace-go/v2/internal/telemetry"

"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
)

const componentName = "go-chi/chi"

var instr *instrumentation.Instrumentation

func init() {
telemetry.LoadIntegration(componentName)
tracer.MarkIntegrationImported("github.com/go-chi/chi")
instr = instrumentation.Load(instrumentation.PackageChi)
}

// Middleware returns middleware that will trace incoming requests.
Expand All @@ -37,7 +36,7 @@ func Middleware(opts ...Option) func(next http.Handler) http.Handler {
for _, fn := range opts {
fn.apply(cfg)
}
log.Debug("contrib/go-chi/chi: Configuring Middleware: %#v", cfg)
instr.Logger().Debug("contrib/go-chi/chi: Configuring Middleware: %#v", cfg)
spanOpts := append(cfg.spanOpts, tracer.ServiceName(cfg.serviceName),
tracer.Tag(ext.Component, componentName),
tracer.Tag(ext.SpanKind, ext.SpanKindServer))
Expand Down Expand Up @@ -67,7 +66,7 @@ func Middleware(opts ...Option) func(next http.Handler) http.Handler {
r = r.WithContext(ctx)

next := next // avoid modifying the value of next in the outer closure scope
if appsec.Enabled() {
if instr.AppSecEnabled() {
next = withAppsec(next, r, span)
// Note that the following response writer passed to the handler
// implements the `interface { Status() int }` expected by httpsec.
Expand Down
Loading
Loading