Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Commit 023ad8f

Browse files
wkiserliyanhui1228
authored andcommitted
Update gRPC client interceptor to use tracer from execution context (#157)
1 parent 61c053a commit 023ad8f

3 files changed

Lines changed: 53 additions & 20 deletions

File tree

examples/trace/helloworld/flask/custom.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,20 @@
1313
# limitations under the License.
1414

1515
import os
16-
import requests
17-
import sys
1816

1917
import flask
18+
import grpc
2019
import mysql.connector
2120
import psycopg2
21+
import requests
2222
import sqlalchemy
2323

24-
from opencensus.trace.ext.flask.flask_middleware import FlaskMiddleware
24+
import hello_world_pb2
25+
import hello_world_pb2_grpc
2526
from opencensus.trace import config_integration
2627
from opencensus.trace.exporters import stackdriver_exporter
28+
from opencensus.trace.ext.flask.flask_middleware import FlaskMiddleware
29+
from opencensus.trace.ext.grpc import client_interceptor
2730
from opencensus.trace.samplers import probability
2831

2932
INTEGRATIONS = ['mysql', 'postgresql', 'sqlalchemy', 'requests']
@@ -38,14 +41,20 @@
3841
# PostgreSQL settings
3942
POSTGRES_PASSWORD = os.environ.get('SYSTEST_POSTGRES_PASSWORD')
4043

44+
# hello_world_server location
45+
HELLO_WORLD_HOST_PORT = 'localhost:50051'
46+
4147
app = flask.Flask(__name__)
4248

4349
# Enable tracing, configure the trace params, send traces to Stackdriver Trace
44-
exporter = stackdriver_exporter.StackdriverExporter(project_id='yanhuili-sandbox')
50+
exporter = stackdriver_exporter.StackdriverExporter()
4551
sampler = probability.ProbabilitySampler(rate=1)
4652
middleware = FlaskMiddleware(app, exporter=exporter, sampler=sampler)
4753
config_integration.trace_integrations(INTEGRATIONS)
4854

55+
# cache of (stub_cls, hostport) -> grpc stub
56+
_stub_cache = {}
57+
4958

5059
@app.route('/')
5160
def hello():
@@ -162,5 +171,29 @@ def sqlalchemy_postgresql_query():
162171
return msg, 500
163172

164173

174+
@app.route('/greet/<name>')
175+
def greet(name):
176+
stub = _get_grpc_stub(
177+
hello_world_pb2_grpc.GreeterStub, HELLO_WORLD_HOST_PORT
178+
)
179+
response = stub.SayHello(hello_world_pb2.HelloRequest(name=name))
180+
return str(response)
181+
182+
183+
def _get_grpc_stub(stub_cls, host_port):
184+
stub = _stub_cache.get((stub_cls, host_port))
185+
if stub is not None:
186+
return stub
187+
188+
channel = grpc.insecure_channel(host_port)
189+
tracer_interceptor = client_interceptor.OpenCensusClientInterceptor(
190+
host_port=HELLO_WORLD_HOST_PORT
191+
)
192+
channel = grpc.intercept_channel(channel, tracer_interceptor)
193+
stub = stub_cls(channel)
194+
_stub_cache[(stub_cls, host_port)] = stub
195+
return stub
196+
197+
165198
if __name__ == '__main__':
166199
app.run(host='localhost', port=8080)

opencensus/trace/ext/grpc/client_interceptor.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,40 +51,44 @@ class OpenCensusClientInterceptor(grpc.UnaryUnaryClientInterceptor,
5151
grpc.StreamStreamClientInterceptor):
5252

5353
def __init__(self, tracer=None, host_port=None):
54-
if tracer is None:
55-
tracer = execution_context.get_opencensus_tracer()
56-
5754
self._tracer = tracer
5855
self.host_port = host_port
5956
self._propagator = binary_format.BinaryFormatPropagator()
6057

58+
@property
59+
def tracer(self):
60+
return self._tracer or execution_context.get_opencensus_tracer()
61+
6162
def _start_client_span(self, client_call_details):
62-
span = self._tracer.start_span(
63+
span = self.tracer.start_span(
6364
name=_get_span_name(client_call_details)
6465
)
6566

6667
# Add the component grpc to span attribute
67-
self._tracer.add_attribute_to_current_span(
68+
self.tracer.add_attribute_to_current_span(
6869
attribute_key=attributes_helper.COMMON_ATTRIBUTES.get(
6970
ATTRIBUTE_COMPONENT),
7071
attribute_value='grpc')
7172

7273
# Add the host:port info to span attribute
73-
self._tracer.add_attribute_to_current_span(
74+
self.tracer.add_attribute_to_current_span(
7475
attribute_key=attributes_helper.GRPC_ATTRIBUTES.get(
7576
GRPC_HOST_PORT),
7677
attribute_value=self.host_port)
7778

7879
# Add the method to span attribute
79-
self._tracer.add_attribute_to_current_span(
80+
self.tracer.add_attribute_to_current_span(
8081
attribute_key=attributes_helper.GRPC_ATTRIBUTES.get(GRPC_METHOD),
8182
attribute_value=str(client_call_details.method))
8283

84+
execution_context.set_opencensus_tracer(self.tracer)
85+
execution_context.set_current_span(span)
86+
8387
return span
8488

8589
def _end_span_between_context(self, current_span):
8690
execution_context.set_current_span(current_span)
87-
self._tracer.end_span()
91+
self.tracer.end_span()
8892

8993
def _intercept_call(
9094
self, client_call_details, request_iterator, grpc_type):
@@ -95,14 +99,12 @@ def _intercept_call(
9599
# Start a span
96100
current_span = self._start_client_span(client_call_details)
97101

98-
span_context = self._tracer.span_context
102+
span_context = current_span.context_tracer.span_context
99103
header = self._propagator.to_header(span_context)
100104
grpc_trace_metadata = {
101105
oc_grpc.GRPC_TRACE_KEY: header,
102106
}
103107

104-
metadata_to_append = None
105-
106108
if isinstance(metadata, list):
107109
metadata_to_append = list(six.iteritems(grpc_trace_metadata))
108110
else:
@@ -122,7 +124,7 @@ def _callback(self, current_span):
122124
def callback(future_response):
123125
execution_context.set_current_span(current_span)
124126
self._trace_future_exception(future_response)
125-
self._tracer.end_span()
127+
self.tracer.end_span()
126128

127129
return callback
128130

@@ -133,7 +135,7 @@ def _trace_future_exception(self, response):
133135
if exception is not None:
134136
exception = str(exception)
135137

136-
self._tracer.add_attribute_to_current_span(
138+
self.tracer.add_attribute_to_current_span(
137139
attribute_key=attributes_helper.COMMON_ATTRIBUTES.get(
138140
ATTRIBUTE_ERROR_MESSAGE),
139141
attribute_value=exception)

tests/unit/trace/ext/grpc/test_client_interceptor.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,11 @@ def setUp(self):
2727
execution_context.clear()
2828

2929
def test_constructor_default(self):
30-
from opencensus.trace.tracers import noop_tracer
3130
from opencensus.trace.propagation import binary_format
3231

3332
interceptor = client_interceptor.OpenCensusClientInterceptor()
3433

35-
self.assertTrue(isinstance(
36-
interceptor._tracer, noop_tracer.NoopTracer))
34+
self.assertIsNone(interceptor._tracer)
3735
self.assertIsNone(interceptor.host_port)
3836
self.assertTrue(isinstance(
3937
interceptor._propagator, binary_format.BinaryFormatPropagator))

0 commit comments

Comments
 (0)