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

Automatically downsample transaction when system is under load (backpressure) #3072

Merged
merged 70 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
0566579
Move enableNdk to SentryAndroidOptions (#2793)
markushi Jun 29, 2023
4f55fd9
Capture failed HTTP requests by default (#2794)
markushi Jul 7, 2023
d6fc22e
Merge branch 'main' into feat/7.0.0
markushi Jul 12, 2023
36afdd4
Fix Changelog
markushi Jul 12, 2023
590fcb8
Merge branch 'feat/7.0.0' of github.com:getsentry/sentry-java into fe…
markushi Jul 12, 2023
1faf168
7.0.0 -> Unreleased in changelog
romtsn Jul 19, 2023
cae0eea
Do not overwrite UI transaction status if set by the user (#2852)
romtsn Jul 20, 2023
3838091
Reduce flush timeout to 4s on Android to avoid ANRs (#2858)
markushi Jul 21, 2023
19fca04
Set ip_address = {{auto}} by default (#2860)
markushi Jul 24, 2023
6182cc2
Merge branch 'main' into feat/7.0.0
romtsn Jul 25, 2023
7717683
Fix test
romtsn Jul 25, 2023
1c0c691
Measure AppStart time till First Draw (#2851)
romtsn Jul 25, 2023
803f03c
update coroutines to 1.6.1, use CopyableThreadContextElement (#2838)
lbloder Jul 25, 2023
8e78ac3
Reduce timeout of AsyncHttpTransport to avoid ANR (#2879)
stefanosiano Aug 4, 2023
0b3de21
Add deadline timeout for automatic transactions (#2865)
markushi Aug 8, 2023
ee21d53
Apollo v2 BeforeSpanCallback: Allow returning null (#2890)
markushi Aug 8, 2023
55b103c
Start a new automatic transaction on every click (#2891)
markushi Aug 11, 2023
b0e93e8
Bump min API to 19 (#2883)
stefanosiano Aug 16, 2023
bdf1379
Fix don't overwrite the span status of unfinished spans (#2859)
markushi Aug 28, 2023
cd268a3
(Android) Use root transaction instead of last active span (#2855)
markushi Aug 31, 2023
1821d66
Merge branch 'main' into feat/7.0.0
romtsn Sep 8, 2023
421d724
Fix changelog
markushi Sep 8, 2023
c383ed1
Make SDK unity-compatible (#2847)
romtsn Sep 8, 2023
72e23fc
Capture unfinished transactions on crash (#2938)
romtsn Sep 27, 2023
d6cd78c
Observe network state to upload any unsent envelopes (#2910)
markushi Sep 28, 2023
227698f
Merge branch 'main' into feat/7.0.0
romtsn Sep 28, 2023
ca595ea
Highlight breaking chnages in changelog
romtsn Sep 28, 2023
ece39a6
Api dump
romtsn Sep 28, 2023
7554695
release: 7.0.0-beta.1
getsentry-bot Sep 28, 2023
96f4697
Merge branch 'release/7.0.0-beta.1' into feat/7.0.0
Sep 29, 2023
1513e7e
Improve start transaction overloads (#2964)
adinauer Oct 6, 2023
e0b84aa
Guard raw logback message and parameters with `sendDefaultPii` if an …
adinauer Oct 11, 2023
f778374
Merge branch 'main' into feat/7.0.0
romtsn Oct 20, 2023
1f3f5dc
Use `getMyMemoryState()` instead of `getRunningAppProcesses()` (#3004)
romtsn Oct 23, 2023
607e89b
Send SDK frames in case of crashes (#3021)
romtsn Nov 3, 2023
a41ca67
Merge branch 'main' into feat/7.0.0
romtsn Nov 7, 2023
5f02b63
Fix build
romtsn Nov 7, 2023
7fec166
Fix test
romtsn Nov 7, 2023
1e7d50d
Merge branch 'main' into feat/7.0.0
romtsn Nov 7, 2023
3f122f3
release: 7.0.0-rc.1
getsentry-bot Nov 8, 2023
b20971e
Merge branch 'release/7.0.0-rc.1' into feat/7.0.0
Nov 8, 2023
209ee17
add sentry-okhttp module (#3005)
ToppleTheNun Nov 24, 2023
c2a0526
Merge branch 'main' into feat/7.0.0
romtsn Nov 24, 2023
3a42bf3
Prepare changelog for v7
romtsn Nov 27, 2023
eca1a76
wording
romtsn Nov 27, 2023
eb245c4
Respect maxSpans for nested child spans (#3065)
romtsn Nov 27, 2023
3e6db94
Capture failed requests for Apollo by default
romtsn Nov 27, 2023
1a2e334
Address review
romtsn Nov 27, 2023
1fd1492
Merge branch 'main' into feat/7.0.0
romtsn Nov 27, 2023
b3170f4
Move more stuff to background for SendEnvelopeIntegrations
romtsn Nov 27, 2023
29b704b
spotless
romtsn Nov 27, 2023
12cde1a
Fix tests
romtsn Nov 27, 2023
741b219
Always execute callback in withScope (#3066)
lbloder Nov 28, 2023
9f185cb
Mention startTransaction overloads removal
romtsn Nov 28, 2023
bcc769f
Backpressure WIP
adinauer Dec 1, 2023
44b2903
Merge branch 'main' into feat/backpressure
adinauer Dec 1, 2023
0d3bb1b
fix changelog
adinauer Dec 1, 2023
1ad36f1
check if queue recently rejected instead of checking if it is current…
adinauer Dec 1, 2023
94b09a2
CR changes; tests; cleanup
adinauer Dec 5, 2023
0e1b15a
Make opt-in; reduce recent reject check to 2s
adinauer Dec 5, 2023
c989dee
add changelog
adinauer Dec 12, 2023
7b22a09
external option; add tests for options
adinauer Dec 12, 2023
51d7297
add backpressure discard reason
adinauer Dec 12, 2023
5b51964
Consider NoOpHub healthy so it does not cause downsampling in case a …
adinauer Dec 12, 2023
8c69f98
remove sysos
adinauer Dec 12, 2023
4987607
delay initial health check so it runs against a real hub
adinauer Dec 12, 2023
ee7cb9f
enable backpressure handling for spring samples
adinauer Dec 12, 2023
637bbbe
Merge branch 'main' into feat/backpressure
adinauer Dec 12, 2023
3194e3f
remove blank line
adinauer Dec 14, 2023
30caf2f
Merge branch 'main' into feat/backpressure
adinauer Dec 14, 2023
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 @@ -210,7 +210,9 @@ class SentrySpringIntegrationTest {

@SpringBootApplication
open class App {
private val transport = mock<ITransport>()
private val transport = mock<ITransport>().also {
whenever(it.isHealthy).thenReturn(true)
}

@Bean
open fun mockTransportFactory(): ITransportFactory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ class SentrySpringIntegrationTest {

@SpringBootApplication
open class App {
private val transport = mock<ITransport>()
private val transport = mock<ITransport>().also {
whenever(it.isHealthy).thenReturn(true)
}

@Bean
open fun mockTransportFactory(): ITransportFactory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import io.sentry.ITransportFactory
import io.sentry.Integration
import io.sentry.Sentry
import io.sentry.SentryOptions
import io.sentry.transport.ITransport
import org.assertj.core.api.Assertions.assertThat
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.springframework.boot.context.annotation.UserConfigurations
import org.springframework.boot.test.context.runner.ApplicationContextRunner
import org.springframework.context.annotation.Bean
Expand Down Expand Up @@ -185,7 +188,9 @@ class EnableSentryTest {
class AppConfigWithCustomTransportFactory {

@Bean
fun transport() = mock<ITransportFactory>()
fun transport() = mock<ITransportFactory>().also {
whenever(it.create(any(), any())).thenReturn(mock<ITransport>())
}
}

@EnableSentry(dsn = "http://key@localhost/proj")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ class SentryWebfluxIntegrationTest {
@SpringBootApplication(exclude = [ReactiveSecurityAutoConfiguration::class, SecurityAutoConfiguration::class])
open class App {

private val transport = mock<ITransport>()
private val transport = mock<ITransport>().also {
whenever(it.isHealthy).thenReturn(true)
}

@Bean
open fun mockTransportFactory(): ITransportFactory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import io.sentry.ITransportFactory
import io.sentry.Integration
import io.sentry.Sentry
import io.sentry.SentryOptions
import io.sentry.transport.ITransport
import org.assertj.core.api.Assertions.assertThat
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.springframework.boot.context.annotation.UserConfigurations
import org.springframework.boot.test.context.runner.ApplicationContextRunner
import org.springframework.context.annotation.Bean
Expand Down Expand Up @@ -185,7 +188,9 @@ class EnableSentryTest {
class AppConfigWithCustomTransportFactory {

@Bean
fun transport() = mock<ITransportFactory>()
fun transport() = mock<ITransportFactory>().also {
whenever(it.create(any(), any())).thenReturn(mock<ITransport>())
}
}

@EnableSentry(dsn = "http://key@localhost/proj")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ class SentryWebfluxIntegrationTest {
@SpringBootApplication(exclude = [ReactiveSecurityAutoConfiguration::class, SecurityAutoConfiguration::class])
open class App {

private val transport = mock<ITransport>()
private val transport = mock<ITransport>().also {
whenever(it.isHealthy).thenReturn(true)
}

@Bean
open fun mockTransportFactory(): ITransportFactory {
Expand Down
9 changes: 7 additions & 2 deletions sentry-test-support/src/main/kotlin/io/sentry/test/Mocks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@
package io.sentry.test

import io.sentry.ISentryExecutorService
import io.sentry.backpressure.IBackpressureMonitor
import org.mockito.kotlin.mock
import java.util.concurrent.Callable
import java.util.concurrent.Future

class ImmediateExecutorService : ISentryExecutorService {
override fun submit(runnable: Runnable): Future<*> {
runnable.run()
if (runnable !is IBackpressureMonitor) {
runnable.run()
}
return mock()
}

override fun <T> submit(callable: Callable<T>): Future<T> = mock()
override fun schedule(runnable: Runnable, delayMillis: Long): Future<*> {
runnable.run()
if (runnable !is IBackpressureMonitor) {
runnable.run()
}
return mock<Future<Runnable>>()
}
override fun close(timeoutMillis: Long) {}
Expand Down
32 changes: 32 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ public final class io/sentry/Hub : io/sentry/IHub {
public fun getTransaction ()Lio/sentry/ITransaction;
public fun isCrashedLastRun ()Ljava/lang/Boolean;
public fun isEnabled ()Z
public fun isHealthy ()Z
public fun popScope ()V
public fun pushScope ()V
public fun removeExtra (Ljava/lang/String;)V
Expand Down Expand Up @@ -485,6 +486,7 @@ public final class io/sentry/HubAdapter : io/sentry/IHub {
public fun getTransaction ()Lio/sentry/ITransaction;
public fun isCrashedLastRun ()Ljava/lang/Boolean;
public fun isEnabled ()Z
public fun isHealthy ()Z
public fun popScope ()V
public fun pushScope ()V
public fun removeExtra (Ljava/lang/String;)V
Expand Down Expand Up @@ -578,6 +580,7 @@ public abstract interface class io/sentry/IHub {
public abstract fun getTransaction ()Lio/sentry/ITransaction;
public abstract fun isCrashedLastRun ()Ljava/lang/Boolean;
public abstract fun isEnabled ()Z
public abstract fun isHealthy ()Z
public abstract fun popScope ()V
public abstract fun pushScope ()V
public abstract fun removeExtra (Ljava/lang/String;)V
Expand Down Expand Up @@ -718,6 +721,7 @@ public abstract interface class io/sentry/ISentryClient {
public abstract fun flush (J)V
public abstract fun getRateLimiter ()Lio/sentry/transport/RateLimiter;
public abstract fun isEnabled ()Z
public fun isHealthy ()Z
}

public abstract interface class io/sentry/ISentryExecutorService {
Expand Down Expand Up @@ -1119,6 +1123,7 @@ public final class io/sentry/NoOpHub : io/sentry/IHub {
public fun getTransaction ()Lio/sentry/ITransaction;
public fun isCrashedLastRun ()Ljava/lang/Boolean;
public fun isEnabled ()Z
public fun isHealthy ()Z
public fun popScope ()V
public fun pushScope ()V
public fun removeExtra (Ljava/lang/String;)V
Expand Down Expand Up @@ -1665,6 +1670,7 @@ public final class io/sentry/Sentry {
public static fun init (Ljava/lang/String;)V
public static fun isCrashedLastRun ()Ljava/lang/Boolean;
public static fun isEnabled ()Z
public static fun isHealthy ()Z
public static fun popScope ()V
public static fun pushScope ()V
public static fun removeExtra (Ljava/lang/String;)V
Expand Down Expand Up @@ -1781,6 +1787,7 @@ public final class io/sentry/SentryClient : io/sentry/ISentryClient {
public fun flush (J)V
public fun getRateLimiter ()Lio/sentry/transport/RateLimiter;
public fun isEnabled ()Z
public fun isHealthy ()Z
}

public final class io/sentry/SentryCrashLastRunState {
Expand Down Expand Up @@ -2078,6 +2085,7 @@ public class io/sentry/SentryOptions {
public fun addOptionsObserver (Lio/sentry/IOptionsObserver;)V
public fun addScopeObserver (Lio/sentry/IScopeObserver;)V
public fun addTracingOrigin (Ljava/lang/String;)V
public fun getBackpressureMonitor ()Lio/sentry/backpressure/IBackpressureMonitor;
public fun getBeforeBreadcrumb ()Lio/sentry/SentryOptions$BeforeBreadcrumbCallback;
public fun getBeforeSend ()Lio/sentry/SentryOptions$BeforeSendCallback;
public fun getBeforeSendTransaction ()Lio/sentry/SentryOptions$BeforeSendTransactionCallback;
Expand Down Expand Up @@ -2156,6 +2164,7 @@ public class io/sentry/SentryOptions {
public fun isAttachThreads ()Z
public fun isDebug ()Z
public fun isEnableAutoSessionTracking ()Z
public fun isEnableBackpressureHandling ()Z
public fun isEnableDeduplication ()Z
public fun isEnableExternalConfiguration ()Z
public fun isEnablePrettySerializationOutput ()Z
Expand All @@ -2177,6 +2186,7 @@ public class io/sentry/SentryOptions {
public fun setAttachServerName (Z)V
public fun setAttachStacktrace (Z)V
public fun setAttachThreads (Z)V
public fun setBackpressureMonitor (Lio/sentry/backpressure/IBackpressureMonitor;)V
public fun setBeforeBreadcrumb (Lio/sentry/SentryOptions$BeforeBreadcrumbCallback;)V
public fun setBeforeSend (Lio/sentry/SentryOptions$BeforeSendCallback;)V
public fun setBeforeSendTransaction (Lio/sentry/SentryOptions$BeforeSendTransactionCallback;)V
Expand All @@ -2191,6 +2201,7 @@ public class io/sentry/SentryOptions {
public fun setDistinctId (Ljava/lang/String;)V
public fun setDsn (Ljava/lang/String;)V
public fun setEnableAutoSessionTracking (Z)V
public fun setEnableBackpressureHandling (Z)V
public fun setEnableDeduplication (Z)V
public fun setEnableExternalConfiguration (Z)V
public fun setEnablePrettySerializationOutput (Z)V
Expand Down Expand Up @@ -2821,6 +2832,24 @@ public final class io/sentry/UserFeedback$JsonKeys {
public fun <init> ()V
}

public final class io/sentry/backpressure/BackpressureMonitor : io/sentry/backpressure/IBackpressureMonitor, java/lang/Runnable {
public fun <init> (Lio/sentry/SentryOptions;Lio/sentry/IHub;)V
public fun getDownsampleFactor ()I
public fun run ()V
public fun start ()V
}

public abstract interface class io/sentry/backpressure/IBackpressureMonitor {
public abstract fun getDownsampleFactor ()I
public abstract fun start ()V
}

public final class io/sentry/backpressure/NoOpBackpressureMonitor : io/sentry/backpressure/IBackpressureMonitor {
public fun getDownsampleFactor ()I
public static fun getInstance ()Lio/sentry/backpressure/NoOpBackpressureMonitor;
public fun start ()V
}

public class io/sentry/cache/EnvelopeCache : io/sentry/cache/IEnvelopeCache {
public static final field CRASH_MARKER_FILE Ljava/lang/String;
public static final field NATIVE_CRASH_MARKER_FILE Ljava/lang/String;
Expand Down Expand Up @@ -4429,6 +4458,7 @@ public final class io/sentry/transport/AsyncHttpTransport : io/sentry/transport/
public fun close ()V
public fun flush (J)V
public fun getRateLimiter ()Lio/sentry/transport/RateLimiter;
public fun isHealthy ()Z
public fun send (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V
}

Expand All @@ -4444,6 +4474,7 @@ public abstract interface class io/sentry/transport/ICurrentDateProvider {
public abstract interface class io/sentry/transport/ITransport : java/io/Closeable {
public abstract fun flush (J)V
public abstract fun getRateLimiter ()Lio/sentry/transport/RateLimiter;
public fun isHealthy ()Z
public fun send (Lio/sentry/SentryEnvelope;)V
public abstract fun send (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V
}
Expand Down Expand Up @@ -4478,6 +4509,7 @@ public final class io/sentry/transport/RateLimiter {
public fun <init> (Lio/sentry/transport/ICurrentDateProvider;Lio/sentry/SentryOptions;)V
public fun filter (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Lio/sentry/SentryEnvelope;
public fun isActiveForCategory (Lio/sentry/DataCategory;)Z
public fun isAnyRateLimitActive ()Z
public fun updateRetryAfterLimits (Ljava/lang/String;Ljava/lang/String;I)V
}

Expand Down
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/Hub.java
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,11 @@ public void bindClient(final @NotNull ISentryClient client) {
}
}

@Override
public boolean isHealthy() {
return stack.peek().getClient().isHealthy();
}

@Override
public void flush(long timeoutMillis) {
if (!isEnabled()) {
Expand Down
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/HubAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ public void bindClient(@NotNull ISentryClient client) {
Sentry.bindClient(client);
}

@Override
public boolean isHealthy() {
return Sentry.isHealthy();
}

@Override
public void flush(long timeoutMillis) {
Sentry.flush(timeoutMillis);
Expand Down
7 changes: 7 additions & 0 deletions sentry/src/main/java/io/sentry/IHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,13 @@ default void addBreadcrumb(@NotNull String message, @NotNull String category) {
*/
void bindClient(@NotNull ISentryClient client);

/**
* Whether the transport is healthy.
*
* @return true if the transport is healthy
*/
boolean isHealthy();

/**
* Flushes events queued up, but keeps the Hub enabled. Not implemented yet.
*
Expand Down
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/ISentryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,9 @@ SentryId captureTransaction(
@ApiStatus.Internal
@Nullable
RateLimiter getRateLimiter();

@ApiStatus.Internal
default boolean isHealthy() {
return true;
}
}
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/NoOpHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ public void configureScope(@NotNull ScopeCallback callback) {}
@Override
public void bindClient(@NotNull ISentryClient client) {}

@Override
public boolean isHealthy() {
return false;
}

@Override
public void flush(long timeoutMillis) {}

Expand Down
10 changes: 10 additions & 0 deletions sentry/src/main/java/io/sentry/Sentry.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.sentry;

import io.sentry.backpressure.BackpressureMonitor;
import io.sentry.cache.EnvelopeCache;
import io.sentry.cache.IEnvelopeCache;
import io.sentry.config.PropertiesProviderFactory;
Expand Down Expand Up @@ -391,6 +392,11 @@ private static boolean initConfigurations(final @NotNull SentryOptions options)
options.addCollector(new JavaMemoryCollector());
}

if (options.isEnableBackpressureHandling()) {
options.setBackpressureMonitor(new BackpressureMonitor(options, HubAdapter.getInstance()));
options.getBackpressureMonitor().start();
}

return true;
}

Expand Down Expand Up @@ -731,6 +737,10 @@ public static void bindClient(final @NotNull ISentryClient client) {
getCurrentHub().bindClient(client);
}

public static boolean isHealthy() {
return getCurrentHub().isHealthy();
}

/**
* Flushes events queued up to the current hub. Not implemented yet.
*
Expand Down
5 changes: 5 additions & 0 deletions sentry/src/main/java/io/sentry/SentryClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,11 @@ public void flush(final long timeoutMillis) {
return transport.getRateLimiter();
}

@Override
public boolean isHealthy() {
return transport.isHealthy();
}

private boolean sample() {
// https://docs.sentry.io/development/sdk-dev/features/#event-sampling
if (options.getSampleRate() != null && random != null) {
Expand Down
Loading
Loading