-
-
Notifications
You must be signed in to change notification settings - Fork 444
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
Automatic performance transactions for Webflux #1807
Comments
I've tried something similar as what is in Click to expand codepackage oopen.timemachine.config
import io.sentry.CustomSamplingContext
import io.sentry.HubAdapter
import io.sentry.ITransaction
import io.sentry.SentryLevel
import io.sentry.SentryTraceHeader
import io.sentry.SpanStatus
import io.sentry.TransactionContext
import io.sentry.exception.InvalidSentryTraceHeaderException
import org.springframework.http.server.reactive.ServerHttpRequest
import org.springframework.stereotype.Component
import org.springframework.web.reactive.HandlerMapping
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.WebFilter
import org.springframework.web.server.WebFilterChain
import org.springframework.web.util.pattern.PathPattern
import reactor.core.publisher.Mono
@Component
class SentryTransactionWebFilter(private val hub: HubAdapter = HubAdapter.getInstance()) : WebFilter {
companion object {
private const val TRANSACTION_OP = "http.server"
}
override fun filter(exchange: ServerWebExchange, chain: WebFilterChain): Mono<Void> {
val sentryTraceHeader = exchange.request.headers.getFirst(SentryTraceHeader.SENTRY_TRACE_HEADER)
// at this stage we are not able to get real transaction name
val transaction = startTransaction(exchange.request, sentryTraceHeader);
return chain.filter(exchange).doFinally {
// after all filters run, templated path pattern is available in request attribute
val transactionName = provideTransactionName(exchange);
// if transaction name is not resolved, the request has not been processed by a controller
// and we should not report it to Sentry
if (transactionName != null) {
transaction.name = transactionName;
transaction.operation = TRANSACTION_OP;
// if exception has been thrown, transaction status is already set to INTERNAL_ERROR, and
// httpResponse.getStatus() returns 200.
if (transaction.status == null) {
transaction.status = SpanStatus.fromHttpStatusCode(exchange.response.rawStatusCode ?: 0);
}
transaction.finish();
}
}.doOnError {
transaction.status = SpanStatus.INTERNAL_ERROR
transaction.throwable = it
}
}
private fun startTransaction(request: ServerHttpRequest, sentryTraceHeader: String?): ITransaction {
val name = "${request.methodValue} ${request.uri}"
val customSamplingContext = CustomSamplingContext()
customSamplingContext["request"] = request
if (sentryTraceHeader != null) {
try {
val contexts = TransactionContext.fromSentryTrace(
name, TRANSACTION_OP, SentryTraceHeader(sentryTraceHeader)
)
return hub.startTransaction(contexts, customSamplingContext, true)
} catch (e: InvalidSentryTraceHeaderException) {
hub.options.logger
.log(SentryLevel.DEBUG, e, "Failed to parse Sentry trace header: %s", e.message)
}
}
return hub.startTransaction(name, "http.server", customSamplingContext, true)
}
// Could be `io.sentry.spring.webflux.TransactionNameProvider`, but that class is private.
private fun provideTransactionName(
serverWebExchange: ServerWebExchange
): String? {
val pattern = serverWebExchange.getAttribute<PathPattern>(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)
return if (pattern != null) {
serverWebExchange.request.methodValue + " " + pattern.patternString
} else {
null
}
}
} |
@koenpunt if you feel submitting a PR, you can make |
@maciejwalkowiak can likely guide you as well, since he has made the WebFlux integration. |
First I need to figure out how to fix Webflux integration for error handlers. Either we stay with Reactor hook that re-binds Hub to current thread, or we move to using Reactor context. |
Any pointers for how to get the project to build in IntelliJ? I keep getting this error on gradle sync;
|
that's because the latest Android Gradle Plugin isn't compatible with IDEA but Android Studio, you can comment the Android projects as a temporary workaround -> |
Hi, is there any update on this issue? WebFlux transaction support would be a great feature to have. |
Not yet, someone tried to do a Draft PR tho #1809 |
We want to wait for #1819 before moving on with this. |
For anyone waiting for this. Please give our OpenTelemetry Integration a try. |
|
By now we've removed sentry from the project and rely on newrelic. But good to know it's implemented. |
Similar to SentryTracingFilter but for Webflux
The text was updated successfully, but these errors were encountered: