Skip to content
Open
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
### Features

- Add `Session.State.Unhandled` for unhandled errors that do not terminate the process ([#5919](https://github.com/getsentry/sentry-java/pull/5919))
- Added `Environment` to the `Scope`, allowing you to overwrite the `Environment` set on the options ([#5772](https://github.com/getsentry/sentry-java/pull/5772))
- The scope `Environment` is also applied to the trace envelope header (DSC), logs, metrics and profiles, so all telemetry of a trace reports the same environment

### Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ private void backfillScope(
setRequest(event);
setUser(event);
setScopeTags(event);
setScopeEnvironment(event);
setBreadcrumbs(event);
setExtras(event);
setContexts(event);
Comment thread
bitsandfoxes marked this conversation as resolved.
Expand Down Expand Up @@ -490,6 +491,16 @@ private void setEnvironment(
}
}

private void setScopeEnvironment(final @NotNull SentryBaseEvent event) {
if (event.getEnvironment() == null) {
final @Nullable String scopeEnvironment =
readFromDisk(options, PersistingScopeObserver.ENVIRONMENT_FILENAME, String.class);
if (scopeEnvironment != null) {
event.setEnvironment(scopeEnvironment);
}
}
}

private void setDebugMeta(
final @NotNull SentryBaseEvent event, final @NotNull OptionsSource optionsSource) {
DebugMeta debugMeta = event.getDebugMeta();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,18 @@ class ApplicationExitInfoEventProcessorTest {
assertEquals("release", processed.environment)
}

@Test
fun `if scope environment is persisted, it takes precedence over the options environment`() {
val hint = HintUtils.createWithTypeCheckHint(BackfillableHint())

val processor = fixture.getSut(tmpDir, populateOptionsCache = true)
fixture.persistScope(PersistingScopeObserver.ENVIRONMENT_FILENAME, "staging")

val processed = processor.process(SentryEvent(), hint)

assertEquals("staging", processed!!.environment)
}

@Test
fun `if release is not persisted and app was not updated, uses release from options`() {
val hint = HintUtils.createWithTypeCheckHint(AbnormalExitHint(timestamp = 2_000))
Expand Down Expand Up @@ -500,6 +512,7 @@ class ApplicationExitInfoEventProcessorTest {
fixture.options.release = "io.sentry.samples@1.2.0+232"
fixture.options.environment = "production"
fixture.options.dist = "custom-dist"
fixture.persistScope(PersistingScopeObserver.ENVIRONMENT_FILENAME, "staging")
setLastUpdateTime(1_000)

val processed = processor.process(SentryEvent(), hint)!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import io.sentry.IScopes
import io.sentry.PropagationContext
import io.sentry.Scope.IWithPropagationContext
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryLevel.INFO
import io.sentry.android.core.SentryAndroidOptions
import io.sentry.util.LazyEvaluator
Expand Down Expand Up @@ -85,6 +86,9 @@ class SentryGestureListenerClickTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(anyOrNull<ScopeType>(), any())
doAnswer {
(it.arguments[0] as IWithPropagationContext).accept(propagationContext)
propagationContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import io.sentry.IScopes
import io.sentry.PropagationContext
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryLevel
import io.sentry.SentryLevel.INFO
import io.sentry.android.core.SentryAndroidOptions
Expand Down Expand Up @@ -82,6 +83,9 @@ class SentryGestureListenerScrollTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(anyOrNull<ScopeType>(), any())
doAnswer {
(it.arguments[0] as Scope.IWithPropagationContext).accept(propagationContext)
propagationContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import io.sentry.IScope
import io.sentry.IScopes
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryTracer
import io.sentry.SpanContext
import io.sentry.SpanId
Expand All @@ -31,6 +32,7 @@ import kotlin.test.assertNotNull
import kotlin.test.assertNull
import org.mockito.ArgumentCaptor
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.check
import org.mockito.kotlin.clearInvocations
import org.mockito.kotlin.doAnswer
Expand Down Expand Up @@ -94,6 +96,9 @@ class SentryGestureListenerTracingTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(anyOrNull<ScopeType>(), any())

return SentryGestureListener(activity, scopes, options)
}
Expand Down
1 change: 1 addition & 0 deletions sentry-android-ndk/api/sentry-android-ndk.api
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public final class io/sentry/android/ndk/NdkScopeObserver : io/sentry/ScopeObser
public fun clearAttachments ()V
public fun removeExtra (Ljava/lang/String;)V
public fun removeTag (Ljava/lang/String;)V
public fun setEnvironment (Ljava/lang/String;)V
public fun setExtra (Ljava/lang/String;Ljava/lang/String;)V
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTrace (Lio/sentry/SpanContext;Lio/sentry/IScope;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ public void setUser(final @Nullable User user) {
}
}

@Override
public void setEnvironment(@Nullable String environment) {
try {
options.getExecutorService().submit(() -> nativeScope.setEnvironment(environment));
} catch (Throwable e) {
options.getLogger().log(SentryLevel.ERROR, e, "Scope sync setEnvironment has an error.");
}
}

@Override
public void addBreadcrumb(final @NotNull Breadcrumb crumb) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,15 @@ class NdkScopeObserverTest {

verify(fixture.nativeScope).clearAttachments()
}

@Test
fun `set environments forwards call to native scope`() {
val sut = fixture.getSut()

sut.setEnvironment(null)
verify(fixture.nativeScope).setEnvironment(eq(null))

sut.setEnvironment("production")
verify(fixture.nativeScope).setEnvironment(eq("production"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import io.sentry.IScopes
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryOptions
import io.sentry.SentryReplayEvent.ReplayType
import io.sentry.android.replay.util.ReplayShadowMediaCodec
Expand Down Expand Up @@ -72,6 +73,9 @@ class ReplaySmokeTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(anyOrNull<ScopeType>(), any())

on { rateLimiter }.doReturn(rateLimiter)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.sentry.DataCategory
import io.sentry.IScopes
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryEnvelope
import io.sentry.SentryEnvelopeHeader
import io.sentry.SentryOptions
Expand Down Expand Up @@ -66,6 +67,9 @@ class BufferCaptureStrategyTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(anyOrNull<ScopeType>(), any())
}
var persistedSegment = LinkedHashMap<String, String?>()
val replayCache =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import io.sentry.DateUtils
import io.sentry.IScopes
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryOptions
import io.sentry.SentryReplayEvent
import io.sentry.SentryReplayEvent.ReplayType
Expand Down Expand Up @@ -76,6 +77,9 @@ class SessionCaptureStrategyTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(anyOrNull<ScopeType>(), any())
}
var persistedSegment = LinkedHashMap<String, String?>()
val replayCache =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import io.sentry.IScopes
import io.sentry.ITransaction
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryOptions
import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS
import io.sentry.SentryTraceHeader
Expand Down Expand Up @@ -65,6 +66,9 @@ class SentryApollo3InterceptorTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(anyOrNull<ScopeType>(), any())
}
private var httpInterceptor =
SentryApollo3HttpInterceptor(scopes, captureFailedRequests = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import io.sentry.IScopes
import io.sentry.ITransaction
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryOptions
import io.sentry.SentryOptions.DEFAULT_PROPAGATION_TARGETS
import io.sentry.SentryTraceHeader
Expand Down Expand Up @@ -79,6 +80,9 @@ abstract class SentryApollo4HttpInterceptorTest(
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(anyOrNull<ScopeType>(), any())
}
private var httpInterceptor =
SentryApollo4HttpInterceptor(scopes, captureFailedRequests = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.sentry.IScopes
import io.sentry.ITransaction
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryOptions
import io.sentry.SentryTraceHeader
import io.sentry.SentryTracer
Expand Down Expand Up @@ -56,6 +57,9 @@ class SentryApolloInterceptorTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(it)
.configureScope(anyOrNull<ScopeType>(), any())
}
private var interceptor = SentryApolloInterceptor(scopes)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import io.sentry.IScope
import io.sentry.IScopes
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryOptions
import io.sentry.exception.ExceptionMechanismException
import io.sentry.protocol.Request
Expand All @@ -26,6 +27,7 @@ import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertSame
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
Expand Down Expand Up @@ -89,6 +91,9 @@ class ExceptionReporterTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(anyOrNull<ScopeType>(), any())

return exceptionReporter
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import io.sentry.ISpan
import io.sentry.NoOpSpan
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.Sentry
import io.sentry.SentryOptions
import io.sentry.SentryTraceHeader
Expand All @@ -33,6 +34,7 @@ import org.apache.kafka.common.TopicPartition
import org.apache.kafka.common.header.Header
import org.apache.kafka.common.header.Headers
import org.mockito.kotlin.any
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.eq
Expand Down Expand Up @@ -64,6 +66,9 @@ class SentryKafkaProducerTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(Scope(options)) }
.whenever(scopes)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(Scope(options)) }
.whenever(scopes)
.configureScope(anyOrNull<ScopeType>(), any())
delegate = mock()
whenever(delegate.send(any(), any())).thenReturn(CompletableFuture.completedFuture(null))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import io.sentry.IScope
import io.sentry.IScopes
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.Sentry
import io.sentry.SentryEvent
import io.sentry.SentryOptions
Expand Down Expand Up @@ -90,6 +91,9 @@ class SentryKtorClientPluginTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(anyOrNull<ScopeType>(), any())

sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.sentry.IScope
import io.sentry.IScopes
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.Sentry
import io.sentry.SentryOptions
import io.sentry.SentryTraceHeader
Expand Down Expand Up @@ -96,6 +97,9 @@ class SentryOkHttpInterceptorTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(anyOrNull<ScopeType>(), any())

sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.sentry.Breadcrumb
import io.sentry.IScopes
import io.sentry.Scope
import io.sentry.ScopeCallback
import io.sentry.ScopeType
import io.sentry.SentryOptions
import io.sentry.SentryTraceHeader
import io.sentry.SentryTracer
Expand Down Expand Up @@ -50,6 +51,9 @@ class SentryFeignClientTest {
doAnswer { (it.arguments[0] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(any())
doAnswer { (it.arguments[1] as ScopeCallback).run(scope) }
.whenever(scopes)
.configureScope(anyOrNull<ScopeType>(), any())
sentryTracer = SentryTracer(TransactionContext("name", "op"), scopes)
}

Expand Down
Loading
Loading