Skip to content

Commit

Permalink
Merge pull request #21 from janwytze/fix/sentry-performance
Browse files Browse the repository at this point in the history
Fix parent transaction linking, add more details to transactions and update to newest Sentry SDK
  • Loading branch information
johnbellone authored Apr 19, 2024
2 parents 5a998af + bb15dfc commit da363e7
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 30 deletions.
20 changes: 14 additions & 6 deletions client_interceptors.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@ func UnaryClientInterceptor(opts ...Option) grpc.UnaryClientInterceptor {
operationName = o.OperationNameOverride
}

span := sentry.StartSpan(ctx, operationName)
span := sentry.StartSpan(ctx, operationName, sentry.WithDescription(method))
span.SetData("grpc.request.method", method)
ctx = span.Context()
md, ok := metadata.FromOutgoingContext(ctx)
if ok {
md.Append("sentry-trace", span.ToSentryTrace())
md.Append(sentry.SentryTraceHeader, span.ToSentryTrace())
md.Append(sentry.SentryBaggageHeader, span.ToBaggage())
} else {
md = metadata.Pairs("sentry-trace", span.ToSentryTrace())
md = metadata.Pairs(
sentry.SentryTraceHeader, span.ToSentryTrace(),
sentry.SentryBaggageHeader, span.ToBaggage(),
)
}
ctx = metadata.NewOutgoingContext(ctx, md)
defer span.Finish()
Expand Down Expand Up @@ -70,13 +75,16 @@ func StreamClientInterceptor(opts ...Option) grpc.StreamClientInterceptor {
operationName = o.OperationNameOverride
}

span := sentry.StartSpan(ctx, operationName)
span := sentry.StartSpan(ctx, operationName, sentry.WithDescription(method))
span.SetData("grpc.request.method", method)
ctx = span.Context()
md, ok := metadata.FromOutgoingContext(ctx)
if ok {
md.Append("sentry-trace", span.ToSentryTrace())
md.Append(sentry.SentryTraceHeader, span.ToSentryTrace())
md.Append(sentry.SentryBaggageHeader, span.ToBaggage())
} else {
md = metadata.Pairs("sentry-trace", span.ToSentryTrace())
md = metadata.Pairs(sentry.SentryTraceHeader, span.ToSentryTrace())
md = metadata.Pairs(sentry.SentryBaggageHeader, span.ToBaggage())
}
ctx = metadata.NewOutgoingContext(ctx, md)
defer span.Finish()
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/johnbellone/grpc-middleware-sentry
go 1.17

require (
github.com/getsentry/sentry-go v0.20.0
github.com/getsentry/sentry-go v0.27.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
google.golang.org/grpc v1.56.3
)
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,7 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/getsentry/sentry-go v0.20.0 h1:bwXW98iMRIWxn+4FgPW7vMrjmbym6HblXALmhjHmQaQ=
github.com/getsentry/sentry-go v0.20.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
Expand Down
70 changes: 47 additions & 23 deletions server_interceptors.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,20 @@ func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
}

md, _ := metadata.FromIncomingContext(ctx) // nil check in ContinueFromGrpcMetadata
span := sentry.StartSpan(ctx, operationName, ContinueFromGrpcMetadata(md))
ctx = span.Context()
defer span.Finish()

// Use the FullMethod as transaction name and as description. This way the FullMethod will show up under
// the span, and under the transaction.
tx := sentry.StartTransaction(
ctx,
info.FullMethod,
sentry.WithOpName(operationName),
sentry.WithDescription(info.FullMethod),
sentry.WithTransactionSource(sentry.SourceURL),
ContinueFromGrpcMetadata(md),
)
tx.SetData("grpc.request.method", info.FullMethod)
ctx = tx.Context()
defer tx.Finish()

if o.CaptureRequestBody {
// TODO: Perhaps makes sense to use SetRequestBody instead?
Expand All @@ -65,8 +76,11 @@ func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
}

hub.CaptureException(err)

// Always sample when an error has occurred.
tx.Sampled = sentry.SampledTrue
}
span.Status = toSpanStatus(status.Code(err))
tx.Status = toSpanStatus(status.Code(err))

return resp, err
}
Expand All @@ -92,9 +106,20 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
}

md, _ := metadata.FromIncomingContext(ctx) // nil check in ContinueFromGrpcMetadata
span := sentry.StartSpan(ctx, operationName, ContinueFromGrpcMetadata(md))
ctx = span.Context()
defer span.Finish()

// Use the FullMethod as transaction name and as description. This way the FullMethod will show up under
// the span, and under the transaction.
tx := sentry.StartTransaction(
ctx,
info.FullMethod,
sentry.WithOpName(operationName),
sentry.WithDescription(info.FullMethod),
sentry.WithTransactionSource(sentry.SourceURL),
ContinueFromGrpcMetadata(md),
)
tx.SetData("grpc.request.method", info.FullMethod)
ctx = tx.Context()
defer tx.Finish()

stream := grpc_middleware.WrapServerStream(ss)
stream.WrappedContext = ctx
Expand All @@ -109,8 +134,11 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
}

hub.CaptureException(err)

// Always sample when an error has occurred.
tx.Sampled = sentry.SampledTrue
}
span.Status = toSpanStatus(status.Code(err))
tx.Status = toSpanStatus(status.Code(err))

return err
}
Expand All @@ -120,23 +148,19 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
// an existing trace. If it cannot detect an existing trace in the request, the
// span will be left unchanged.
func ContinueFromGrpcMetadata(md metadata.MD) sentry.SpanOption {
return func(s *sentry.Span) {
if md == nil {
return
}
if md == nil {
return nil
}

trace, ok := md["sentry-trace"]
if !ok {
return
}
if len(trace) != 1 {
return
}
if trace[0] == "" {
return
}
updateFromSentryTrace(s, []byte(trace[0]))
var trace, baggage string
if traceMetadata, ok := md[sentry.SentryTraceHeader]; ok && len(traceMetadata) > 0 {
trace = traceMetadata[0]
}
if baggageMetadata, ok := md[sentry.SentryBaggageHeader]; ok && len(baggageMetadata) > 0 {
baggage = baggageMetadata[0]
}

return sentry.ContinueFromHeaders(trace, baggage)
}

// Re-export of functions from tracing.go of sentry-go
Expand Down

0 comments on commit da363e7

Please sign in to comment.