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

Commit 1f92449

Browse files
victoraugustollsreyang
authored andcommitted
Support server performance breakdown by operation name (#735)
1 parent 15818d0 commit 1f92449

File tree

13 files changed

+190
-29
lines changed

13 files changed

+190
-29
lines changed

contrib/opencensus-ext-azure/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Changelog
22

33
## Unreleased
4+
- Supported server performance breakdown by operation name
5+
([#735](https://github.com/census-instrumentation/opencensus-python/pull/735))
46

57
## 0.3.1
68
- Added metrics exporter

contrib/opencensus-ext-azure/opencensus/ext/azure/trace_exporter/__init__.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,24 @@ def span_data_to_envelope(self, sd):
6969
sd.start_time,
7070
sd.end_time,
7171
),
72-
responseCode='0', # TODO
73-
success=True, # TODO
72+
responseCode='0',
73+
success=False,
7474
properties={},
7575
)
7676
envelope.data = Data(baseData=data, baseType='RequestData')
7777
if 'http.method' in sd.attributes:
7878
data.name = sd.attributes['http.method']
79+
if 'http.route' in sd.attributes:
80+
data.name = data.name + ' ' + sd.attributes['http.route']
81+
envelope.tags['ai.operation.name'] = data.name
7982
if 'http.url' in sd.attributes:
80-
data.name = data.name + ' ' + sd.attributes['http.url']
8183
data.url = sd.attributes['http.url']
8284
if 'http.status_code' in sd.attributes:
83-
data.responseCode = str(sd.attributes['http.status_code'])
85+
status_code = sd.attributes['http.status_code']
86+
data.responseCode = str(status_code)
87+
data.success = (
88+
status_code >= 200 and status_code <= 399
89+
)
8490
else:
8591
envelope.name = \
8692
'Microsoft.ApplicationInsights.RemoteDependency'
@@ -111,6 +117,9 @@ def span_data_to_envelope(self, sd):
111117
data.type = 'INPROC'
112118
# TODO: links, tracestate, tags
113119
for key in sd.attributes:
120+
# This removes redundant data from ApplicationInsights
121+
if key.startswith('http.'):
122+
continue
114123
data.properties[key] = sd.attributes[key]
115124
return envelope
116125

contrib/opencensus-ext-azure/tests/test_azure_trace_exporter.py

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def test_span_data_to_envelope(self):
225225
envelope.data.baseType,
226226
'RemoteDependencyData')
227227

228-
# SpanKind.SERVER HTTP
228+
# SpanKind.SERVER HTTP - 200 request
229229
envelope = exporter.span_data_to_envelope(SpanData(
230230
name='test',
231231
context=SpanContext(
@@ -239,6 +239,8 @@ def test_span_data_to_envelope(self):
239239
parent_span_id='6e0c63257de34c93',
240240
attributes={
241241
'http.method': 'GET',
242+
'http.path': '/wiki/Rabbit',
243+
'http.route': '/wiki/Rabbit',
242244
'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
243245
'http.status_code': 200,
244246
},
@@ -265,6 +267,9 @@ def test_span_data_to_envelope(self):
265267
self.assertEqual(
266268
envelope.tags['ai.operation.id'],
267269
'6e0c63257de34c90bf9efcd03927272e')
270+
self.assertEqual(
271+
envelope.tags['ai.operation.name'],
272+
'GET /wiki/Rabbit')
268273
self.assertEqual(
269274
envelope.time,
270275
'2010-10-24T07:28:38.123456Z')
@@ -279,7 +284,80 @@ def test_span_data_to_envelope(self):
279284
'200')
280285
self.assertEqual(
281286
envelope.data.baseData.name,
282-
'GET https://www.wikipedia.org/wiki/Rabbit')
287+
'GET /wiki/Rabbit')
288+
self.assertEqual(
289+
envelope.data.baseData.success,
290+
True)
291+
self.assertEqual(
292+
envelope.data.baseData.url,
293+
'https://www.wikipedia.org/wiki/Rabbit')
294+
self.assertEqual(
295+
envelope.data.baseType,
296+
'RequestData')
297+
298+
# SpanKind.SERVER HTTP - Failed request
299+
envelope = exporter.span_data_to_envelope(SpanData(
300+
name='test',
301+
context=SpanContext(
302+
trace_id='6e0c63257de34c90bf9efcd03927272e',
303+
span_id='6e0c63257de34c91',
304+
trace_options=TraceOptions('1'),
305+
tracestate=Tracestate(),
306+
from_header=False,
307+
),
308+
span_id='6e0c63257de34c92',
309+
parent_span_id='6e0c63257de34c93',
310+
attributes={
311+
'http.method': 'GET',
312+
'http.path': '/wiki/Rabbit',
313+
'http.route': '/wiki/Rabbit',
314+
'http.url': 'https://www.wikipedia.org/wiki/Rabbit',
315+
'http.status_code': 400,
316+
},
317+
start_time='2010-10-24T07:28:38.123456Z',
318+
end_time='2010-10-24T07:28:38.234567Z',
319+
stack_trace=None,
320+
links=None,
321+
status=None,
322+
annotations=None,
323+
message_events=None,
324+
same_process_as_parent_span=None,
325+
child_span_count=None,
326+
span_kind=SpanKind.SERVER,
327+
))
328+
self.assertEqual(
329+
envelope.iKey,
330+
'12345678-1234-5678-abcd-12345678abcd')
331+
self.assertEqual(
332+
envelope.name,
333+
'Microsoft.ApplicationInsights.Request')
334+
self.assertEqual(
335+
envelope.tags['ai.operation.parentId'],
336+
'|6e0c63257de34c90bf9efcd03927272e.6e0c63257de34c93.')
337+
self.assertEqual(
338+
envelope.tags['ai.operation.id'],
339+
'6e0c63257de34c90bf9efcd03927272e')
340+
self.assertEqual(
341+
envelope.tags['ai.operation.name'],
342+
'GET /wiki/Rabbit')
343+
self.assertEqual(
344+
envelope.time,
345+
'2010-10-24T07:28:38.123456Z')
346+
self.assertEqual(
347+
envelope.data.baseData.id,
348+
'|6e0c63257de34c90bf9efcd03927272e.6e0c63257de34c92.')
349+
self.assertEqual(
350+
envelope.data.baseData.duration,
351+
'0.00:00:00.111')
352+
self.assertEqual(
353+
envelope.data.baseData.responseCode,
354+
'400')
355+
self.assertEqual(
356+
envelope.data.baseData.name,
357+
'GET /wiki/Rabbit')
358+
self.assertEqual(
359+
envelope.data.baseData.success,
360+
False)
283361
self.assertEqual(
284362
envelope.data.baseData.url,
285363
'https://www.wikipedia.org/wiki/Rabbit')

contrib/opencensus-ext-django/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Changelog
22

33
## Unreleased
4+
- Updated span attributes to include some missing attributes listed [here](https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/HTTP.md#attributes)
5+
([#735](https://github.com/census-instrumentation/opencensus-python/pull/735))
46

57
## 0.3.2
68
Released 2019-07-26

contrib/opencensus-ext-django/opencensus/ext/django/middleware.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
from opencensus.trace import utils
3030
from opencensus.trace.propagation import trace_context_http_header_format
3131

32+
HTTP_HOST = attributes_helper.COMMON_ATTRIBUTES['HTTP_HOST']
3233
HTTP_METHOD = attributes_helper.COMMON_ATTRIBUTES['HTTP_METHOD']
34+
HTTP_PATH = attributes_helper.COMMON_ATTRIBUTES['HTTP_PATH']
35+
HTTP_ROUTE = attributes_helper.COMMON_ATTRIBUTES['HTTP_ROUTE']
3336
HTTP_URL = attributes_helper.COMMON_ATTRIBUTES['HTTP_URL']
3437
HTTP_STATUS_CODE = attributes_helper.COMMON_ATTRIBUTES['HTTP_STATUS_CODE']
3538

@@ -157,12 +160,21 @@ def process_request(self, request):
157160
# Span name is being set at process_view
158161
span = tracer.start_span()
159162
span.span_kind = span_module.SpanKind.SERVER
163+
tracer.add_attribute_to_current_span(
164+
attribute_key=HTTP_HOST,
165+
attribute_value=request.get_host())
160166
tracer.add_attribute_to_current_span(
161167
attribute_key=HTTP_METHOD,
162168
attribute_value=request.method)
163169
tracer.add_attribute_to_current_span(
164-
attribute_key=HTTP_URL,
170+
attribute_key=HTTP_PATH,
171+
attribute_value=str(request.path))
172+
tracer.add_attribute_to_current_span(
173+
attribute_key=HTTP_ROUTE,
165174
attribute_value=str(request.path))
175+
tracer.add_attribute_to_current_span(
176+
attribute_key=HTTP_URL,
177+
attribute_value=str(request.build_absolute_uri()))
166178

167179
# Add the span to thread local
168180
# in some cases (exceptions, timeouts) currentspan in

contrib/opencensus-ext-django/tests/test_django_middleware.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def test_process_request(self):
8585
span_id = '6e0c63257de34c92'
8686
django_trace_id = '00-{}-{}-00'.format(trace_id, span_id)
8787

88-
django_request = RequestFactory().get('/', **{
88+
django_request = RequestFactory().get('/wiki/Rabbit', **{
8989
'HTTP_TRACEPARENT': django_trace_id})
9090

9191
# Force the test request to be sampled
@@ -110,8 +110,11 @@ def test_process_request(self):
110110
span = tracer.current_span()
111111

112112
expected_attributes = {
113-
'http.url': u'/',
113+
'http.host': u'testserver',
114114
'http.method': 'GET',
115+
'http.path': u'/wiki/Rabbit',
116+
'http.route': u'/wiki/Rabbit',
117+
'http.url': u'http://testserver/wiki/Rabbit',
115118
}
116119
self.assertEqual(span.span_kind, span_module.SpanKind.SERVER)
117120
self.assertEqual(span.attributes, expected_attributes)
@@ -185,7 +188,7 @@ def test_process_response(self):
185188
span_id = '6e0c63257de34c92'
186189
django_trace_id = '00-{}-{}-00'.format(trace_id, span_id)
187190

188-
django_request = RequestFactory().get('/', **{
191+
django_request = RequestFactory().get('/wiki/Rabbit', **{
189192
'traceparent': django_trace_id,
190193
})
191194

@@ -214,8 +217,11 @@ def test_process_response(self):
214217
django_response.status_code = 200
215218

216219
expected_attributes = {
217-
'http.url': u'/',
220+
'http.host': u'testserver',
218221
'http.method': 'GET',
222+
'http.path': u'/wiki/Rabbit',
223+
'http.route': u'/wiki/Rabbit',
224+
'http.url': u'http://testserver/wiki/Rabbit',
219225
'http.status_code': '200',
220226
'django.user.id': '123',
221227
'django.user.name': 'test_name'
@@ -237,7 +243,7 @@ def test_process_response_unfinished_child_span(self):
237243
span_id = '6e0c63257de34c92'
238244
django_trace_id = '00-{}-{}-00'.format(trace_id, span_id)
239245

240-
django_request = RequestFactory().get('/', **{
246+
django_request = RequestFactory().get('/wiki/Rabbit', **{
241247
'traceparent': django_trace_id,
242248
})
243249

@@ -266,8 +272,11 @@ def test_process_response_unfinished_child_span(self):
266272
django_response.status_code = 500
267273

268274
expected_attributes = {
269-
'http.url': u'/',
275+
'http.host': u'testserver',
270276
'http.method': 'GET',
277+
'http.path': u'/wiki/Rabbit',
278+
'http.route': u'/wiki/Rabbit',
279+
'http.url': u'http://testserver/wiki/Rabbit',
271280
'http.status_code': '500',
272281
'django.user.id': '123',
273282
'django.user.name': 'test_name'

contrib/opencensus-ext-flask/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44
- Make ProbabilitySampler default
5+
- Updated span attributes to include some missing attributes listed [here](https://github.com/census-instrumentation/opencensus-specs/blob/master/trace/HTTP.md#attributes)
6+
([#735](https://github.com/census-instrumentation/opencensus-python/pull/735))
57

68
## 0.3.0
79
Released 2019-04-24

contrib/opencensus-ext-flask/opencensus/ext/flask/flask_middleware.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131
from opencensus.trace import utils
3232
from opencensus.trace.propagation import trace_context_http_header_format
3333

34+
HTTP_HOST = attributes_helper.COMMON_ATTRIBUTES['HTTP_HOST']
3435
HTTP_METHOD = attributes_helper.COMMON_ATTRIBUTES['HTTP_METHOD']
36+
HTTP_PATH = attributes_helper.COMMON_ATTRIBUTES['HTTP_PATH']
37+
HTTP_ROUTE = attributes_helper.COMMON_ATTRIBUTES['HTTP_ROUTE']
3538
HTTP_URL = attributes_helper.COMMON_ATTRIBUTES['HTTP_URL']
3639
HTTP_STATUS_CODE = attributes_helper.COMMON_ATTRIBUTES['HTTP_STATUS_CODE']
3740

@@ -144,12 +147,24 @@ def _before_request(self):
144147
flask.request.method,
145148
flask.request.url)
146149
tracer.add_attribute_to_current_span(
147-
HTTP_METHOD, flask.request.method)
150+
HTTP_HOST, flask.request.host
151+
)
148152
tracer.add_attribute_to_current_span(
149-
HTTP_URL, str(flask.request.url))
153+
HTTP_METHOD, flask.request.method
154+
)
155+
tracer.add_attribute_to_current_span(
156+
HTTP_PATH, flask.request.path
157+
)
158+
tracer.add_attribute_to_current_span(
159+
HTTP_ROUTE, flask.request.path
160+
)
161+
tracer.add_attribute_to_current_span(
162+
HTTP_URL, str(flask.request.url)
163+
)
150164
execution_context.set_opencensus_attr(
151165
'blacklist_hostnames',
152-
self.blacklist_hostnames)
166+
self.blacklist_hostnames
167+
)
153168
except Exception: # pragma: NO COVER
154169
log.error('Failed to trace request', exc_info=True)
155170

@@ -166,7 +181,8 @@ def _after_request(self, response):
166181
tracer = execution_context.get_opencensus_tracer()
167182
tracer.add_attribute_to_current_span(
168183
HTTP_STATUS_CODE,
169-
str(response.status_code))
184+
str(response.status_code)
185+
)
170186
except Exception: # pragma: NO COVER
171187
log.error('Failed to trace request', exc_info=True)
172188
finally:

contrib/opencensus-ext-flask/tests/test_flask_middleware.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def test__before_request(self):
141141
flask_middleware.FlaskMiddleware(app=app,
142142
sampler=samplers.AlwaysOnSampler())
143143
context = app.test_request_context(
144-
path='/',
144+
path='/wiki/Rabbit',
145145
headers={flask_trace_header: flask_trace_id})
146146

147147
with context:
@@ -152,8 +152,11 @@ def test__before_request(self):
152152
span = tracer.current_span()
153153

154154
expected_attributes = {
155-
'http.url': u'http://localhost/',
156-
'http.method': 'GET',
155+
'http.host': u'localhost',
156+
'http.method': u'GET',
157+
'http.path': u'/wiki/Rabbit',
158+
'http.route': u'/wiki/Rabbit',
159+
'http.url': u'http://localhost/wiki/Rabbit',
157160
}
158161

159162
self.assertEqual(span.span_kind, span_module.SpanKind.SERVER)
@@ -203,7 +206,7 @@ def test_header_encoding(self):
203206
flask_middleware.FlaskMiddleware(app=app,
204207
sampler=samplers.AlwaysOnSampler())
205208
context = app.test_request_context(
206-
path='/',
209+
path='/wiki/Rabbit',
207210
headers={flask_trace_header: flask_trace_id})
208211

209212
with context:
@@ -214,8 +217,11 @@ def test_header_encoding(self):
214217
span = tracer.current_span()
215218

216219
expected_attributes = {
217-
'http.url': u'http://localhost/',
218-
'http.method': 'GET',
220+
'http.host': u'localhost',
221+
'http.method': u'GET',
222+
'http.path': u'/wiki/Rabbit',
223+
'http.route': u'/wiki/Rabbit',
224+
'http.url': u'http://localhost/wiki/Rabbit',
219225
}
220226

221227
self.assertEqual(span.attributes, expected_attributes)
@@ -229,7 +235,7 @@ def test_header_is_none(self):
229235
flask_middleware.FlaskMiddleware(app=app,
230236
sampler=samplers.AlwaysOnSampler())
231237
context = app.test_request_context(
232-
path='/')
238+
path='/wiki/Rabbit')
233239

234240
with context:
235241
app.preprocess_request()
@@ -239,8 +245,11 @@ def test_header_is_none(self):
239245
span = tracer.current_span()
240246

241247
expected_attributes = {
242-
'http.url': u'http://localhost/',
243-
'http.method': 'GET',
248+
'http.host': u'localhost',
249+
'http.method': u'GET',
250+
'http.path': u'/wiki/Rabbit',
251+
'http.route': u'/wiki/Rabbit',
252+
'http.url': u'http://localhost/wiki/Rabbit',
244253
}
245254

246255
self.assertEqual(span.attributes, expected_attributes)

0 commit comments

Comments
 (0)