Skip to content

Commit

Permalink
Tracing without performance improvements (#862)
Browse files Browse the repository at this point in the history
  • Loading branch information
cleptric committed Sep 4, 2024
1 parent 7085a1d commit 24ffea5
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 259 deletions.
9 changes: 3 additions & 6 deletions dynamic_sampling_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ func DynamicSamplingContextFromHeader(header []byte) (DynamicSamplingContext, er
}

func DynamicSamplingContextFromTransaction(span *Span) DynamicSamplingContext {
entries := map[string]string{}

hub := hubFromContext(span.Context())
scope := hub.Scope()
client := hub.Client()
Expand All @@ -52,6 +50,8 @@ func DynamicSamplingContextFromTransaction(span *Span) DynamicSamplingContext {
}
}

entries := make(map[string]string)

if traceID := span.TraceID.String(); traceID != "" {
entries["trace_id"] = traceID
}
Expand Down Expand Up @@ -80,10 +80,7 @@ func DynamicSamplingContextFromTransaction(span *Span) DynamicSamplingContext {

entries["sampled"] = strconv.FormatBool(span.Sampled.Bool())

return DynamicSamplingContext{
Entries: entries,
Frozen: true,
}
return DynamicSamplingContext{Entries: entries, Frozen: true}
}

func (d DynamicSamplingContext) HasEntries() bool {
Expand Down
6 changes: 3 additions & 3 deletions echo/sentryecho.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func New(options Options) echo.MiddlewareFunc {

func (h *handler) handle(next echo.HandlerFunc) echo.HandlerFunc {
return func(ctx echo.Context) error {
hub := sentry.GetHubFromContext(ctx.Request().Context())
hub := GetHubFromContext(ctx)
if hub == nil {
hub = sentry.CurrentHub().Clone()
}
Expand All @@ -70,8 +70,8 @@ func (h *handler) handle(next echo.HandlerFunc) echo.HandlerFunc {
}

options := []sentry.SpanOption{
sentry.ContinueTrace(hub, r.Header.Get(sentry.SentryTraceHeader), r.Header.Get(sentry.SentryBaggageHeader)),
sentry.WithOpName("http.server"),
sentry.ContinueFromRequest(r),
sentry.WithTransactionSource(transactionSource),
sentry.WithSpanOrigin(sentry.SpanOriginEcho),
}
Expand All @@ -82,7 +82,7 @@ func (h *handler) handle(next echo.HandlerFunc) echo.HandlerFunc {
options...,
)

transaction.SetData("http.request.method", ctx.Request().Method)
transaction.SetData("http.request.method", r.Method)

defer func() {
status := ctx.Response().Status
Expand Down
12 changes: 8 additions & 4 deletions fasthttp/sentryfasthttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,20 @@ func New(options Options) *Handler {
// Handle wraps fasthttp.RequestHandler and recovers from caught panics.
func (h *Handler) Handle(handler fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
hub := sentry.CurrentHub().Clone()
hub := GetHubFromContext(ctx)
if hub == nil {
hub = sentry.CurrentHub().Clone()
}

if client := hub.Client(); client != nil {
client.SetSDKIdentifier(sdkIdentifier)
}

convertedHTTPRequest := convert(ctx)
r := convert(ctx)

options := []sentry.SpanOption{
sentry.ContinueTrace(hub, r.Header.Get(sentry.SentryTraceHeader), r.Header.Get(sentry.SentryBaggageHeader)),
sentry.WithOpName("http.server"),
sentry.ContinueFromRequest(convertedHTTPRequest),
sentry.WithTransactionSource(sentry.SourceRoute),
sentry.WithSpanOrigin(sentry.SpanOriginFastHTTP),
}
Expand All @@ -90,11 +93,12 @@ func (h *Handler) Handle(handler fasthttp.RequestHandler) fasthttp.RequestHandle
transaction.SetData("http.request.method", method)

scope := hub.Scope()
scope.SetRequest(convertedHTTPRequest)
scope.SetRequest(r)
scope.SetRequestBody(ctx.Request.Body())
ctx.SetUserValue(valuesKey, hub)
ctx.SetUserValue(transactionKey, transaction)
defer h.recoverWithSentry(hub, ctx)

handler(ctx)
}
}
Expand Down
12 changes: 8 additions & 4 deletions fiber/sentryfiber.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,25 @@ func New(options Options) fiber.Handler {
}

func (h *handler) handle(ctx *fiber.Ctx) error {
hub := sentry.CurrentHub().Clone()
hub := GetHubFromContext(ctx)
if hub == nil {
hub = sentry.CurrentHub().Clone()
}

if client := hub.Client(); client != nil {
client.SetSDKIdentifier(sdkIdentifier)
}

convertedHTTPRequest := convert(ctx)
r := convert(ctx)

method := ctx.Method()

transactionName := ctx.Path()
transactionSource := sentry.SourceURL

options := []sentry.SpanOption{
sentry.ContinueTrace(hub, r.Header.Get(sentry.SentryTraceHeader), r.Header.Get(sentry.SentryBaggageHeader)),
sentry.WithOpName("http.server"),
sentry.ContinueFromRequest(convertedHTTPRequest),
sentry.WithTransactionSource(transactionSource),
sentry.WithSpanOrigin(sentry.SpanOriginFiber),
}
Expand All @@ -90,11 +93,12 @@ func (h *handler) handle(ctx *fiber.Ctx) error {
transaction.SetData("http.request.method", method)

scope := hub.Scope()
scope.SetRequest(convertedHTTPRequest)
scope.SetRequest(r)
scope.SetRequestBody(ctx.Request().Body())
ctx.Locals(valuesKey, hub)
ctx.Locals(transactionKey, transaction)
defer h.recoverWithSentry(hub, ctx)

return ctx.Next()
}

Expand Down
22 changes: 19 additions & 3 deletions gin/sentrygin.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
const sdkIdentifier = "sentry.go.gin"

const valuesKey = "sentry"
const transactionKey = "sentry_transaction"

type handler struct {
repanic bool
Expand Down Expand Up @@ -55,7 +56,6 @@ func (h *handler) handle(c *gin.Context) {
hub := sentry.GetHubFromContext(ctx)
if hub == nil {
hub = sentry.CurrentHub().Clone()
ctx = sentry.SetHubOnContext(ctx, hub)
}

if client := hub.Client(); client != nil {
Expand All @@ -71,17 +71,20 @@ func (h *handler) handle(c *gin.Context) {
}

options := []sentry.SpanOption{
sentry.ContinueTrace(hub, c.GetHeader(sentry.SentryTraceHeader), c.GetHeader(sentry.SentryBaggageHeader)),
sentry.WithOpName("http.server"),
sentry.ContinueFromRequest(c.Request),
sentry.WithTransactionSource(transactionSource),
sentry.WithSpanOrigin(sentry.SpanOriginGin),
}

transaction := sentry.StartTransaction(ctx,
transaction := sentry.StartTransaction(
sentry.SetHubOnContext(ctx, hub),
fmt.Sprintf("%s %s", c.Request.Method, transactionName),
options...,
)

transaction.SetData("http.request.method", c.Request.Method)

defer func() {
status := c.Writer.Status()
transaction.Status = sentry.HTTPtoSpanStatus(status)
Expand All @@ -92,7 +95,9 @@ func (h *handler) handle(c *gin.Context) {
c.Request = c.Request.WithContext(transaction.Context())
hub.Scope().SetRequest(c.Request)
c.Set(valuesKey, hub)
c.Set(transactionKey, transaction)
defer h.recoverWithSentry(hub, c.Request)

c.Next()
}

Expand Down Expand Up @@ -135,3 +140,14 @@ func GetHubFromContext(ctx *gin.Context) *sentry.Hub {
}
return nil
}

// GetSpanFromContext retrieves attached *sentry.Span instance from gin.Context.
// If there is no transaction on echo.Context, it will return nil.
func GetSpanFromContext(ctx *gin.Context) *sentry.Span {
if span, ok := ctx.Get(transactionKey); ok {
if span, ok := span.(*sentry.Span); ok {
return span
}
}
return nil
}
11 changes: 4 additions & 7 deletions http/sentryhttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (h *Handler) HandleFunc(handler http.HandlerFunc) http.HandlerFunc {
func (h *Handler) handle(handler http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
hub := sentry.GetHubFromContext(ctx)
hub := sentry.GetHubFromContext(r.Context())
if hub == nil {
hub = sentry.CurrentHub().Clone()
ctx = sentry.SetHubOnContext(ctx, hub)
Expand All @@ -95,8 +95,8 @@ func (h *Handler) handle(handler http.Handler) http.HandlerFunc {
}

options := []sentry.SpanOption{
sentry.ContinueTrace(hub, r.Header.Get(sentry.SentryTraceHeader), r.Header.Get(sentry.SentryBaggageHeader)),
sentry.WithOpName("http.server"),
sentry.ContinueFromRequest(r),
sentry.WithTransactionSource(sentry.SourceURL),
sentry.WithSpanOrigin(sentry.SpanOriginStdLib),
}
Expand All @@ -116,13 +116,10 @@ func (h *Handler) handle(handler http.Handler) http.HandlerFunc {
transaction.Finish()
}()

// TODO(tracing): if the next handler.ServeHTTP panics, store
// information on the transaction accordingly (status, tag,
// level?, ...).
r = r.WithContext(transaction.Context())
hub.Scope().SetRequest(r)

r = r.WithContext(transaction.Context())
defer h.recoverWithSentry(hub, r)

handler.ServeHTTP(rw, r)
}
}
Expand Down
34 changes: 21 additions & 13 deletions hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sentry

import (
"context"
"fmt"
"sync"
"time"
)
Expand Down Expand Up @@ -365,25 +366,32 @@ func (hub *Hub) Flush(timeout time.Duration) bool {
return client.Flush(timeout)
}

// Continue a trace based on HTTP header values. If performance is enabled this
// returns a SpanOption that can be used to start a transaction, otherwise nil.
func (hub *Hub) ContinueTrace(trace, baggage string) (SpanOption, error) {
// GetTraceparent returns the current Sentry traceparent string, to be used as a HTTP header value
// or HTML meta tag value.
// This function is context aware, as in it either returns the traceparent based
// on the current span, or the scope's propagation context.
func (hub *Hub) GetTraceparent() string {
scope := hub.Scope()
propagationContext, err := PropagationContextFromHeaders(trace, baggage)
if err != nil {
return nil, err

if scope.span != nil {
return scope.span.ToSentryTrace()
}

scope.SetPropagationContext(propagationContext)
return fmt.Sprintf("%s-%s", scope.propagationContext.TraceID, scope.propagationContext.SpanID)
}

client := hub.Client()
if client != nil && client.options.EnableTracing {
return ContinueFromHeaders(trace, baggage), nil
}
// GetBaggage returns the current Sentry baggage string, to be used as a HTTP header value
// or HTML meta tag value.
// This function is context aware, as in it either returns the baggage based
// on the current span or the scope's propagation context.
func (hub *Hub) GetBaggage() string {
scope := hub.Scope()

scope.SetContext("trace", propagationContext.Map())
if scope.span != nil {
return scope.span.ToBaggage()
}

return nil, nil
return scope.propagationContext.DynamicSamplingContext.String()
}

// HasHubOnContext checks whether Hub instance is bound to a given Context struct.
Expand Down
Loading

0 comments on commit 24ffea5

Please sign in to comment.