Skip to content

Commit

Permalink
contrib/gin-gonic/gin: support globalconfig.ServiceName()
Browse files Browse the repository at this point in the history
This change adds support for `globalconfig.ServiceName()` to the gin
trace middleware. Because this middleware does not follow the same pattern
as other http frameworks and requires a service parameter to be passed in
we use the empty string value as an indicator that the default service
name should be used.

Fixes DataDog#767
  • Loading branch information
marcind committed Nov 17, 2020
1 parent 54f03f4 commit 077c280
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 4 deletions.
7 changes: 4 additions & 3 deletions contrib/gin-gonic/gin/gintrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ import (
"github.com/gin-gonic/gin"
)

// Middleware returns middleware that will trace incoming requests.
// Middleware returns middleware that will trace incoming requests. If service is empty then the
// default service name will be used.
func Middleware(service string, opts ...Option) gin.HandlerFunc {
cfg := newConfig()
cfg := newConfig(service)
for _, opt := range opts {
opt(cfg)
}
return func(c *gin.Context) {
resource := cfg.resourceNamer(c)
opts := []ddtrace.StartSpanOption{
tracer.ServiceName(service),
tracer.ServiceName(cfg.serviceName),
tracer.ResourceName(resource),
tracer.SpanType(ext.SpanTypeWeb),
tracer.Tag(ext.HTTPMethod, c.Request.Method),
Expand Down
92 changes: 92 additions & 0 deletions contrib/gin-gonic/gin/gintrace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,95 @@ func TestResourceNamerSettings(t *testing.T) {
router.ServeHTTP(w, r)
})
}

func TestServiceName(t *testing.T) {
t.Run("default", func(t *testing.T) {
assert := assert.New(t)
mt := mocktracer.Start()
defer mt.Stop()

router := gin.New()
router.Use(Middleware(""))
router.GET("/ping", func(c *gin.Context) {
span, ok := tracer.SpanFromContext(c.Request.Context())
assert.True(ok)
assert.Equal(span.(mocktracer.Span).Tag(ext.ServiceName), "gin.router")
c.Status(200)
})

r := httptest.NewRequest("GET", "/ping", nil)
w := httptest.NewRecorder()

// do and verify the request
router.ServeHTTP(w, r)
response := w.Result()
assert.Equal(response.StatusCode, 200)

// verify traces look good
spans := mt.FinishedSpans()
assert.Len(spans, 1)
span := spans[0]
assert.Equal("gin.router", span.Tag(ext.ServiceName))
})

t.Run("global", func(t *testing.T) {
globalconfig.SetServiceName("global-service")
defer globalconfig.SetServiceName("")

assert := assert.New(t)
mt := mocktracer.Start()
defer mt.Stop()

router := gin.New()
router.Use(Middleware(""))
router.GET("/ping", func(c *gin.Context) {
span, ok := tracer.SpanFromContext(c.Request.Context())
assert.True(ok)
assert.Equal(span.(mocktracer.Span).Tag(ext.ServiceName), "global-service")
c.Status(200)
})

r := httptest.NewRequest("GET", "/ping", nil)
w := httptest.NewRecorder()

// do and verify the request
router.ServeHTTP(w, r)
response := w.Result()
assert.Equal(response.StatusCode, 200)

// verify traces look good
spans := mt.FinishedSpans()
assert.Len(spans, 1)
span := spans[0]
assert.Equal("global-service", span.Tag(ext.ServiceName))
})

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

router := gin.New()
router.Use(Middleware("my-service"))
router.GET("/ping", func(c *gin.Context) {
span, ok := tracer.SpanFromContext(c.Request.Context())
assert.True(ok)
assert.Equal(span.(mocktracer.Span).Tag(ext.ServiceName), "my-service")
c.Status(200)
})

r := httptest.NewRequest("GET", "/ping", nil)
w := httptest.NewRecorder()

// do and verify the request
router.ServeHTTP(w, r)
response := w.Result()
assert.Equal(response.StatusCode, 200)

// verify traces look good
spans := mt.FinishedSpans()
assert.Len(spans, 1)
span := spans[0]
assert.Equal("my-service", span.Tag(ext.ServiceName))
})
}
10 changes: 9 additions & 1 deletion contrib/gin-gonic/gin/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,24 @@ import (
type config struct {
analyticsRate float64
resourceNamer func(c *gin.Context) string
serviceName string
}

func newConfig() *config {
func newConfig(service string) *config {
if service == "" {
service = "gin.router"
if svc := globalconfig.ServiceName(); svc != "" {
service = svc
}
}
rate := globalconfig.AnalyticsRate()
if internal.BoolEnv("DD_TRACE_GIN_ANALYTICS_ENABLED", false) {
rate = 1.0
}
return &config{
analyticsRate: rate,
resourceNamer: defaultResourceNamer,
serviceName: service,
}
}

Expand Down

0 comments on commit 077c280

Please sign in to comment.