Skip to content

Commit bab5f0e

Browse files
committed
Added redact_url which redacts both credentials and query strings. Modified code for instrumentations and corresponding tests.
1 parent e499841 commit bab5f0e

File tree

17 files changed

+89
-47
lines changed

17 files changed

+89
-47
lines changed

instrumentation/opentelemetry-instrumentation-aiohttp-client/src/opentelemetry/instrumentation/aiohttp_client/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def response_hook(span: Span, params: typing.Union[
119119
from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE
120120
from opentelemetry.trace import Span, SpanKind, TracerProvider, get_tracer
121121
from opentelemetry.trace.status import Status, StatusCode
122-
from opentelemetry.util.http import remove_url_credentials, sanitize_method, redact_query_parameters
122+
from opentelemetry.util.http import sanitize_method, redact_url
123123

124124
_UrlFilterT = typing.Optional[typing.Callable[[yarl.URL], str]]
125125
_RequestHookT = typing.Optional[
@@ -240,9 +240,9 @@ async def on_request_start(
240240
method = params.method
241241
request_span_name = _get_span_name(method)
242242
request_url = (
243-
redact_query_parameters(remove_url_credentials(trace_config_ctx.url_filter(params.url)))
243+
redact_url(trace_config_ctx.url_filter(params.url))
244244
if callable(trace_config_ctx.url_filter)
245-
else redact_query_parameters(remove_url_credentials(str(params.url)))
245+
else redact_url(str(params.url))
246246
)
247247

248248
span_attributes = {}

instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -587,16 +587,16 @@ async def do_request(url):
587587
)
588588
self.memory_exporter.clear()
589589

590-
def test_credential_removal(self):
590+
def test_remove_sensitive_params(self):
591591
trace_configs = [aiohttp_client.create_trace_config()]
592592

593-
app = HttpServerMock("test_credential_removal")
593+
app = HttpServerMock("test_remove_sensitive_params")
594594

595595
@app.route("/status/200")
596596
def index():
597597
return "hello"
598598

599-
url = "http://username:password@localhost:5000/status/200"
599+
url = "http://username:password@localhost:5000/status/200?Signature=secret"
600600

601601
with app.run("localhost", 5000):
602602
with self.subTest(url=url):
@@ -618,7 +618,7 @@ async def do_request(url):
618618
(StatusCode.UNSET, None),
619619
{
620620
HTTP_METHOD: "GET",
621-
HTTP_URL: ("http://localhost:5000/status/200"),
621+
HTTP_URL: ("http://REDACTED:REDACTED@localhost:5000/status/200?Signature=REDACTED"),
622622
HTTP_STATUS_CODE: int(HTTPStatus.OK),
623623
},
624624
)

instrumentation/opentelemetry-instrumentation-aiohttp-server/src/opentelemetry/instrumentation/aiohttp_server/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ async def hello(request):
5757
from opentelemetry.semconv.metrics import MetricInstruments
5858
from opentelemetry.semconv.trace import SpanAttributes
5959
from opentelemetry.trace.status import Status, StatusCode
60-
from opentelemetry.util.http import get_excluded_urls, remove_url_credentials, redact_query_parameters
60+
from opentelemetry.util.http import get_excluded_urls, redact_url
6161

6262
_duration_attrs = [
6363
SpanAttributes.HTTP_METHOD,
@@ -146,7 +146,7 @@ def collect_request_attributes(request: web.Request) -> Dict:
146146
SpanAttributes.HTTP_ROUTE: _get_view_func(request),
147147
SpanAttributes.HTTP_FLAVOR: f"{request.version.major}.{request.version.minor}",
148148
SpanAttributes.HTTP_TARGET: request.path,
149-
SpanAttributes.HTTP_URL: redact_query_parameters(remove_url_credentials(http_url)),
149+
SpanAttributes.HTTP_URL: redact_url(http_url),
150150
}
151151

152152
http_method = request.method

instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,8 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
258258
get_custom_headers,
259259
normalise_request_header_name,
260260
normalise_response_header_name,
261-
remove_url_credentials,
262261
sanitize_method,
263-
redact_query_parameters,
262+
redact_url,
264263
)
265264

266265

@@ -356,7 +355,7 @@ def collect_request_attributes(
356355
if _report_old(sem_conv_opt_in_mode):
357356
_set_http_url(
358357
result,
359-
redact_query_parameters(remove_url_credentials(http_url)),
358+
redact_url(http_url),
360359
_StabilityMode.DEFAULT,
361360
)
362361
http_method = scope.get("method", "")

instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,12 +1796,13 @@ def test_response_attributes_invalid_status_code(self):
17961796
otel_asgi.set_status_code(self.span, "Invalid Status Code")
17971797
self.assertEqual(self.span.set_status.call_count, 1)
17981798

1799-
def test_credential_removal(self):
1799+
def test_remove_sensitive_params(self):
18001800
self.scope["server"] = ("username:password@mock", 80)
18011801
self.scope["path"] = "/status/200"
1802+
self.scope["query_string"] = b"X-Goog-Signature=1234567890"
18021803
attrs = otel_asgi.collect_request_attributes(self.scope)
18031804
self.assertEqual(
1804-
attrs[SpanAttributes.HTTP_URL], "http://mock/status/200"
1805+
attrs[SpanAttributes.HTTP_URL], "http://REDACTED:REDACTED@mock/status/200?X-Goog-Signature=REDACTED"
18051806
)
18061807

18071808
def test_collect_target_attribute_missing(self):

instrumentation/opentelemetry-instrumentation-httpx/src/opentelemetry/instrumentation/httpx/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ async def async_response_hook(span, request, response):
244244
from opentelemetry.trace import SpanKind, Tracer, TracerProvider, get_tracer
245245
from opentelemetry.trace.span import Span
246246
from opentelemetry.trace.status import StatusCode
247-
from opentelemetry.util.http import remove_url_credentials, sanitize_method, redact_query_parameters
247+
from opentelemetry.util.http import sanitize_method, redact_url
248248

249249
_logger = logging.getLogger(__name__)
250250

@@ -298,7 +298,7 @@ def _extract_parameters(
298298
# In httpx >= 0.20.0, handle_request receives a Request object
299299
request: httpx.Request = args[0]
300300
method = request.method.encode()
301-
url = httpx.URL(redact_query_parameters(remove_url_credentials(str(request.url))))
301+
url = httpx.URL(redact_url(str(request.url)))
302302
headers = request.headers
303303
stream = request.stream
304304
extensions = request.extensions

instrumentation/opentelemetry-instrumentation-httpx/tests/test_httpx_integration.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,12 +1127,12 @@ def perform_request(
11271127
return self.client.request(method, url, headers=headers)
11281128
return client.request(method, url, headers=headers)
11291129

1130-
def test_credential_removal(self):
1131-
new_url = "http://username:password@mock/status/200"
1130+
def test_remove_sensitive_params(self):
1131+
new_url = "http://username:password@mock/status/200?sig=secret"
11321132
self.perform_request(new_url)
11331133
span = self.assert_span()
11341134

1135-
self.assertEqual(span.attributes[SpanAttributes.HTTP_URL], self.URL)
1135+
self.assertEqual(span.attributes[SpanAttributes.HTTP_URL], "http://REDACTED:REDACTED@mock/status/200?sig=REDACTED")
11361136

11371137

11381138
class TestAsyncIntegration(BaseTestCases.BaseManualTest):
@@ -1196,12 +1196,12 @@ def test_basic_multiple(self):
11961196
)
11971197
self.assert_span(num_spans=2)
11981198

1199-
def test_credential_removal(self):
1200-
new_url = "http://username:password@mock/status/200"
1199+
def test_remove_sensitive_params(self):
1200+
new_url = "http://username:password@mock/status/200?Signature=secret"
12011201
self.perform_request(new_url)
12021202
span = self.assert_span()
12031203

1204-
self.assertEqual(span.attributes[SpanAttributes.HTTP_URL], self.URL)
1204+
self.assertEqual(span.attributes[SpanAttributes.HTTP_URL], "http://REDACTED:REDACTED@mock/status/200?Signature=REDACTED")
12051205

12061206

12071207
class TestSyncInstrumentationIntegration(BaseTestCases.BaseInstrumentorTest):

instrumentation/opentelemetry-instrumentation-requests/src/opentelemetry/instrumentation/requests/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,8 @@ def response_hook(span, request_obj, response):
147147
ExcludeList,
148148
get_excluded_urls,
149149
parse_excluded_urls,
150-
remove_url_credentials,
151150
sanitize_method,
152-
redact_query_parameters,
151+
redact_url,
153152
)
154153
from opentelemetry.util.http.httplib import set_ip_on_next_http_connection
155154

@@ -233,7 +232,7 @@ def get_or_create_headers():
233232
method = request.method
234233
span_name = get_default_span_name(method)
235234

236-
url = redact_query_parameters(remove_url_credentials(request.url))
235+
url = redact_url(request.url)
237236

238237

239238
span_attributes = {}

instrumentation/opentelemetry-instrumentation-requests/tests/test_requests_integration.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -686,12 +686,12 @@ def perform_request(url: str, session: requests.Session = None):
686686
return requests.get(url, timeout=5)
687687
return session.get(url)
688688

689-
def test_credential_removal(self):
690-
new_url = "http://username:password@mock/status/200"
689+
def test_remove_sensitive_params(self):
690+
new_url = "http://username:password@mock/status/200?AWSAccessKeyId=secret"
691691
self.perform_request(new_url)
692692
span = self.assert_span()
693693

694-
self.assertEqual(span.attributes[HTTP_URL], self.URL)
694+
self.assertEqual(span.attributes[HTTP_URL], "http://REDACTED:REDACTED@mock/status/200?AWSAccessKeyId=REDACTED")
695695

696696
def test_if_headers_equals_none(self):
697697
result = requests.get(self.URL, headers=None, timeout=5)

instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from opentelemetry.propagate import inject
2323
from opentelemetry.semconv.trace import SpanAttributes
2424
from opentelemetry.trace.status import Status, StatusCode
25-
from opentelemetry.util.http import remove_url_credentials, redact_query_parameters
25+
from opentelemetry.util.http import redact_url
2626

2727

2828
def _normalize_request(args, kwargs):
@@ -75,7 +75,7 @@ def fetch_async(
7575

7676
if span.is_recording():
7777
attributes = {
78-
SpanAttributes.HTTP_URL: redact_query_parameters(remove_url_credentials(request.url)),
78+
SpanAttributes.HTTP_URL: redact_url(request.url),
7979
SpanAttributes.HTTP_METHOD: request.method,
8080
}
8181
for key, value in attributes.items():
@@ -161,7 +161,7 @@ def _finish_tracing_callback(
161161
def _create_metric_attributes(response):
162162
metric_attributes = {
163163
SpanAttributes.HTTP_STATUS_CODE: response.code,
164-
SpanAttributes.HTTP_URL: redact_query_parameters(remove_url_credentials(response.request.url)),
164+
SpanAttributes.HTTP_URL: redact_url(response.request.url),
165165
SpanAttributes.HTTP_METHOD: response.request.method,
166166
}
167167

0 commit comments

Comments
 (0)