25
25
import grpc
26
26
27
27
from opentelemetry import propagators , trace
28
+ from opentelemetry .trace .status import Status , StatusCanonicalCode
28
29
29
30
from . import grpcext
30
31
from ._utilities import RpcInfo
33
34
class _GuardedSpan :
34
35
def __init__ (self , span ):
35
36
self .span = span
37
+ self .generated_span = None
36
38
self ._engaged = True
37
39
38
40
def __enter__ (self ):
39
- self .span .__enter__ ()
41
+ self .generated_span = self . span .__enter__ ()
40
42
return self
41
43
42
44
def __exit__ (self , * args , ** kwargs ):
43
45
if self ._engaged :
46
+ self .generated_span = None
44
47
return self .span .__exit__ (* args , ** kwargs )
45
48
return False
46
49
@@ -122,7 +125,15 @@ def intercept_unary(self, request, metadata, client_info, invoker):
122
125
timeout = client_info .timeout ,
123
126
request = request ,
124
127
)
125
- result = invoker (request , metadata )
128
+
129
+ try :
130
+ result = invoker (request , metadata )
131
+ except grpc .RpcError as exc :
132
+ guarded_span .generated_span .set_status (
133
+ Status (StatusCanonicalCode (exc .code ().value [0 ]))
134
+ )
135
+ raise
136
+
126
137
return self ._trace_result (guarded_span , rpc_info , result )
127
138
128
139
# For RPCs that stream responses, the result can be a generator. To record
@@ -136,7 +147,7 @@ def _intercept_server_stream(
136
147
else :
137
148
mutable_metadata = OrderedDict (metadata )
138
149
139
- with self ._start_span (client_info .full_method ):
150
+ with self ._start_span (client_info .full_method ) as span :
140
151
_inject_span_context (mutable_metadata )
141
152
metadata = tuple (mutable_metadata .items ())
142
153
rpc_info = RpcInfo (
@@ -146,9 +157,16 @@ def _intercept_server_stream(
146
157
)
147
158
if client_info .is_client_stream :
148
159
rpc_info .request = request_or_iterator
149
- result = invoker (request_or_iterator , metadata )
150
- for response in result :
151
- yield response
160
+
161
+ try :
162
+ result = invoker (request_or_iterator , metadata )
163
+ for response in result :
164
+ yield response
165
+ except grpc .RpcError as exc :
166
+ span .set_status (
167
+ Status (StatusCanonicalCode (exc .code ().value [0 ]))
168
+ )
169
+ raise
152
170
153
171
def intercept_stream (
154
172
self , request_or_iterator , metadata , client_info , invoker
@@ -172,5 +190,13 @@ def intercept_stream(
172
190
timeout = client_info .timeout ,
173
191
request = request_or_iterator ,
174
192
)
175
- result = invoker (request_or_iterator , metadata )
193
+
194
+ try :
195
+ result = invoker (request_or_iterator , metadata )
196
+ except grpc .RpcError as exc :
197
+ guarded_span .generated_span .set_status (
198
+ Status (StatusCanonicalCode (exc .code ().value [0 ]))
199
+ )
200
+ raise
201
+
176
202
return self ._trace_result (guarded_span , rpc_info , result )
0 commit comments