@@ -92,6 +92,18 @@ def response_hook(span, request, response):
92
92
_RequestHookT = typing .Optional [
93
93
typing .Callable [[Span , urllib3 .connectionpool .HTTPConnectionPool ], None ]
94
94
]
95
+ _ExtendedRequestHookT = typing .Optional [
96
+ typing .Callable [
97
+ [
98
+ Span ,
99
+ urllib3 .connectionpool .HTTPConnectionPool ,
100
+ # Request headers dict
101
+ typing .Dict ,
102
+ # Request Body
103
+ str ,
104
+ ],
105
+ None ]
106
+ ]
95
107
_ResponseHookT = typing .Optional [
96
108
typing .Callable [
97
109
[
@@ -139,7 +151,7 @@ def _uninstrument(self, **kwargs):
139
151
140
152
def _instrument (
141
153
tracer ,
142
- request_hook : _RequestHookT = None ,
154
+ request_hook : typing . Union [ _RequestHookT , _ExtendedRequestHookT ] = None ,
143
155
response_hook : _ResponseHookT = None ,
144
156
url_filter : _UrlFilterT = None ,
145
157
):
@@ -150,6 +162,7 @@ def instrumented_urlopen(wrapped, instance, args, kwargs):
150
162
method = _get_url_open_arg ("method" , args , kwargs ).upper ()
151
163
url = _get_url (instance , args , kwargs , url_filter )
152
164
headers = _prepare_headers (kwargs )
165
+ body = _get_url_open_arg ("body" , args , kwargs )
153
166
154
167
span_name = "HTTP {}" .format (method .strip ())
155
168
span_attributes = {
@@ -161,7 +174,7 @@ def instrumented_urlopen(wrapped, instance, args, kwargs):
161
174
span_name , kind = SpanKind .CLIENT , attributes = span_attributes
162
175
) as span :
163
176
if callable (request_hook ):
164
- request_hook ( span , instance )
177
+ _call_request_hook ( request_hook , span , instance , headers , body )
165
178
inject (headers )
166
179
167
180
with _suppress_further_instrumentation ():
@@ -179,6 +192,19 @@ def instrumented_urlopen(wrapped, instance, args, kwargs):
179
192
)
180
193
181
194
195
+ def _call_request_hook (request_hook : typing .Union [_RequestHookT , _ExtendedRequestHookT ],
196
+ span : Span ,
197
+ connection_pool : urllib3 .connectionpool .HTTPConnectionPool ,
198
+ headers : typing .Dict ,
199
+ body : str ):
200
+ try :
201
+ # First assume request_hook is a function of type _ExtendedRequestHookT
202
+ request_hook (span , connection_pool , headers , body )
203
+ except TypeError :
204
+ # Fallback to call request_hook as a function of type _RequestHookT
205
+ request_hook (span , connection_pool )
206
+
207
+
182
208
def _get_url_open_arg (name : str , args : typing .List , kwargs : typing .Mapping ):
183
209
arg_idx = _URL_OPEN_ARG_TO_INDEX_MAPPING .get (name )
184
210
if arg_idx is not None :
0 commit comments