Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ constructor(
operationType: String?,
operationId: String?,
): ISpan {
val urlDetails = UrlUtils.parse(request.url)
val urlDetails = UrlUtils.parse(request.url, scopes.options.dataCollectionResolver)
val method = request.method.name

val operation = if (operationType != null) "http.graphql.$operationType" else "http.graphql"
Expand Down Expand Up @@ -232,7 +232,13 @@ constructor(
span.finish()
}

val breadcrumb = Breadcrumb.http(request.url, request.method.name, statusCode)
val breadcrumb =
Breadcrumb.http(
request.url,
request.method.name,
statusCode,
scopes.options.dataCollectionResolver,
)

request.body?.contentLength.ifHasValidLength { contentLength ->
breadcrumb.setData("request_body_size", contentLength)
Expand Down Expand Up @@ -351,7 +357,7 @@ constructor(
// url will be: https://api.github.com/users/getsentry/repos/
// ideally we'd like a parameterized url: https://api.github.com/users/{user}/repos/
// but that's not possible
val urlDetails = UrlUtils.parse(request.url)
val urlDetails = UrlUtils.parse(request.url, scopes.options.dataCollectionResolver)

// return if its not a target match
if (!PropagationTargetsUtils.contain(failedRequestTargets, urlDetails.urlOrFallback)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ constructor(
operationType: String?,
operationId: String?,
): ISpan {
val urlDetails = UrlUtils.parse(request.url)
val urlDetails = UrlUtils.parse(request.url, scopes.options.dataCollectionResolver)
val method = request.method.name

val operation = if (operationType != null) "http.graphql.$operationType" else "http.graphql"
Expand Down Expand Up @@ -231,7 +231,13 @@ constructor(
span.finish()
}

val breadcrumb = Breadcrumb.http(request.url, request.method.name, statusCode)
val breadcrumb =
Breadcrumb.http(
request.url,
request.method.name,
statusCode,
scopes.options.dataCollectionResolver,
)

request.body?.contentLength.ifHasValidLength { contentLength ->
breadcrumb.setData("request_body_size", contentLength)
Expand Down Expand Up @@ -350,7 +356,7 @@ constructor(
// url will be: https://api.github.com/users/getsentry/repos/
// ideally we'd like a parameterized url: https://api.github.com/users/{user}/repos/
// but that's not possible
val urlDetails = UrlUtils.parse(request.url)
val urlDetails = UrlUtils.parse(request.url, scopes.options.dataCollectionResolver)

// return if it's not a target match
if (!PropagationTargetsUtils.contain(failedRequestTargets, urlDetails.urlOrFallback)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,12 @@ class SentryApolloInterceptor(
val httpRequest = httpResponse.request()

val breadcrumb =
Breadcrumb.http(httpRequest.url().toString(), httpRequest.method(), httpResponse.code())
Breadcrumb.http(
httpRequest.url().toString(),
httpRequest.method(),
httpResponse.code(),
scopes.options.dataCollectionResolver,
)

httpRequest.body()?.contentLength().ifHasValidLength { contentLength ->
breadcrumb.setData("request_body_size", contentLength)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ internal object SentryKtorClientUtils {
request: HttpRequest,
response: HttpResponse,
) {
val urlDetails = UrlUtils.parse(request.url.toString())
val urlDetails = UrlUtils.parse(request.url.toString(), scopes.options.dataCollectionResolver)

val mechanism = Mechanism().apply { type = "SentryKtorClientPlugin" }
val exception =
Expand Down Expand Up @@ -116,7 +116,12 @@ internal object SentryKtorClientUtils {
endTimestamp: SentryDate?,
) {
val breadcrumb =
Breadcrumb.http(request.url.toString(), request.method.value, response.status.value)
Breadcrumb.http(
request.url.toString(),
request.method.value,
response.status.value,
scopes.options.dataCollectionResolver,
)
breadcrumb.setData(
SpanDataConvention.HTTP_RESPONSE_CONTENT_LENGTH_KEY,
response.contentLength(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal class SentryOkHttpEvent(private val scopes: IScopes, private val reques
private var method: String

init {
val urlDetails = UrlUtils.parse(request.url.toString())
val urlDetails = UrlUtils.parse(request.url.toString(), scopes.options.dataCollectionResolver)
url = urlDetails.urlOrFallback
method = request.method

Expand Down Expand Up @@ -62,7 +62,7 @@ internal class SentryOkHttpEvent(private val scopes: IScopes, private val reques
* due to interceptors.
*/
fun setRequest(request: Request) {
val urlDetails = UrlUtils.parse(request.url.toString())
val urlDetails = UrlUtils.parse(request.url.toString(), scopes.options.dataCollectionResolver)
url = urlDetails.urlOrFallback

val host: String = request.url.host
Expand All @@ -78,8 +78,8 @@ internal class SentryOkHttpEvent(private val scopes: IScopes, private val reques
breadcrumb.setData("url", urlDetails.url!!)
}
breadcrumb.setData("method", method.uppercase())
if (urlDetails.query != null) {
breadcrumb.setData("http.query", urlDetails.query!!)
urlDetails.query?.let {
breadcrumb.setData("http.query", it)
}
if (urlDetails.fragment != null) {
breadcrumb.setData("http.fragment", urlDetails.fragment!!)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public open class SentryOkHttpInterceptor(
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()

val urlDetails = UrlUtils.parse(request.url.toString())
val urlDetails = UrlUtils.parse(request.url.toString(), scopes.options.dataCollectionResolver)
val url = urlDetails.urlOrFallback
val method = request.method

Expand Down Expand Up @@ -235,7 +235,13 @@ public open class SentryOkHttpInterceptor(
startTimestamp: Long,
networkDetailData: NetworkRequestData?,
) {
val breadcrumb = Breadcrumb.http(request.url.toString(), request.method, code)
val breadcrumb =
Breadcrumb.http(
request.url.toString(),
request.method,
code,
scopes.options.dataCollectionResolver,
)

// Track request and response body sizes for the breadcrumb
request.body?.contentLength().ifHasValidLength {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal object SentryOkHttpUtils {
// url will be: https://api.github.com/users/getsentry/repos/
// ideally we'd like a parameterized url: https://api.github.com/users/{user}/repos/
// but that's not possible
val urlDetails = UrlUtils.parse(request.url.toString())
val urlDetails = UrlUtils.parse(request.url.toString(), scopes.options.dataCollectionResolver)

val mechanism = Mechanism().apply { type = "SentryOkHttpInterceptor" }
val exception =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,26 @@ class SentryOkHttpInterceptorTest {
)
}

@Test
fun `data collection filters failed request query parameters`() {
val sut =
fixture.getSut(
captureFailedRequests = true,
httpStatusCode = 500,
optionsConfiguration = { it.dataCollection.setUserInfo(false) },
)

sut.newCall(getRequest(url = "/hello?name=value&token=secret")).execute()

verify(fixture.scopes)
.captureEvent(
check {
assertEquals("name=value&token=[Filtered]", it.request!!.queryString)
},
any<Hint>(),
)
}

@Test
fun `captures an error event with request body size`() {
val sut = fixture.getSut(captureFailedRequests = true, httpStatusCode = 500)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ public Response execute(final @NotNull Request request, final @NotNull Request.O
final @NotNull SpanOptions spanOptions = new SpanOptions();
spanOptions.setOrigin(TRACE_ORIGIN);
ISpan span = activeSpan.startChild("http.client", null, spanOptions);
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.parse(request.url());
final @NotNull UrlUtils.UrlDetails urlDetails =
UrlUtils.parse(request.url(), scopes.getOptions().getDataCollectionResolver());
final @NotNull String method = request.httpMethod().name();
span.setDescription(method + " " + urlDetails.getUrlOrFallback());
span.setData(SpanDataConvention.HTTP_METHOD_KEY, method.toUpperCase(Locale.ROOT));
Expand Down Expand Up @@ -158,7 +159,8 @@ private void addBreadcrumb(final @NotNull Request request, final @Nullable Respo
Breadcrumb.http(
request.url(),
request.httpMethod().name(),
response != null ? response.status() : null);
response != null ? response.status() : null,
scopes.getOptions().getDataCollectionResolver());
breadcrumb.setData("request_body_size", request.body() != null ? request.body().length : 0);
if (response != null && response.body() != null && response.body().length() != null) {
breadcrumb.setData("response_body_size", response.body().length());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@ private void addRequestAttributesToScope(
if (request.getUrl() == null) {
final @Nullable String url = extractUrl(attributes, options);
if (url != null) {
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.parse(url);
final @NotNull UrlUtils.UrlDetails urlDetails =
UrlUtils.parse(url, options.getDataCollectionResolver());
urlDetails.applyToRequest(request);
}
}

if (request.getQueryString() == null) {
final @Nullable String query = attributes.get(UrlAttributes.URL_QUERY);
if (query != null) {
request.setQueryString(query);
request.setQueryString(
UrlUtils.filterQueryParams(query, options.getDataCollectionResolver()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,36 @@ class OpenTelemetryAttributesExtractorTest {
thenQueryIsSetTo("q=123456&b=X")
}

@Test
fun `data collection filters URL query attributes`() {
fixture.options.dataCollection.setUserInfo(false)
givenAttributes(
mapOf(
HttpAttributes.HTTP_REQUEST_METHOD to "GET",
UrlAttributes.URL_QUERY to "name=value&token=secret",
)
)

whenExtractingAttributes()

thenQueryIsSetTo("name=value&token=[Filtered]")
}

@Test
fun `data collection can disable URL query attributes`() {
fixture.options.dataCollection.queryParams = KeyValueCollectionBehavior.off()
givenAttributes(
mapOf(
HttpAttributes.HTTP_REQUEST_METHOD to "GET",
UrlAttributes.URL_QUERY to "name=value",
)
)

whenExtractingAttributes()

assertNull(fixture.scope.request!!.queryString)
}

@Test
fun `when there is an existing request on scope it is filled with more details`() {
fixture.scope.request = Request().also { it.bodySize = 123L }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ public SentryRequestHttpServletRequestProcessor(
final Request sentryRequest = new Request();
sentryRequest.setMethod(httpRequest.getMethod());
final @NotNull UrlUtils.UrlDetails urlDetails =
UrlUtils.parse(httpRequest.getRequestURL().toString());
UrlUtils.parse(httpRequest.getRequestURL().toString(), options.getDataCollectionResolver());
urlDetails.applyToRequest(sentryRequest);
sentryRequest.setQueryString(httpRequest.getQueryString());
sentryRequest.setQueryString(
UrlUtils.filterQueryParams(
httpRequest.getQueryString(), options.getDataCollectionResolver()));
sentryRequest.setHeaders(resolveHeadersMap(httpRequest));

event.setRequest(sentryRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ public SentryRequestHttpServletRequestProcessor(
final Request sentryRequest = new Request();
sentryRequest.setMethod(httpRequest.getMethod());
final @NotNull UrlUtils.UrlDetails urlDetails =
UrlUtils.parse(httpRequest.getRequestURL().toString());
UrlUtils.parse(httpRequest.getRequestURL().toString(), options.getDataCollectionResolver());
urlDetails.applyToRequest(sentryRequest);
sentryRequest.setQueryString(httpRequest.getQueryString());
sentryRequest.setQueryString(
UrlUtils.filterQueryParams(
httpRequest.getQueryString(), options.getDataCollectionResolver()));
sentryRequest.setHeaders(resolveHeadersMap(httpRequest));

event.setRequest(sentryRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,33 @@ class SentryRequestHttpServletRequestProcessorTest {
assertEquals("param1=xyz", eventRequest.queryString)
}

@Test
fun `data collection filters query parameters`() {
val request =
MockMvcRequestBuilders.get(URI.create("http://example.com?name=value&token=secret"))
.buildRequest(MockServletContext())
val options = SentryOptions().also { it.dataCollection.setUserInfo(false) }
val event = SentryEvent()

SentryRequestHttpServletRequestProcessor(request, options).process(event, Hint())

assertEquals("name=value&token=[Filtered]", event.request!!.queryString)
}

@Test
fun `data collection can disable query parameters`() {
val request =
MockMvcRequestBuilders.get(URI.create("http://example.com?name=value"))
.buildRequest(MockServletContext())
val options =
SentryOptions().also { it.dataCollection.queryParams = KeyValueCollectionBehavior.off() }
val event = SentryEvent()

SentryRequestHttpServletRequestProcessor(request, options).process(event, Hint())

assertNull(event.request!!.queryString)
}

@Test
fun `attaches header with multiple values`() {
val request =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ public SentryRequestResolver(final @NotNull IScopes scopes) {
final Request sentryRequest = new Request();
sentryRequest.setMethod(httpRequest.getMethod());
final @NotNull UrlUtils.UrlDetails urlDetails =
UrlUtils.parse(httpRequest.getRequestURL().toString());
UrlUtils.parse(
httpRequest.getRequestURL().toString(),
scopes.getOptions().getDataCollectionResolver());
urlDetails.applyToRequest(sentryRequest);
sentryRequest.setQueryString(httpRequest.getQueryString());
sentryRequest.setQueryString(
UrlUtils.filterQueryParams(
httpRequest.getQueryString(), scopes.getOptions().getDataCollectionResolver()));
final @NotNull List<String> additionalSecurityCookieNames =
extractSecurityCookieNamesOrUseCached(httpRequest);
sentryRequest.setHeaders(resolveHeadersMap(httpRequest, additionalSecurityCookieNames));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ public SentrySpanClientHttpRequestInterceptor(
final ISpan span = activeSpan.startChild("http.client", null, spanOptions);
final String methodName =
request.getMethod() != null ? request.getMethod().name() : "unknown";
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.parse(request.getURI().toString());
final @NotNull UrlUtils.UrlDetails urlDetails =
UrlUtils.parse(
request.getURI().toString(), scopes.getOptions().getDataCollectionResolver());
span.setDescription(methodName + " " + urlDetails.getUrlOrFallback());
span.setData(SpanDataConvention.HTTP_METHOD_KEY, methodName.toUpperCase(Locale.ROOT));
urlDetails.applyToSpan(span);
Expand Down Expand Up @@ -135,7 +137,11 @@ private void addBreadcrumb(
final String methodName = request.getMethod() != null ? request.getMethod().name() : "unknown";

final Breadcrumb breadcrumb =
Breadcrumb.http(request.getURI().toString(), methodName, responseStatusCode);
Breadcrumb.http(
request.getURI().toString(),
methodName,
responseStatusCode,
scopes.getOptions().getDataCollectionResolver());
breadcrumb.setData("request_body_size", body.length);

final Hint hint = new Hint();
Expand Down
Loading
Loading