Skip to content

Commit 7cd057f

Browse files
authored
Merge pull request #5964 from getsentry/fix/timber-lazy-logs-option
fix(android): [Logs and Metrics Enable Flags 13] Read Timber option lazily
2 parents 16b4e67 + c05ab4a commit 7cd057f

5 files changed

Lines changed: 76 additions & 7 deletions

File tree

‎sentry-android-core/build.gradle.kts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ dependencies {
126126
testImplementation(projects.sentrySpotlight)
127127
testImplementation(projects.sentryAndroidFragment)
128128
testImplementation(projects.sentryAndroidTimber)
129+
testImplementation(libs.timber)
129130
testImplementation(projects.sentryAndroidReplay)
130131
testImplementation(projects.sentryCompose)
131132
testImplementation(projects.sentryAndroidNdk)
@@ -136,5 +137,4 @@ dependencies {
136137
testImplementation(libs.androidx.compose.foundation.layout)
137138
testImplementation(libs.androidx.compose.material3)
138139
testRuntimeOnly(libs.androidx.fragment.ktx)
139-
testRuntimeOnly(libs.timber)
140140
}

‎sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ static void installDefaultIntegrations(
479479
}
480480

481481
if (isTimberAvailable) {
482-
options.addIntegration(new SentryTimberIntegration(options.isEnableTimberLogs()));
482+
options.addIntegration(new SentryTimberIntegration(() -> options.isEnableTimberLogs()));
483483
}
484484
options.addIntegration(new AppComponentsBreadcrumbsIntegration(context));
485485
options.addIntegration(new SystemEventsBreadcrumbsIntegration(context));

‎sentry-android-core/src/test/java/io/sentry/android/core/SentryAndroidTest.kt‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import io.sentry.SentryEnvelope
2323
import io.sentry.SentryLevel
2424
import io.sentry.SentryLevel.DEBUG
2525
import io.sentry.SentryLevel.FATAL
26+
import io.sentry.SentryLogEvent
2627
import io.sentry.SentryOptions
2728
import io.sentry.SentryOptions.BeforeSendCallback
2829
import io.sentry.Session
@@ -84,6 +85,7 @@ import org.robolectric.annotation.Config
8485
import org.robolectric.shadow.api.Shadow
8586
import org.robolectric.shadows.ShadowActivityManager
8687
import org.robolectric.shadows.ShadowActivityManager.ApplicationExitInfoBuilder
88+
import timber.log.Timber
8789

8890
@RunWith(AndroidJUnit4::class)
8991
@Config(sdk = [Build.VERSION_CODES.N], shadows = [SentryShadowProcess::class])
@@ -238,6 +240,46 @@ class SentryAndroidTest {
238240
assertNotEquals(0, AppStartMetrics.getInstance().appStartTimeSpan.durationMs)
239241
}
240242

243+
@Test
244+
fun `auto-installed Timber integration uses Logs option set in configuration callback`() {
245+
val logs = mutableListOf<SentryLogEvent>()
246+
fixture.initSut { options ->
247+
options.isEnableTimberLogs = true
248+
options.logs.beforeSend =
249+
SentryOptions.Logs.BeforeSendLogCallback { log ->
250+
logs.add(log)
251+
log
252+
}
253+
}
254+
255+
Timber.i("message")
256+
257+
assertEquals(1, logs.size)
258+
}
259+
260+
@Test
261+
fun `auto-installed Timber integration uses configuration callback override of manifest option`() {
262+
val metadata =
263+
Bundle().apply {
264+
putString(ManifestMetadataReader.DSN, "https://key@sentry.io/123")
265+
putBoolean(ManifestMetadataReader.ENABLE_TIMBER_LOGS, true)
266+
}
267+
val mockContext = ContextUtilsTestHelper.mockMetaData(metaData = metadata)
268+
val logs = mutableListOf<SentryLogEvent>()
269+
270+
initForTest(mockContext) { options ->
271+
options.isEnableTimberLogs = false
272+
options.logs.beforeSend =
273+
SentryOptions.Logs.BeforeSendLogCallback { log ->
274+
logs.add(log)
275+
log
276+
}
277+
}
278+
Timber.i("message")
279+
280+
assertTrue(logs.isEmpty())
281+
}
282+
241283
@Test
242284
fun `deduplicates fragment, timber and system events integrations`() {
243285
var refOptions: SentryAndroidOptions? = null

‎sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberIntegration.kt‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import io.sentry.SentryLogLevel
99
import io.sentry.SentryOptions
1010
import io.sentry.android.timber.BuildConfig.VERSION_NAME
1111
import io.sentry.util.IntegrationUtils.addIntegrationToSdkVersion
12+
import io.sentry.util.LazyEvaluator.Evaluator
1213
import java.io.Closeable
1314
import timber.log.Timber
1415

@@ -18,11 +19,13 @@ public class SentryTimberIntegration(
1819
public val minBreadcrumbLevel: SentryLevel = SentryLevel.INFO,
1920
public val minLogsLevel: SentryLogLevel = SentryLogLevel.INFO,
2021
) : Integration, Closeable {
21-
public var enableLogs: Boolean = false
22-
private set
22+
public val enableLogs: Boolean
23+
get() = enableLogsProvider.evaluate()
24+
25+
private var enableLogsProvider: Evaluator<Boolean> = Evaluator { false }
2326

2427
public constructor(enableLogs: Boolean) : this() {
25-
this.enableLogs = enableLogs
28+
enableLogsProvider = Evaluator { enableLogs }
2629
}
2730

2831
public constructor(
@@ -31,7 +34,11 @@ public class SentryTimberIntegration(
3134
minLogsLevel: SentryLogLevel,
3235
enableLogs: Boolean,
3336
) : this(minEventLevel, minBreadcrumbLevel, minLogsLevel) {
34-
this.enableLogs = enableLogs
37+
enableLogsProvider = Evaluator { enableLogs }
38+
}
39+
40+
internal constructor(enableLogsProvider: Evaluator<Boolean>) : this() {
41+
this.enableLogsProvider = enableLogsProvider
3542
}
3643

3744
private lateinit var tree: SentryTimberTree
@@ -47,7 +54,14 @@ public class SentryTimberIntegration(
4754
override fun register(scopes: IScopes, options: SentryOptions) {
4855
logger = options.logger
4956

50-
tree = SentryTimberTree(scopes, minEventLevel, minBreadcrumbLevel, minLogsLevel, enableLogs)
57+
tree =
58+
SentryTimberTree(
59+
scopes,
60+
minEventLevel,
61+
minBreadcrumbLevel,
62+
minLogsLevel,
63+
enableLogsProvider.evaluate(),
64+
)
5165
Timber.plant(tree)
5266

5367
logger.log(SentryLevel.DEBUG, "SentryTimberIntegration installed.")

‎sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberIntegrationTest.kt‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import io.sentry.logger.ILoggerApi
1212
import io.sentry.logger.SentryLogParameters
1313
import io.sentry.protocol.SdkVersion
1414
import io.sentry.transport.ITransport
15+
import io.sentry.util.LazyEvaluator.Evaluator
1516
import kotlin.test.BeforeTest
1617
import kotlin.test.Test
1718
import kotlin.test.assertEquals
@@ -108,6 +109,18 @@ class SentryTimberIntegrationTest {
108109
verify(fixture.logs).log(any(), any<SentryLogParameters>(), any<String>())
109110
}
110111

112+
@Test
113+
fun `Integration evaluates Logs provider when registered`() {
114+
var enableLogs = false
115+
val sut = SentryTimberIntegration(Evaluator { enableLogs })
116+
enableLogs = true
117+
118+
sut.register(fixture.scopes, fixture.options)
119+
Timber.i("message")
120+
121+
verify(fixture.logs).log(any(), any<SentryLogParameters>(), any<String>())
122+
}
123+
111124
@Test
112125
fun `Integrations removes a tree from Timber on close integration`() {
113126
val sut = fixture.getSut()

0 commit comments

Comments
 (0)