@@ -47,9 +47,20 @@ func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
47
47
}
48
48
49
49
md , _ := metadata .FromIncomingContext (ctx ) // nil check in ContinueFromGrpcMetadata
50
- span := sentry .StartSpan (ctx , operationName , ContinueFromGrpcMetadata (md ))
51
- ctx = span .Context ()
52
- defer span .Finish ()
50
+
51
+ // Use the FullMethod as transaction name and as description. This way the FullMethod will show up under
52
+ // the span, and under the transaction.
53
+ tx := sentry .StartTransaction (
54
+ ctx ,
55
+ info .FullMethod ,
56
+ sentry .WithOpName (operationName ),
57
+ sentry .WithDescription (info .FullMethod ),
58
+ sentry .WithTransactionSource (sentry .SourceURL ),
59
+ ContinueFromGrpcMetadata (md ),
60
+ )
61
+ tx .SetData ("grpc.request.method" , info .FullMethod )
62
+ ctx = tx .Context ()
63
+ defer tx .Finish ()
53
64
54
65
if o .CaptureRequestBody {
55
66
// TODO: Perhaps makes sense to use SetRequestBody instead?
@@ -65,8 +76,11 @@ func UnaryServerInterceptor(opts ...Option) grpc.UnaryServerInterceptor {
65
76
}
66
77
67
78
hub .CaptureException (err )
79
+
80
+ // Always sample when an error has occurred.
81
+ tx .Sampled = sentry .SampledTrue
68
82
}
69
- span .Status = toSpanStatus (status .Code (err ))
83
+ tx .Status = toSpanStatus (status .Code (err ))
70
84
71
85
return resp , err
72
86
}
@@ -92,9 +106,20 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
92
106
}
93
107
94
108
md , _ := metadata .FromIncomingContext (ctx ) // nil check in ContinueFromGrpcMetadata
95
- span := sentry .StartSpan (ctx , operationName , ContinueFromGrpcMetadata (md ))
96
- ctx = span .Context ()
97
- defer span .Finish ()
109
+
110
+ // Use the FullMethod as transaction name and as description. This way the FullMethod will show up under
111
+ // the span, and under the transaction.
112
+ tx := sentry .StartTransaction (
113
+ ctx ,
114
+ info .FullMethod ,
115
+ sentry .WithOpName (operationName ),
116
+ sentry .WithDescription (info .FullMethod ),
117
+ sentry .WithTransactionSource (sentry .SourceURL ),
118
+ ContinueFromGrpcMetadata (md ),
119
+ )
120
+ tx .SetData ("grpc.request.method" , info .FullMethod )
121
+ ctx = tx .Context ()
122
+ defer tx .Finish ()
98
123
99
124
stream := grpc_middleware .WrapServerStream (ss )
100
125
stream .WrappedContext = ctx
@@ -109,8 +134,11 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
109
134
}
110
135
111
136
hub .CaptureException (err )
137
+
138
+ // Always sample when an error has occurred.
139
+ tx .Sampled = sentry .SampledTrue
112
140
}
113
- span .Status = toSpanStatus (status .Code (err ))
141
+ tx .Status = toSpanStatus (status .Code (err ))
114
142
115
143
return err
116
144
}
@@ -120,23 +148,19 @@ func StreamServerInterceptor(opts ...Option) grpc.StreamServerInterceptor {
120
148
// an existing trace. If it cannot detect an existing trace in the request, the
121
149
// span will be left unchanged.
122
150
func ContinueFromGrpcMetadata (md metadata.MD ) sentry.SpanOption {
123
- return func (s * sentry.Span ) {
124
- if md == nil {
125
- return
126
- }
151
+ if md == nil {
152
+ return nil
153
+ }
127
154
128
- trace , ok := md ["sentry-trace" ]
129
- if ! ok {
130
- return
131
- }
132
- if len (trace ) != 1 {
133
- return
134
- }
135
- if trace [0 ] == "" {
136
- return
137
- }
138
- updateFromSentryTrace (s , []byte (trace [0 ]))
155
+ var trace , baggage string
156
+ if traceMetadata , ok := md [sentry .SentryTraceHeader ]; ok && len (traceMetadata ) > 0 {
157
+ trace = traceMetadata [0 ]
139
158
}
159
+ if baggageMetadata , ok := md [sentry .SentryBaggageHeader ]; ok && len (baggageMetadata ) > 0 {
160
+ baggage = baggageMetadata [0 ]
161
+ }
162
+
163
+ return sentry .ContinueFromHeaders (trace , baggage )
140
164
}
141
165
142
166
// Re-export of functions from tracing.go of sentry-go
0 commit comments