1- import os
2- import logging
3-
4- import wrapt
5- import ddtrace
61import requests
72
8- from ...ext import http
9- from ...propagation .http import HTTPPropagator
10- from ...utils .formats import asbool
11- from ...utils .wrappers import unwrap as _u
12-
3+ from wrapt import wrap_function_wrapper as _w
134
14- log = logging .getLogger (__name__ )
5+ from ...util import unwrap as _u
6+ from .connection import _wrap_session_init , _wrap_request
157
168
179def patch ():
@@ -20,8 +12,8 @@ def patch():
2012 return
2113 setattr (requests , '__datadog_patch' , True )
2214
23- wrapt . wrap_function_wrapper ('requests' , 'Session.__init__' , _session_initializer )
24- wrapt . wrap_function_wrapper ('requests' , 'Session.request' , _traced_request_func )
15+ _w ('requests' , 'Session.__init__' , _wrap_session_init )
16+ _w ('requests' , 'Session.request' , _wrap_request )
2517
2618
2719def unpatch ():
@@ -32,70 +24,3 @@ def unpatch():
3224
3325 _u (requests .Session , '__init__' )
3426 _u (requests .Session , 'request' )
35-
36-
37- def _session_initializer (func , instance , args , kwargs ):
38- """Define settings when requests client is initialized"""
39- func (* args , ** kwargs )
40-
41- # set tracer settings
42- distributed_tracing = asbool (os .environ .get ('DATADOG_REQUESTS_DISTRIBUTED_TRACING' )) or False
43- setattr (instance , 'distributed_tracing' , distributed_tracing )
44-
45-
46- def _traced_request_func (func , instance , args , kwargs ):
47- """ traced_request is a tracing wrapper for requests' Session.request
48- instance method.
49- """
50-
51- # perhaps a global tracer isn't what we want, so permit individual requests
52- # sessions to have their own (with the standard global fallback)
53- tracer = getattr (instance , 'datadog_tracer' , ddtrace .tracer )
54-
55- # [TODO:christian] replace this with a unified way of handling options (eg, Pin)
56- distributed_tracing = getattr (instance , 'distributed_tracing' , None )
57-
58- # bail on the tracing if not enabled.
59- if not tracer .enabled :
60- return func (* args , ** kwargs )
61-
62- method = kwargs .get ('method' ) or args [0 ]
63- url = kwargs .get ('url' ) or args [1 ]
64- headers = kwargs .get ('headers' , {})
65-
66- with tracer .trace ("requests.request" , span_type = http .TYPE ) as span :
67- if distributed_tracing :
68- propagator = HTTPPropagator ()
69- propagator .inject (span .context , headers )
70- kwargs ['headers' ] = headers
71-
72- resp = None
73- try :
74- resp = func (* args , ** kwargs )
75- return resp
76- finally :
77- try :
78- _apply_tags (span , method , url , resp )
79- except Exception :
80- log .debug ("error patching tags" , exc_info = True )
81-
82-
83- def _apply_tags (span , method , url , response ):
84- """ apply_tags will patch the given span with tags about the given request. """
85- span .set_tag (http .METHOD , method )
86- span .set_tag (http .URL , url )
87- if response is not None :
88- span .set_tag (http .STATUS_CODE , response .status_code )
89- # `span.error` must be an integer
90- span .error = int (500 <= response .status_code )
91-
92-
93- class TracedSession (requests .Session ):
94- """ TracedSession is a requests' Session that is already patched.
95- """
96- pass
97-
98-
99- # Always patch our traced session with the traced method (cheesy way of sharing
100- # code)
101- wrapt .wrap_function_wrapper (TracedSession , 'request' , _traced_request_func )
0 commit comments