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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- Add an explicit Logs opt-in to the Android Logcat integration ([#5945](https://github.com/getsentry/sentry-java/pull/5945))
- Add an explicit Logs opt-in to the Android Timber integration ([#5943](https://github.com/getsentry/sentry-java/pull/5943))
- Add an explicit Logs opt-in to the JUL handler ([#5942](https://github.com/getsentry/sentry-java/pull/5942))
- Add an explicit Logs opt-in to the Log4j2 appender ([#5941](https://github.com/getsentry/sentry-java/pull/5941))
Expand Down
2 changes: 2 additions & 0 deletions sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
public fun isEnableAutoActivityLifecycleTracing ()Z
public fun isEnableAutoTraceIdGeneration ()Z
public fun isEnableFramesTracking ()Z
public fun isEnableLogcatLogs ()Z
public fun isEnableNdk ()Z
public fun isEnableNdkAppHangTracking ()Z
public fun isEnableNetworkEventBreadcrumbs ()Z
Expand Down Expand Up @@ -464,6 +465,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
public fun setEnableAutoActivityLifecycleTracing (Z)V
public fun setEnableAutoTraceIdGeneration (Z)V
public fun setEnableFramesTracking (Z)V
public fun setEnableLogcatLogs (Z)V
public fun setEnableNdk (Z)V
public fun setEnableNdkAppHangTracking (Z)V
public fun setEnableNetworkEventBreadcrumbs (Z)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ final class ManifestMetadataReader {

static final String ENABLE_TIMBER_LOGS = "io.sentry.timber.logs.enabled";

static final String ENABLE_LOGCAT_LOGS = "io.sentry.logcat.logs.enabled";

static final String ENABLE_METRICS = "io.sentry.metrics.enabled";

static final String ENABLE_AUTO_TRACE_ID_GENERATION =
Expand Down Expand Up @@ -711,6 +713,9 @@ static void applyMetadata(
options.setEnableTimberLogs(
readBool(metadata, logger, ENABLE_TIMBER_LOGS, options.isEnableTimberLogs()));

options.setEnableLogcatLogs(
readBool(metadata, logger, ENABLE_LOGCAT_LOGS, options.isEnableLogcatLogs()));

options
.getMetrics()
.setEnabled(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ public final class SentryAndroidOptions extends SentryOptions {
/** Enable or disable automatic Sentry Logs capture from Timber. Default is disabled. */
private boolean enableTimberLogs = false;

/** Enable or disable automatic Sentry Logs capture from Logcat. Default is disabled. */
private boolean enableLogcatLogs = false;

/**
* Enables the Auto instrumentation for Activity lifecycle tracing.
*
Expand Down Expand Up @@ -468,6 +471,14 @@ public void setEnableTimberLogs(boolean enableTimberLogs) {
this.enableTimberLogs = enableTimberLogs;
}

public boolean isEnableLogcatLogs() {
return enableLogcatLogs;
}

public void setEnableLogcatLogs(boolean enableLogcatLogs) {
this.enableLogcatLogs = enableLogcatLogs;
}

/**
* Enable or disable all the automatic breadcrumbs
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.sentry.Sentry;
import io.sentry.SentryLevel;
import io.sentry.SentryLogLevel;
import io.sentry.SentryOptions;
import io.sentry.logger.SentryLogParameters;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -52,8 +53,10 @@ private static void addAsLog(
@Nullable final String msg,
@Nullable final Throwable tr) {
final @NotNull ScopesAdapter scopes = ScopesAdapter.getInstance();
// Check if logs are enabled before doing expensive operations
if (!scopes.getOptions().getLogs().isEnabled()) {
final @NotNull SentryOptions options = scopes.getOptions();
if (!(options instanceof SentryAndroidOptions)
|| !((SentryAndroidOptions) options).isEnableLogcatLogs()
|| !options.getLogs().isEnabled()) {
return;
}
final @Nullable String trMessage = tr != null ? tr.getMessage() : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import io.sentry.FilterString
import io.sentry.ILogger
import io.sentry.ProfileLifecycle
Expand Down Expand Up @@ -1986,6 +1987,36 @@ class ManifestMetadataReaderTest {
assertTrue(fixture.options.isEnableTimberLogs)
}

@Test
fun `applyMetadata keeps Logcat logs disabled if not found`() {
val context = fixture.getContext()

ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider)

assertThat(fixture.options.isEnableLogcatLogs).isFalse()
}

@Test
fun `applyMetadata reads Logcat logs enabled to options`() {
val bundle = bundleOf(ManifestMetadataReader.ENABLE_LOGCAT_LOGS to true)
val context = fixture.getContext(metaData = bundle)

ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider)

assertThat(fixture.options.isEnableLogcatLogs).isTrue()
}

@Test
fun `applyMetadata reads Logcat logs disabled to options`() {
fixture.options.isEnableLogcatLogs = true
val bundle = bundleOf(ManifestMetadataReader.ENABLE_LOGCAT_LOGS to false)
val context = fixture.getContext(metaData = bundle)

ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider)

assertThat(fixture.options.isEnableLogcatLogs).isFalse()
}

@Test
fun `applyMetadata reads metrics enabled and keep default value if not found`() {
// Arrange
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.sentry.android.core

import com.google.common.truth.Truth.assertThat
import io.sentry.ITransactionProfiler
import io.sentry.NoOpTransactionProfiler
import io.sentry.protocol.DebugImage
Expand Down Expand Up @@ -108,6 +109,19 @@ class SentryAndroidOptionsTest {
assertTrue(sentryOptions.isEnableTimberLogs)
}

@Test
fun `Logcat logs are disabled by default`() {
assertThat(SentryAndroidOptions().isEnableLogcatLogs).isFalse()
}

@Test
fun `Logcat logs can be enabled`() {
val sentryOptions = SentryAndroidOptions()
sentryOptions.isEnableLogcatLogs = true

assertThat(sentryOptions.isEnableLogcatLogs).isTrue()
}

@Test
fun `attach screenshots disabled by default for Android`() {
val sentryOptions = SentryAndroidOptions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.sentry.android.core

import android.os.Bundle
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import io.sentry.Breadcrumb
import io.sentry.Sentry
import io.sentry.SentryLevel
Expand All @@ -15,6 +16,7 @@ import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import org.junit.runner.RunWith
import org.robolectric.shadows.ShadowLog

@RunWith(AndroidJUnit4::class)
class SentryLogcatAdapterTest {
Expand All @@ -26,16 +28,22 @@ class SentryLogcatAdapterTest {
val breadcrumbs = mutableListOf<Breadcrumb>()
val logs = mutableListOf<SentryLogEvent>()

fun initSut(options: Sentry.OptionsConfiguration<SentryAndroidOptions>? = null) {
val metadata =
Bundle().apply { putString(ManifestMetadataReader.DSN, "https://key@sentry.io/123") }
fun initSut(
enableLogcatLogs: Boolean? = true,
metadata: Bundle = Bundle(),
options: Sentry.OptionsConfiguration<SentryAndroidOptions>? = null,
) {
metadata.putString(ManifestMetadataReader.DSN, "https://key@sentry.io/123")
val mockContext = ContextUtilsTestHelper.mockMetaData(metaData = metadata)
initForTest(mockContext) {
it.beforeBreadcrumb = SentryOptions.BeforeBreadcrumbCallback { breadcrumb, _ ->
breadcrumbs.add(breadcrumb)
breadcrumb
}
it.logs.isEnabled = true
if (enableLogcatLogs != null) {
it.isEnableLogcatLogs = enableLogcatLogs
}
it.logs.beforeSend =
SentryOptions.Logs.BeforeSendLogCallback { logEvent ->
logs.add(logEvent)
Expand All @@ -55,6 +63,37 @@ class SentryLogcatAdapterTest {
Sentry.close()
fixture.breadcrumbs.clear()
fixture.logs.clear()
ShadowLog.clear()
}

@Test
fun `Logcat logs are disabled by default while breadcrumbs and Android Log remain enabled`() {
fixture.initSut(enableLogcatLogs = null)

SentryLogcatAdapter.d(tag, commonMsg)

assertThat(fixture.logs).isEmpty()
assertThat(fixture.breadcrumbs).hasSize(1)
assertThat(ShadowLog.getLogs().any { it.tag == tag && it.msg == commonMsg }).isTrue()
}

@Test
fun `Logcat logs can be enabled through Android options`() {
fixture.initSut(enableLogcatLogs = true)

SentryLogcatAdapter.d(tag, commonMsg)

assertThat(fixture.logs).hasSize(1)
}

@Test
fun `Logcat logs can be enabled through manifest metadata`() {
val metadata = Bundle().apply { putBoolean(ManifestMetadataReader.ENABLE_LOGCAT_LOGS, true) }
fixture.initSut(enableLogcatLogs = null, metadata = metadata)

SentryLogcatAdapter.d(tag, commonMsg)

assertThat(fixture.logs).hasSize(1)
}

@Test
Expand Down
Loading