Skip to content

Commit

Permalink
contrib/gin-gonic/gin: Extract parent span info from HTTP Headers
Browse files Browse the repository at this point in the history
Use propagation features to try to get some span context in the incoming
request headers.

If the headers are not set, the comportment is the same as before

If a span is already present in the request's context, it will be
used primarily as the parent span.

Fixes #280
  • Loading branch information
samsaggace committed Jul 25, 2018
1 parent 0a3c14f commit 2423f7c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
9 changes: 7 additions & 2 deletions contrib/gin-gonic/gin/gintrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"strconv"

"gopkg.in/DataDog/dd-trace-go.v1/ddtrace"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"

Expand All @@ -16,13 +17,17 @@ import (
func Middleware(service string) gin.HandlerFunc {
return func(c *gin.Context) {
resource := c.HandlerName()
span, ctx := tracer.StartSpanFromContext(c.Request.Context(), "http.request",
opts := []ddtrace.StartSpanOption{
tracer.ServiceName(service),
tracer.ResourceName(resource),
tracer.SpanType(ext.AppTypeWeb),
tracer.Tag(ext.HTTPMethod, c.Request.Method),
tracer.Tag(ext.HTTPURL, c.Request.URL.Path),
)
}
if spanctx, err := tracer.Extract(tracer.HTTPHeadersCarrier(c.Request.Header)); err == nil {
opts = append(opts, tracer.ChildOf(spanctx))
}
span, ctx := tracer.StartSpanFromContext(c.Request.Context(), "http.request", opts...)
defer span.Finish()

// pass the span through the request context
Expand Down
24 changes: 24 additions & 0 deletions contrib/gin-gonic/gin/gintrace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,27 @@ func TestGetSpanNotInstrumented(t *testing.T) {
response := w.Result()
assert.Equal(response.StatusCode, 200)
}

func TestExtractSpan(t *testing.T) {
assert := assert.New(t)
mt := mocktracer.Start()
defer mt.Stop()

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

pspan := tracer.StartSpan("test")
tracer.Inject(pspan.Context(), tracer.HTTPHeadersCarrier(r.Header))

router := gin.New()
router.Use(Middleware("foobar"))
router.GET("/user/:id", func(c *gin.Context) {
span, ok := tracer.SpanFromContext(c.Request.Context())
assert.True(ok)

//Ensure current span if a child of the span injected in the HTTP request
assert.Equal(span.(mocktracer.Span).ParentID(), pspan.(mocktracer.Span).SpanID())
})

router.ServeHTTP(w, r)
}

0 comments on commit 2423f7c

Please sign in to comment.