From bd9deeaaa0e67a5ad45682486c93fad9ebb82a50 Mon Sep 17 00:00:00 2001 From: Jamie Lynch Date: Mon, 9 Dec 2024 14:44:18 +0000 Subject: [PATCH] fix: set internal error logger correctly --- .../internal/logging/EmbLoggerImpl.kt | 5 +- .../embracesdk/internal/logging/EmbLogger.kt | 7 +++ .../features/InternalErrorLogTest.kt | 54 +++++++++++++++++++ .../injection/ModuleInitBootstrapper.kt | 4 +- .../android/embracesdk/fakes/FakeEmbLogger.kt | 4 ++ 5 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/features/InternalErrorLogTest.kt diff --git a/embrace-android-core/src/main/kotlin/io/embrace/android/embracesdk/internal/logging/EmbLoggerImpl.kt b/embrace-android-core/src/main/kotlin/io/embrace/android/embracesdk/internal/logging/EmbLoggerImpl.kt index 011c7fef9c..4d40ddd34e 100644 --- a/embrace-android-core/src/main/kotlin/io/embrace/android/embracesdk/internal/logging/EmbLoggerImpl.kt +++ b/embrace-android-core/src/main/kotlin/io/embrace/android/embracesdk/internal/logging/EmbLoggerImpl.kt @@ -1,6 +1,7 @@ package io.embrace.android.embracesdk.internal.logging import android.util.Log +import io.embrace.android.embracesdk.internal.utils.Provider import java.util.concurrent.atomic.AtomicBoolean internal const val EMBRACE_TAG = "[Embrace]" @@ -12,7 +13,7 @@ internal const val EMBRACE_TAG = "[Embrace]" class EmbLoggerImpl : EmbLogger { private val loggedSdkNotStarted = AtomicBoolean(false) - var errorHandler: InternalErrorHandler? = null + override var errorHandlerProvider: Provider = { null } override fun logInfo(msg: String, throwable: Throwable?) { log(msg, EmbLogger.Severity.INFO, throwable) @@ -31,7 +32,7 @@ class EmbLoggerImpl : EmbLogger { override fun trackInternalError(type: InternalErrorType, throwable: Throwable) { try { - errorHandler?.trackInternalError(type, throwable) + errorHandlerProvider()?.trackInternalError(type, throwable) } catch (exc: Throwable) { // don't cause a crash loop! Log.w(EMBRACE_TAG, "Failed to track internal error", exc) diff --git a/embrace-android-infra/src/main/kotlin/io/embrace/android/embracesdk/internal/logging/EmbLogger.kt b/embrace-android-infra/src/main/kotlin/io/embrace/android/embracesdk/internal/logging/EmbLogger.kt index 95ffe5180d..61828a0bde 100644 --- a/embrace-android-infra/src/main/kotlin/io/embrace/android/embracesdk/internal/logging/EmbLogger.kt +++ b/embrace-android-infra/src/main/kotlin/io/embrace/android/embracesdk/internal/logging/EmbLogger.kt @@ -1,5 +1,7 @@ package io.embrace.android.embracesdk.internal.logging +import io.embrace.android.embracesdk.internal.utils.Provider + /** * A simple interface that is used within the Embrace SDK for logging. */ @@ -9,6 +11,11 @@ interface EmbLogger : InternalErrorHandler { DEBUG, INFO, WARNING, ERROR } + /** + * The implementation of the internal error handler. This is set after the logger is initialized. + */ + var errorHandlerProvider: Provider + /** * Logs an informational message. */ diff --git a/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/features/InternalErrorLogTest.kt b/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/features/InternalErrorLogTest.kt new file mode 100644 index 0000000000..8be7caee4e --- /dev/null +++ b/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/features/InternalErrorLogTest.kt @@ -0,0 +1,54 @@ +package io.embrace.android.embracesdk.testcases.features + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.embrace.android.embracesdk.fakes.FakeEmbLogger +import io.embrace.android.embracesdk.internal.spans.findAttributeValue +import io.embrace.android.embracesdk.testframework.IntegrationTestRule +import io.embrace.android.embracesdk.testframework.assertions.getLastLog +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +internal class InternalErrorLogTest { + + @Rule + @JvmField + val testRule: IntegrationTestRule = IntegrationTestRule() + + @Test + fun `internal error log delivered`() { + testRule.runTest( + setupAction = { + (overriddenInitModule.logger as FakeEmbLogger).throwOnInternalError = false + }, + testCaseAction = { + recordSession { + embrace.impl.internalInterface.logInternalError("Some error message", null) + } + }, + assertAction = { + with(getSingleLogEnvelope().getLastLog()) { + assertEquals("ERROR", severityText) + assertEquals("", body) + + val attrs = checkNotNull(attributes) + assertEquals("sys.internal", attrs.findAttributeValue("emb.type")) + assertEquals( + "Some error message", + attrs.findAttributeValue("exception.message") + ) + assertEquals( + "java.lang.RuntimeException", + attrs.findAttributeValue("exception.type") + ) + assertNotNull(attrs.findAttributeValue("log.record.uid")) + assertNotNull(attrs.findAttributeValue("session.id")) + checkNotNull(attrs.findAttributeValue("exception.stacktrace")) + } + } + ) + } +} diff --git a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/injection/ModuleInitBootstrapper.kt b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/injection/ModuleInitBootstrapper.kt index ad81e4d876..fbe8169b7f 100644 --- a/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/injection/ModuleInitBootstrapper.kt +++ b/embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/injection/ModuleInitBootstrapper.kt @@ -246,9 +246,7 @@ internal class ModuleInitBootstrapper( } postInit(FeatureModule::class) { featureModule.registerFeatures() - (initModule.logger as? EmbLoggerImpl)?.let { - it.errorHandler = featureModule.internalErrorDataSource.dataSource - } + initModule.logger.errorHandlerProvider = { featureModule.internalErrorDataSource.dataSource } } dataCaptureServiceModule = init(DataCaptureServiceModule::class) { diff --git a/embrace-test-fakes/src/main/kotlin/io/embrace/android/embracesdk/fakes/FakeEmbLogger.kt b/embrace-test-fakes/src/main/kotlin/io/embrace/android/embracesdk/fakes/FakeEmbLogger.kt index ae412cd7e9..97f0085903 100644 --- a/embrace-test-fakes/src/main/kotlin/io/embrace/android/embracesdk/fakes/FakeEmbLogger.kt +++ b/embrace-test-fakes/src/main/kotlin/io/embrace/android/embracesdk/fakes/FakeEmbLogger.kt @@ -1,10 +1,13 @@ package io.embrace.android.embracesdk.fakes import io.embrace.android.embracesdk.internal.logging.EmbLogger +import io.embrace.android.embracesdk.internal.logging.InternalErrorHandler import io.embrace.android.embracesdk.internal.logging.InternalErrorType +import io.embrace.android.embracesdk.internal.utils.Provider class FakeEmbLogger( var throwOnInternalError: Boolean = true, + override var errorHandlerProvider: Provider = { null }, ) : EmbLogger { data class LogMessage( @@ -37,5 +40,6 @@ class FakeEmbLogger( throw IllegalStateException("Internal error: $type", throwable) } internalErrorMessages.add(LogMessage(type.toString(), throwable)) + errorHandlerProvider()?.trackInternalError(type, throwable) } }