mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-30 21:56:07 +08:00
Urllib3 request hook (#660)
* Urllib3: extend request hook with request body and headers * Change GET to POST in test_extended_request_hook * added changelog entry * update ExtendedReqeustHookT * adding up to date generated code * replace _RequestHookT with _ExtendedRequestHookT * updated Changelog Co-authored-by: Ran Nozik <ran@heliosphere.io>
This commit is contained in:

committed by
GitHub

parent
fc8a02bcf8
commit
b47328e134
@ -15,6 +15,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- `opentelemetry-instrumentation-botocore` Fix span injection for lambda invoke
|
- `opentelemetry-instrumentation-botocore` Fix span injection for lambda invoke
|
||||||
([#663](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/663))
|
([#663](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/663))
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- `opentelemetry-instrumentation-urllib3` Updated `_RequestHookT` with two additional fields - the request body and the request headers
|
||||||
|
([#660](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/660))
|
||||||
|
|
||||||
## [1.5.0-0.24b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.5.0-0.24b0) - 2021-08-26
|
## [1.5.0-0.24b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.5.0-0.24b0) - 2021-08-26
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -90,7 +90,15 @@ _SUPPRESS_HTTP_INSTRUMENTATION_KEY = context.create_key(
|
|||||||
|
|
||||||
_UrlFilterT = typing.Optional[typing.Callable[[str], str]]
|
_UrlFilterT = typing.Optional[typing.Callable[[str], str]]
|
||||||
_RequestHookT = typing.Optional[
|
_RequestHookT = typing.Optional[
|
||||||
typing.Callable[[Span, urllib3.connectionpool.HTTPConnectionPool], None]
|
typing.Callable[
|
||||||
|
[
|
||||||
|
Span,
|
||||||
|
urllib3.connectionpool.HTTPConnectionPool,
|
||||||
|
typing.Dict,
|
||||||
|
typing.Optional[str],
|
||||||
|
],
|
||||||
|
None,
|
||||||
|
]
|
||||||
]
|
]
|
||||||
_ResponseHookT = typing.Optional[
|
_ResponseHookT = typing.Optional[
|
||||||
typing.Callable[
|
typing.Callable[
|
||||||
@ -150,6 +158,7 @@ def _instrument(
|
|||||||
method = _get_url_open_arg("method", args, kwargs).upper()
|
method = _get_url_open_arg("method", args, kwargs).upper()
|
||||||
url = _get_url(instance, args, kwargs, url_filter)
|
url = _get_url(instance, args, kwargs, url_filter)
|
||||||
headers = _prepare_headers(kwargs)
|
headers = _prepare_headers(kwargs)
|
||||||
|
body = _get_url_open_arg("body", args, kwargs)
|
||||||
|
|
||||||
span_name = "HTTP {}".format(method.strip())
|
span_name = "HTTP {}".format(method.strip())
|
||||||
span_attributes = {
|
span_attributes = {
|
||||||
@ -161,7 +170,7 @@ def _instrument(
|
|||||||
span_name, kind=SpanKind.CLIENT, attributes=span_attributes
|
span_name, kind=SpanKind.CLIENT, attributes=span_attributes
|
||||||
) as span:
|
) as span:
|
||||||
if callable(request_hook):
|
if callable(request_hook):
|
||||||
request_hook(span, instance)
|
request_hook(span, instance, headers, body)
|
||||||
inject(headers)
|
inject(headers)
|
||||||
|
|
||||||
with _suppress_further_instrumentation():
|
with _suppress_further_instrumentation():
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
import json
|
||||||
import typing
|
import typing
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
@ -45,6 +45,7 @@ class TestURLLib3Instrumentor(TestBase):
|
|||||||
httpretty.enable(allow_net_connect=False)
|
httpretty.enable(allow_net_connect=False)
|
||||||
httpretty.register_uri(httpretty.GET, self.HTTP_URL, body="Hello!")
|
httpretty.register_uri(httpretty.GET, self.HTTP_URL, body="Hello!")
|
||||||
httpretty.register_uri(httpretty.GET, self.HTTPS_URL, body="Hello!")
|
httpretty.register_uri(httpretty.GET, self.HTTPS_URL, body="Hello!")
|
||||||
|
httpretty.register_uri(httpretty.POST, self.HTTP_URL, body="Hello!")
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
@ -261,7 +262,7 @@ class TestURLLib3Instrumentor(TestBase):
|
|||||||
self.assert_success_span(response, self.HTTP_URL)
|
self.assert_success_span(response, self.HTTP_URL)
|
||||||
|
|
||||||
def test_hooks(self):
|
def test_hooks(self):
|
||||||
def request_hook(span, request):
|
def request_hook(span, request, body, headers):
|
||||||
span.update_name("name set from hook")
|
span.update_name("name set from hook")
|
||||||
|
|
||||||
def response_hook(span, request, response):
|
def response_hook(span, request, response):
|
||||||
@ -279,3 +280,30 @@ class TestURLLib3Instrumentor(TestBase):
|
|||||||
self.assertEqual(span.name, "name set from hook")
|
self.assertEqual(span.name, "name set from hook")
|
||||||
self.assertIn("response_hook_attr", span.attributes)
|
self.assertIn("response_hook_attr", span.attributes)
|
||||||
self.assertEqual(span.attributes["response_hook_attr"], "value")
|
self.assertEqual(span.attributes["response_hook_attr"], "value")
|
||||||
|
|
||||||
|
def test_request_hook_params(self):
|
||||||
|
def request_hook(span, request, headers, body):
|
||||||
|
span.set_attribute("request_hook_headers", json.dumps(headers))
|
||||||
|
span.set_attribute("request_hook_body", body)
|
||||||
|
|
||||||
|
URLLib3Instrumentor().uninstrument()
|
||||||
|
URLLib3Instrumentor().instrument(request_hook=request_hook,)
|
||||||
|
|
||||||
|
headers = {"header1": "value1", "header2": "value2"}
|
||||||
|
body = "param1=1¶m2=2"
|
||||||
|
|
||||||
|
pool = urllib3.HTTPConnectionPool("httpbin.org")
|
||||||
|
response = pool.request(
|
||||||
|
"POST", "/status/200", body=body, headers=headers
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(b"Hello!", response.data)
|
||||||
|
|
||||||
|
span = self.assert_span()
|
||||||
|
|
||||||
|
self.assertIn("request_hook_headers", span.attributes)
|
||||||
|
self.assertEqual(
|
||||||
|
span.attributes["request_hook_headers"], json.dumps(headers)
|
||||||
|
)
|
||||||
|
self.assertIn("request_hook_body", span.attributes)
|
||||||
|
self.assertEqual(span.attributes["request_hook_body"], body)
|
||||||
|
Reference in New Issue
Block a user