Skip to content

Commit a36a460

Browse files
author
Emanuele Palazzetti
committed
[requests] add a default service name, or use a user defined one or the parent if available
1 parent d8df89a commit a36a460

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

ddtrace/contrib/requests/connection.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import logging
33
import ddtrace
44

5+
from .constants import DEFAULT_SERVICE
6+
57
from ...ext import http
68
from ...util import asbool
79
from ...propagation.http import HTTPPropagator
@@ -16,7 +18,29 @@ def _wrap_session_init(func, instance, args, kwargs):
1618

1719
# set tracer settings
1820
distributed_tracing = asbool(os.environ.get('DATADOG_REQUESTS_DISTRIBUTED_TRACING')) or False
21+
service_name = os.environ.get('DATADOG_REQUESTS_SERVICE_NAME') or DEFAULT_SERVICE
1922
setattr(instance, 'distributed_tracing', distributed_tracing)
23+
setattr(instance, 'service_name', service_name)
24+
25+
26+
def _extract_service_name(session, span):
27+
"""Extracts the right service name based on the following logic:
28+
- `requests` is the default service name
29+
- users can change it via `session.service_name = 'clients'`
30+
- if the Span doesn't have a parent, use the set service name
31+
or fallback to the default
32+
- if the Span has a parent, use the set service name or the
33+
parent service value if the set service name is the default
34+
35+
The priority can be represented as:
36+
Updated service name > parent service name > default to `requests`.
37+
"""
38+
service_name = getattr(session, 'service_name', DEFAULT_SERVICE)
39+
if (service_name == DEFAULT_SERVICE and
40+
span._parent is not None and
41+
span._parent.service is not None):
42+
service_name = span._parent.service
43+
return service_name
2044

2145

2246
def _wrap_request(func, instance, args, kwargs):
@@ -35,6 +59,9 @@ def _wrap_request(func, instance, args, kwargs):
3559
headers = kwargs.get('headers', {})
3660

3761
with tracer.trace("requests.request", span_type=http.TYPE) as span:
62+
# update the span service name before doing any action
63+
span.service = _extract_service_name(instance, span)
64+
3865
if distributed_tracing:
3966
propagator = HTTPPropagator()
4067
propagator.inject(span.context, headers)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DEFAULT_SERVICE = 'requests'

tests/contrib/requests/test_requests.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,69 @@ def test_500(self):
139139
eq_(s.get_tag(http.METHOD), 'GET')
140140
eq_(s.get_tag(http.STATUS_CODE), '500')
141141
eq_(s.error, 1)
142+
143+
def test_default_service_name(self):
144+
# ensure a default service name is set
145+
out = self.session.get(URL_200)
146+
eq_(out.status_code, 200)
147+
148+
spans = self.tracer.writer.pop()
149+
eq_(len(spans), 1)
150+
s = spans[0]
151+
152+
eq_(s.service, 'requests')
153+
154+
def test_user_set_service_name(self):
155+
# ensure a service name set by the user has precedence
156+
self.session.service_name = 'clients'
157+
out = self.session.get(URL_200)
158+
eq_(out.status_code, 200)
159+
160+
spans = self.tracer.writer.pop()
161+
eq_(len(spans), 1)
162+
s = spans[0]
163+
164+
eq_(s.service, 'clients')
165+
166+
def test_parent_service_name_precedence(self):
167+
# ensure the parent service name has precedence if the value
168+
# is not set by the user
169+
with self.tracer.trace('parent.span', service='web'):
170+
out = self.session.get(URL_200)
171+
eq_(out.status_code, 200)
172+
173+
spans = self.tracer.writer.pop()
174+
eq_(len(spans), 2)
175+
s = spans[1]
176+
177+
eq_(s.name, 'requests.request')
178+
eq_(s.service, 'web')
179+
180+
def test_parent_without_service_name(self):
181+
# ensure the default value is used if the parent
182+
# doesn't have a service
183+
with self.tracer.trace('parent.span'):
184+
out = self.session.get(URL_200)
185+
eq_(out.status_code, 200)
186+
187+
spans = self.tracer.writer.pop()
188+
eq_(len(spans), 2)
189+
s = spans[1]
190+
191+
eq_(s.name, 'requests.request')
192+
eq_(s.service, 'requests')
193+
194+
def test_user_service_name_precedence(self):
195+
# ensure the user service name takes precedence over
196+
# the parent Span
197+
with self.tracer.trace('parent.span', service='web'):
198+
self.session.service_name = 'clients'
199+
out = self.session.get(URL_200)
200+
eq_(out.status_code, 200)
201+
202+
spans = self.tracer.writer.pop()
203+
eq_(len(spans), 2)
204+
s = spans[1]
205+
206+
eq_(s.name, 'requests.request')
207+
eq_(s.service, 'clients')

0 commit comments

Comments
 (0)