Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send http.request.method in span data #2896

Merged
merged 11 commits into from
Aug 17, 2023
Merged
4 changes: 2 additions & 2 deletions .github/workflows/integration-tests-benchmarks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
run: make stop

- name: Run All Tests in SauceLab
uses: saucelabs/saucectl-run-action@f401339df4c4b84945783f16b45fd545ac52a2eb # pin@v3
uses: saucelabs/saucectl-run-action@1c751bae46d3bf910cd10140e5a4e8259acd9fac # pin@v3
if: github.event_name != 'pull_request' && env.SAUCE_USERNAME != null
env:
GITHUB_TOKEN: ${{ github.token }}
Expand All @@ -51,7 +51,7 @@ jobs:
config-file: .sauce/sentry-uitest-android-benchmark.yml

- name: Run one test in SauceLab
uses: saucelabs/saucectl-run-action@f401339df4c4b84945783f16b45fd545ac52a2eb # pin@v3
uses: saucelabs/saucectl-run-action@1c751bae46d3bf910cd10140e5a4e8259acd9fac # pin@v3
if: github.event_name == 'pull_request' && env.SAUCE_USERNAME != null
env:
GITHUB_TOKEN: ${{ github.token }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration-tests-ui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
run: make stop

- name: Run Tests in SauceLab
uses: saucelabs/saucectl-run-action@f401339df4c4b84945783f16b45fd545ac52a2eb # pin@v3
uses: saucelabs/saucectl-run-action@1c751bae46d3bf910cd10140e5a4e8259acd9fac # pin@v3
env:
GITHUB_TOKEN: ${{ github.token }}
with:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Features

- Send `db.system` and `db.name` in span data ([#2894](https://github.com/getsentry/sentry-java/pull/2894))
- Send `http.request.method` in span data ([#2896](https://github.com/getsentry/sentry-java/pull/2896))

## 6.28.0

Expand All @@ -15,6 +16,7 @@
- Improve server side GraphQL support for spring-graphql and Nextflix DGS ([#2856](https://github.com/getsentry/sentry-java/pull/2856))
- If you have already been using `SentryDataFetcherExceptionHandler` that still works but has been deprecated. Please use `SentryGenericDataFetcherExceptionHandler` combined with `SentryInstrumentation` instead for better error reporting.
- More exceptions and errors caught and reported to Sentry by also looking at the `ExecutionResult` (more specifically its `errors`)
- You may want to filter out certain errors, please see [docs on filtering](https://docs.sentry.io/platforms/java/configuration/filtering/)
- More details for Sentry events: query, variables and response (where possible)
- Breadcrumbs for operation (query, mutation, subscription), data fetchers and data loaders (Spring only)
- Better hub propagation by using `GraphQLContext`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import io.sentry.android.okhttp.SentryOkHttpEventListener.Companion.SECURE_CONNE
import io.sentry.util.UrlUtils
import okhttp3.Request
import okhttp3.Response
import java.util.Locale
import java.util.concurrent.ConcurrentHashMap

private const val PROTOCOL_KEY = "protocol"
Expand Down Expand Up @@ -50,7 +51,7 @@ internal class SentryOkHttpEvent(private val hub: IHub, private val request: Req
callRootSpan?.setData("url", url)
callRootSpan?.setData("host", host)
callRootSpan?.setData("path", encodedPath)
callRootSpan?.setData(SpanDataConvention.HTTP_METHOD_KEY, method)
callRootSpan?.setData(SpanDataConvention.HTTP_METHOD_KEY, method.toUpperCase(Locale.ROOT))
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import io.sentry.SentryIntegrationPackageStorage
import io.sentry.SentryLevel
import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS
import io.sentry.SpanDataConvention
import io.sentry.SpanDataConvention.HTTP_METHOD_KEY
import io.sentry.SpanStatus
import io.sentry.TypeCheckHint.APOLLO_REQUEST
import io.sentry.TypeCheckHint.APOLLO_RESPONSE
Expand All @@ -34,6 +35,7 @@ import io.sentry.util.UrlUtils
import io.sentry.vendor.Base64
import okio.Buffer
import org.jetbrains.annotations.ApiStatus
import java.util.Locale

private const val TRACE_ORIGIN = "auto.graphql.apollo3"

Expand Down Expand Up @@ -171,7 +173,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor(
variables?.let {
setData("variables", it)
}
setData("http.method", method)
setData(HTTP_METHOD_KEY, method.toUpperCase(Locale.ROOT))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS
import io.sentry.SentryTraceHeader
import io.sentry.SentryTracer
import io.sentry.SpanDataConvention
import io.sentry.SpanDataConvention.HTTP_METHOD_KEY
import io.sentry.SpanStatus
import io.sentry.TraceContext
import io.sentry.TracesSamplingDecision
Expand Down Expand Up @@ -154,6 +155,7 @@ class SentryApollo3InterceptorTest {
verify(fixture.hub).captureTransaction(
check {
assertTransactionDetails(it, httpStatusCode = 404, contentLength = null)
assertEquals("POST", it.spans.first().data?.get(SpanDataConvention.HTTP_METHOD_KEY))
assertEquals(404, it.spans.first().data?.get(SpanDataConvention.HTTP_STATUS_CODE_KEY))
assertEquals(SpanStatus.NOT_FOUND, it.spans.first().status)
},
Expand Down Expand Up @@ -314,7 +316,7 @@ class SentryApollo3InterceptorTest {
assertTrue { httpClientSpan.description?.startsWith("Post LaunchDetails") == true }
assertNotNull(httpClientSpan.data) {
assertNotNull(it["operationId"])
assertEquals("Post", it["http.method"])
assertEquals("POST", it[HTTP_METHOD_KEY])
httpStatusCode?.let { code ->
assertEquals(code, it[SpanDataConvention.HTTP_STATUS_CODE_KEY])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import io.sentry.SpanStatus
import io.sentry.TypeCheckHint.APOLLO_REQUEST
import io.sentry.TypeCheckHint.APOLLO_RESPONSE
import io.sentry.util.TracingUtils
import java.util.Locale
import java.util.concurrent.Executor

private const val TRACE_ORIGIN = "auto.graphql.apollo"
Expand Down Expand Up @@ -72,6 +73,12 @@ class SentryApolloInterceptor(
} else {
span.status = SpanStatus.UNKNOWN
}
response.httpResponse.map { it.request().method() }.orNull()?.let {
span.setData(
SpanDataConvention.HTTP_METHOD_KEY,
it.toUpperCase(Locale.ROOT)
)
}

finish(span, requestWithHeader, response)
callBack.onResponse(response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class SentryApolloInterceptorTest {
check {
assertTransactionDetails(it)
assertEquals(SpanStatus.OK, it.spans.first().status)
assertEquals("POST", it.spans.first().data?.get(SpanDataConvention.HTTP_METHOD_KEY))
},
anyOrNull<TraceContext>(),
anyOrNull(),
Expand All @@ -116,6 +117,8 @@ class SentryApolloInterceptorTest {
assertTransactionDetails(it)
assertEquals(SpanStatus.PERMISSION_DENIED, it.spans.first().status)
assertEquals(403, it.spans.first().data?.get(SpanDataConvention.HTTP_STATUS_CODE_KEY))
// we do not have access to the request and method in case of an error
assertNull(it.spans.first().data?.get(SpanDataConvention.HTTP_METHOD_KEY))
},
anyOrNull<TraceContext>(),
anyOrNull(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -56,7 +57,9 @@ public Response execute(final @NotNull Request request, final @NotNull Request.O
ISpan span = activeSpan.startChild("http.client");
span.getSpanContext().setOrigin(TRACE_ORIGIN);
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.parse(request.url());
span.setDescription(request.httpMethod().name() + " " + urlDetails.getUrlOrFallback());
final @NotNull String method = request.httpMethod().name();
span.setDescription(method + " " + urlDetails.getUrlOrFallback());
span.setData(SpanDataConvention.HTTP_METHOD_KEY, method.toUpperCase(Locale.ROOT));
urlDetails.applyToSpan(span);

final @NotNull Request modifiedRequest = maybeAddTracingHeaders(request, span);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class SentryFeignClientTest {
assertEquals("http.client", httpClientSpan.operation)
assertEquals("GET ${fixture.server.url("/status/200")}", httpClientSpan.description)
assertEquals(201, httpClientSpan.data[SpanDataConvention.HTTP_STATUS_CODE_KEY])
assertEquals("GET", httpClientSpan.data[SpanDataConvention.HTTP_METHOD_KEY])
assertEquals(SpanStatus.OK, httpClientSpan.status)
assertEquals("auto.http.openfeign", httpClientSpan.spanContext.origin)
assertTrue(httpClientSpan.isFinished)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.sentry.util.TracingUtils;
import io.sentry.util.UrlUtils;
import java.io.IOException;
import java.util.Locale;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.http.HttpRequest;
Expand Down Expand Up @@ -53,6 +54,7 @@ public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) {
request.getMethod() != null ? request.getMethod().name() : "unknown";
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.parse(request.getURI().toString());
span.setDescription(methodName + " " + urlDetails.getUrlOrFallback());
span.setData(SpanDataConvention.HTTP_METHOD_KEY, methodName.toUpperCase(Locale.ROOT));
urlDetails.applyToSpan(span);

maybeAddTracingHeaders(request, span);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.sentry.SpanStatus;
import io.sentry.util.Objects;
import io.sentry.util.TracingUtils;
import java.util.Locale;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.web.reactive.function.client.ClientRequest;
Expand Down Expand Up @@ -42,7 +43,9 @@ public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) {

final ISpan span = activeSpan.startChild("http.client");
span.getSpanContext().setOrigin(TRACE_ORIGIN);
span.setDescription(request.method().name() + " " + request.url());
final @NotNull String method = request.method().name();
span.setDescription(method + " " + request.url());
span.setData(SpanDataConvention.HTTP_METHOD_KEY, method.toUpperCase(Locale.ROOT));

final @NotNull ClientRequest modifiedRequest = maybeAddTracingHeaders(request, span);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.sentry.util.TracingUtils;
import io.sentry.util.UrlUtils;
import java.io.IOException;
import java.util.Locale;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.http.HttpRequest;
Expand Down Expand Up @@ -54,6 +55,7 @@ public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) {
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.parse(request.getURI().toString());
urlDetails.applyToSpan(span);
span.setDescription(methodName + " " + urlDetails.getUrlOrFallback());
span.setData(SpanDataConvention.HTTP_METHOD_KEY, methodName.toUpperCase(Locale.ROOT));

maybeAddTracingHeaders(request, span);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.sentry.util.Objects;
import io.sentry.util.TracingUtils;
import io.sentry.util.UrlUtils;
import java.util.Locale;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.web.reactive.function.client.ClientRequest;
Expand Down Expand Up @@ -43,7 +44,9 @@ public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) {
final ISpan span = activeSpan.startChild("http.client");
span.getSpanContext().setOrigin(TRACE_ORIGIN);
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.parse(request.url().toString());
span.setDescription(request.method().name() + " " + urlDetails.getUrlOrFallback());
final @NotNull String method = request.method().name();
span.setDescription(method + " " + urlDetails.getUrlOrFallback());
span.setData(SpanDataConvention.HTTP_METHOD_KEY, method.toUpperCase(Locale.ROOT));
urlDetails.applyToSpan(span);

final ClientRequest clientRequestWithSentryTraceHeader = maybeAddHeaders(request, span);
Expand Down
2 changes: 1 addition & 1 deletion sentry/src/main/java/io/sentry/SpanDataConvention.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public interface SpanDataConvention {
String DB_NAME_KEY = "db.name";
String HTTP_QUERY_KEY = "http.query";
String HTTP_FRAGMENT_KEY = "http.fragment";
String HTTP_METHOD_KEY = "http.method";
String HTTP_METHOD_KEY = "http.request.method";
String HTTP_STATUS_CODE_KEY = "http.response.status_code";
String HTTP_RESPONSE_CONTENT_LENGTH_KEY = "http.response_content_length";
String BLOCKED_MAIN_THREAD_KEY = "blocked_main_thread";
Expand Down