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

Commit 9cd14d3

Browse files
reyangSergeyKanzhelev
authored andcommitted
support trace propagation in httplib integration (#237)
1 parent 456ee2c commit 9cd14d3

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

opencensus/trace/ext/httplib/trace.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def wrap_httplib_request(request_func):
5757
"""Wrap the httplib request function to trace. Create a new span and update
5858
and close the span in the response later.
5959
"""
60-
def call(self, method, url, *args, **kwargs):
60+
def call(self, method, url, body, headers, *args, **kwargs):
6161
_tracer = execution_context.get_opencensus_tracer()
6262
_span = _tracer.start_span()
6363
_span.name = '[httplib]{}'.format(request_func.__name__)
@@ -71,8 +71,13 @@ def call(self, method, url, *args, **kwargs):
7171
# Store the current span id to thread local.
7272
execution_context.set_opencensus_attr(
7373
'httplib/current_span_id', _span.span_id)
74-
75-
return request_func(self, method, url, *args, **kwargs)
74+
try:
75+
headers = headers.copy()
76+
headers.update(_tracer.propagator.to_headers(
77+
_span.context_tracer.span_context))
78+
except Exception: # pragma: NO COVER
79+
pass
80+
return request_func(self, method, url, body, headers, *args, **kwargs)
7681

7782
return call
7883

tests/unit/trace/ext/httplib/test_httplib_trace.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import mock
1818

1919
from opencensus.trace.ext.httplib import trace
20+
from opencensus.trace.propagation import trace_context_http_header_format
2021

2122

2223
class Test_httplib_trace(unittest.TestCase):
@@ -61,7 +62,10 @@ def test_trace_integration(self):
6162
wrap_response_result)
6263

6364
def test_wrap_httplib_request(self):
64-
mock_tracer = MockTracer()
65+
mock_span = mock.Mock()
66+
span_id = '1234'
67+
mock_span.span_id = span_id
68+
mock_tracer = MockTracer(mock_span)
6569
mock_request_func = mock.Mock()
6670
mock_request_func.__name__ = 'request'
6771

@@ -72,17 +76,25 @@ def test_wrap_httplib_request(self):
7276

7377
wrapped = trace.wrap_httplib_request(mock_request_func)
7478

75-
url = 'http://localhost:8080'
79+
mock_self = mock.Mock()
7680
method = 'GET'
81+
url = 'http://localhost:8080'
82+
body = None
83+
headers = {}
7784

7885
with patch:
79-
wrapped(mock.Mock(), method, url)
86+
wrapped(mock_self, method, url, body, headers)
8087

8188
expected_attributes = {
8289
'/http/url': url,
8390
'/http/method': method}
8491
expected_name = '[httplib]request'
8592

93+
mock_request_func.assert_called_with(
94+
mock_self, method, url, body, {
95+
'traceparent': '00-123-456-01',
96+
}
97+
)
8698
self.assertEqual(expected_attributes,
8799
mock_tracer.span.attributes)
88100
self.assertEqual(expected_name, mock_tracer.span.name)
@@ -151,13 +163,20 @@ def test_wrap_httplib_response_no_open_span(self):
151163
class MockTracer(object):
152164
def __init__(self, span=None):
153165
self.span = span
166+
self.propagator = (
167+
trace_context_http_header_format.TraceContextPropagator()
168+
)
154169

155170
def current_span(self):
156171
return self.span
157172

158173
def start_span(self):
159174
span = mock.Mock()
160175
span.attributes = {}
176+
span.context_tracer = mock.Mock()
177+
span.context_tracer.span_context = mock.Mock()
178+
span.context_tracer.span_context.trace_id = '123'
179+
span.context_tracer.span_context.span_id = '456'
161180
self.span = span
162181
return span
163182

0 commit comments

Comments
 (0)