From 7fa844520154fa53470e229f42823eed691b134d Mon Sep 17 00:00:00 2001 From: Marius Constantin Date: Wed, 16 Oct 2024 17:53:32 +0200 Subject: [PATCH] Fix the regression for the TelemetryErrorEvent with throwable --- dd-sdk-android-core/api/apiSurface | 1 - .../api/dd-sdk-android-core.api | 4 - .../kotlin/com/datadog/android/Datadog.kt | 2 +- .../error/internal/DatadogExceptionHandler.kt | 1 + .../kotlin/com/datadog/android/DatadogTest.kt | 1 + .../internal/DatadogExceptionHandlerTest.kt | 1 + dd-sdk-android-internal/api/apiSurface | 3 + .../api/dd-sdk-android-internal.api | 6 + dd-sdk-android-internal/build.gradle.kts | 8 + .../telemetry/InternalTelemetryEvent.kt | 12 +- .../android}/internal/utils/ThrowableExt.kt | 4 +- .../datadog/internal/forge/Configurator.kt | 19 ++ .../InternalTelemetryErrorEventTest.kt | 198 +++++++++++++ .../internal/utils/ThrowableExtTest.kt | 5 +- .../rum/internal/anr/ANRDetectorRunnable.kt | 1 + .../internal/domain/scope/RumResourceScope.kt | 1 + .../rum/internal/domain/scope/RumViewScope.kt | 1 + .../internal/TelemetryEventHandler.kt | 4 +- .../telemetry/internal/TelemetryEventId.kt | 2 +- .../internal/anr/ANRDetectorRunnableTest.kt | 1 + .../domain/scope/RumResourceScopeTest.kt | 1 + .../internal/domain/scope/RumViewScopeTest.kt | 1 + .../utils/forge/ErrorEventForgeryFactory.kt | 1 + .../TelemetryErrorEventForgeryFactory.kt | 1 + .../internal/TelemetryEventHandlerTest.kt | 264 +++++++++++++++++- .../handlers/AndroidSpanLogsHandler.kt | 1 + .../handlers/AndroidSpanLogsHandlerTest.kt | 1 + .../utils/forge/ErrorEventForgeryFactory.kt | 1 + .../okhttp/trace/TracingInterceptor.kt | 1 + ...gInterceptorContextInjectionSampledTest.kt | 1 + ...nterceptorNonDdTracerNotSendingSpanTest.kt | 1 + .../TracingInterceptorNonDdTracerTest.kt | 1 + .../TracingInterceptorNotSendingSpanTest.kt | 1 + .../okhttp/trace/TracingInterceptorTest.kt | 1 + reliability/single-fit/rum/build.gradle.kts | 1 + .../tests/elmyr/ErrorEventForgeryFactory.kt | 1 + 36 files changed, 532 insertions(+), 22 deletions(-) rename {dd-sdk-android-core/src/main/kotlin/com/datadog/android/core => dd-sdk-android-internal/src/main/java/com/datadog/android}/internal/utils/ThrowableExt.kt (85%) create mode 100644 dd-sdk-android-internal/src/test/java/com/datadog/internal/forge/Configurator.kt create mode 100644 dd-sdk-android-internal/src/test/java/com/datadog/internal/telemetry/InternalTelemetryErrorEventTest.kt rename {dd-sdk-android-core/src/test/kotlin/com/datadog/android/core => dd-sdk-android-internal/src/test/java/com/datadog}/internal/utils/ThrowableExtTest.kt (95%) diff --git a/dd-sdk-android-core/api/apiSurface b/dd-sdk-android-core/api/apiSurface index 8ad9b71ea8..0647cc4ae0 100644 --- a/dd-sdk-android-core/api/apiSurface +++ b/dd-sdk-android-core/api/apiSurface @@ -290,7 +290,6 @@ fun Long.toHexString(): String fun java.math.BigInteger.toHexString(): String fun Thread.State.asString(): String fun Array.loggableStackTrace(): String -fun Throwable.loggableStackTrace(): String enum com.datadog.android.core.metrics.MethodCallSamplingRate constructor(Float) - ALL diff --git a/dd-sdk-android-core/api/dd-sdk-android-core.api b/dd-sdk-android-core/api/dd-sdk-android-core.api index c4f3172efc..e0191e8d44 100644 --- a/dd-sdk-android-core/api/dd-sdk-android-core.api +++ b/dd-sdk-android-core/api/dd-sdk-android-core.api @@ -783,10 +783,6 @@ public final class com/datadog/android/core/internal/utils/ThreadExtKt { public static final fun loggableStackTrace ([Ljava/lang/StackTraceElement;)Ljava/lang/String; } -public final class com/datadog/android/core/internal/utils/ThrowableExtKt { - public static final fun loggableStackTrace (Ljava/lang/Throwable;)Ljava/lang/String; -} - public final class com/datadog/android/core/metrics/MethodCallSamplingRate : java/lang/Enum { public static final field ALL Lcom/datadog/android/core/metrics/MethodCallSamplingRate; public static final field HIGH Lcom/datadog/android/core/metrics/MethodCallSamplingRate; diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/Datadog.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/Datadog.kt index 5dd6637bbf..31218e70cb 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/Datadog.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/Datadog.kt @@ -20,8 +20,8 @@ import com.datadog.android.core.internal.HashGenerator import com.datadog.android.core.internal.NoOpInternalSdkCore import com.datadog.android.core.internal.SdkCoreRegistry import com.datadog.android.core.internal.Sha256HashGenerator -import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.core.internal.utils.unboundInternalLogger +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.lint.InternalApi import com.datadog.android.privacy.TrackingConsent import java.util.Locale diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/error/internal/DatadogExceptionHandler.kt b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/error/internal/DatadogExceptionHandler.kt index 643f871b22..6996c6c87f 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/error/internal/DatadogExceptionHandler.kt +++ b/dd-sdk-android-core/src/main/kotlin/com/datadog/android/error/internal/DatadogExceptionHandler.kt @@ -18,6 +18,7 @@ import com.datadog.android.core.internal.thread.waitToIdle import com.datadog.android.core.internal.utils.asString import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.core.internal.utils.triggerUploadWorker +import com.datadog.android.internal.utils.loggableStackTrace import java.lang.ref.WeakReference import java.util.concurrent.ThreadPoolExecutor diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/DatadogTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/DatadogTest.kt index d65191f645..71ba6d54b6 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/DatadogTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/DatadogTest.kt @@ -19,6 +19,7 @@ import com.datadog.android.core.internal.NoOpInternalSdkCore import com.datadog.android.core.internal.SdkCoreRegistry import com.datadog.android.core.internal.Sha256HashGenerator import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.privacy.TrackingConsent import com.datadog.android.utils.config.ApplicationContextTestConfiguration import com.datadog.android.utils.config.InternalLoggerTestConfiguration diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/error/internal/DatadogExceptionHandlerTest.kt b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/error/internal/DatadogExceptionHandlerTest.kt index f40b3044d1..04389d028f 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/error/internal/DatadogExceptionHandlerTest.kt +++ b/dd-sdk-android-core/src/test/kotlin/com/datadog/android/error/internal/DatadogExceptionHandlerTest.kt @@ -22,6 +22,7 @@ import com.datadog.android.core.internal.thread.waitToIdle import com.datadog.android.core.internal.utils.TAG_DATADOG_UPLOAD import com.datadog.android.core.internal.utils.UPLOAD_WORKER_NAME import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.utils.config.ApplicationContextTestConfiguration import com.datadog.android.utils.forge.Configurator import com.datadog.android.utils.verifyLog diff --git a/dd-sdk-android-internal/api/apiSurface b/dd-sdk-android-internal/api/apiSurface index f18e985357..f80629999a 100644 --- a/dd-sdk-android-internal/api/apiSurface +++ b/dd-sdk-android-internal/api/apiSurface @@ -17,6 +17,8 @@ sealed class com.datadog.android.internal.telemetry.InternalTelemetryEvent constructor(String, Map?) class Error : Log constructor(String, Map? = null, Throwable? = null, String? = null, String? = null) + fun resolveKind(): String? + fun resolveStacktrace(): String? data class Configuration : InternalTelemetryEvent constructor(Boolean, Long, Long, Boolean, Boolean, Int) data class Metric : InternalTelemetryEvent @@ -27,5 +29,6 @@ sealed class com.datadog.android.internal.telemetry.InternalTelemetryEvent constructor(Boolean, Boolean, Boolean, MutableMap = mutableMapOf()) object InterceptorInstantiated : InternalTelemetryEvent fun ByteArray.toHexString(): String +fun Throwable.loggableStackTrace(): String annotation com.datadog.tools.annotation.NoOpImplementation constructor(Boolean = false) diff --git a/dd-sdk-android-internal/api/dd-sdk-android-internal.api b/dd-sdk-android-internal/api/dd-sdk-android-internal.api index 6a82e15b4e..a6ae5b9963 100644 --- a/dd-sdk-android-internal/api/dd-sdk-android-internal.api +++ b/dd-sdk-android-internal/api/dd-sdk-android-internal.api @@ -87,6 +87,8 @@ public final class com/datadog/android/internal/telemetry/InternalTelemetryEvent public final fun getError ()Ljava/lang/Throwable; public final fun getKind ()Ljava/lang/String; public final fun getStacktrace ()Ljava/lang/String; + public final fun resolveKind ()Ljava/lang/String; + public final fun resolveStacktrace ()Ljava/lang/String; } public final class com/datadog/android/internal/telemetry/InternalTelemetryEvent$Metric : com/datadog/android/internal/telemetry/InternalTelemetryEvent { @@ -106,6 +108,10 @@ public final class com/datadog/android/internal/utils/ByteArrayExtKt { public static final fun toHexString ([B)Ljava/lang/String; } +public final class com/datadog/android/internal/utils/ThrowableExtKt { + public static final fun loggableStackTrace (Ljava/lang/Throwable;)Ljava/lang/String; +} + public abstract interface annotation class com/datadog/tools/annotation/NoOpImplementation : java/lang/annotation/Annotation { public abstract fun publicNoOpImplementation ()Z } diff --git a/dd-sdk-android-internal/build.gradle.kts b/dd-sdk-android-internal/build.gradle.kts index b74bff255e..75077fe996 100644 --- a/dd-sdk-android-internal/build.gradle.kts +++ b/dd-sdk-android-internal/build.gradle.kts @@ -47,6 +47,14 @@ dependencies { // Generate NoOp implementations ksp(project(":tools:noopfactory")) + testImplementation(project(":tools:unit")) { + attributes { + attribute( + com.android.build.api.attributes.ProductFlavorAttr.of("platform"), + objects.named("jvm") + ) + } + } testImplementation(libs.bundles.jUnit5) testImplementation(libs.bundles.testTools) testFixturesImplementation(libs.kotlin) diff --git a/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/telemetry/InternalTelemetryEvent.kt b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/telemetry/InternalTelemetryEvent.kt index 839156c49d..4388770d76 100644 --- a/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/telemetry/InternalTelemetryEvent.kt +++ b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/telemetry/InternalTelemetryEvent.kt @@ -6,6 +6,8 @@ package com.datadog.android.internal.telemetry +import com.datadog.android.internal.utils.loggableStackTrace + @Suppress("UndocumentedPublicClass", "UndocumentedPublicFunction", "UndocumentedPublicProperty") sealed class InternalTelemetryEvent { @@ -18,7 +20,15 @@ sealed class InternalTelemetryEvent { val error: Throwable? = null, val stacktrace: String? = null, val kind: String? = null - ) : Log(message, additionalProperties) + ) : Log(message, additionalProperties) { + fun resolveKind(): String? { + return kind ?: error?.javaClass?.canonicalName ?: error?.javaClass?.simpleName + } + + fun resolveStacktrace(): String? { + return stacktrace ?: error?.loggableStackTrace() + } + } } data class Configuration( diff --git a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/utils/ThrowableExt.kt b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ThrowableExt.kt similarity index 85% rename from dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/utils/ThrowableExt.kt rename to dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ThrowableExt.kt index 21ec894918..78e28b213d 100644 --- a/dd-sdk-android-core/src/main/kotlin/com/datadog/android/core/internal/utils/ThrowableExt.kt +++ b/dd-sdk-android-internal/src/main/java/com/datadog/android/internal/utils/ThrowableExt.kt @@ -4,16 +4,14 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.core.internal.utils +package com.datadog.android.internal.utils -import com.datadog.android.lint.InternalApi import java.io.PrintWriter import java.io.StringWriter /** * Converts stacktrace to string format. */ -@InternalApi fun Throwable.loggableStackTrace(): String { val stringWriter = StringWriter() @Suppress("UnsafeThirdPartyFunctionCall") // NPE cannot happen here diff --git a/dd-sdk-android-internal/src/test/java/com/datadog/internal/forge/Configurator.kt b/dd-sdk-android-internal/src/test/java/com/datadog/internal/forge/Configurator.kt new file mode 100644 index 0000000000..6bedd793f8 --- /dev/null +++ b/dd-sdk-android-internal/src/test/java/com/datadog/internal/forge/Configurator.kt @@ -0,0 +1,19 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +package com.datadog.internal.forge + +import com.datadog.android.internal.tests.elmyr.InternalTelemetryErrorLogForgeryFactory +import com.datadog.tools.unit.forge.BaseConfigurator +import fr.xgouchet.elmyr.Forge + +internal class Configurator : + BaseConfigurator() { + override fun configure(forge: Forge) { + super.configure(forge) + forge.addFactory(InternalTelemetryErrorLogForgeryFactory()) + } +} diff --git a/dd-sdk-android-internal/src/test/java/com/datadog/internal/telemetry/InternalTelemetryErrorEventTest.kt b/dd-sdk-android-internal/src/test/java/com/datadog/internal/telemetry/InternalTelemetryErrorEventTest.kt new file mode 100644 index 0000000000..e205c9015c --- /dev/null +++ b/dd-sdk-android-internal/src/test/java/com/datadog/internal/telemetry/InternalTelemetryErrorEventTest.kt @@ -0,0 +1,198 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2016-Present Datadog, Inc. + */ + +package com.datadog.internal.telemetry + +import com.datadog.android.internal.telemetry.InternalTelemetryEvent +import com.datadog.android.internal.utils.loggableStackTrace +import com.datadog.tools.unit.forge.aThrowable +import fr.xgouchet.elmyr.Forge +import fr.xgouchet.elmyr.junit5.ForgeExtension +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.api.extension.Extensions +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.junit.jupiter.MockitoSettings +import org.mockito.quality.Strictness + +@Extensions( + ExtendWith(MockitoExtension::class), + ExtendWith(ForgeExtension::class) +) +@MockitoSettings(strictness = Strictness.LENIENT) +internal class InternalTelemetryErrorEventTest { + + @Test + fun `M resolve the given stacktrace W resolveStacktrace { stacktrace explicitly provided }`(forge: Forge) { + // Given + val expectedStackTrace = forge.aString() + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = null, + stacktrace = expectedStackTrace, + kind = forge.aNullable { aString() } + ) + + // When + val resolvedStackTrace = errorEvent.resolveStacktrace() + assertThat(resolvedStackTrace).isEqualTo(expectedStackTrace) + } + + @Test + fun `M resolve the given stacktrace W resolveStacktrace { stacktrace and throwable explicitly provided }`( + forge: Forge + ) { + // Given + val expectedStackTrace = forge.aString() + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = forge.aThrowable(), + stacktrace = expectedStackTrace, + kind = forge.aNullable { aString() } + ) + + // When + val resolvedStackTrace = errorEvent.resolveStacktrace() + assertThat(resolvedStackTrace).isEqualTo(expectedStackTrace) + } + + @Test + fun `M resolve throwable stacktrace W resolveStacktrace { only throwable explicitly provided }`( + forge: Forge + ) { + // Given + val fakeThrowable = forge.aThrowable() + val expectedStackTrace = fakeThrowable.loggableStackTrace() + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = fakeThrowable, + stacktrace = null, + kind = forge.aNullable { aString() } + ) + + // When + val resolvedStackTrace = errorEvent.resolveStacktrace() + assertThat(resolvedStackTrace).isEqualTo(expectedStackTrace) + } + + @Test + fun `M resolve null W resolveStacktrace { stacktrace nor throwable provided }`( + forge: Forge + ) { + // Given + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = null, + stacktrace = null, + kind = forge.aNullable { aString() } + ) + + // When + val resolvedStackTrace = errorEvent.resolveStacktrace() + assertThat(resolvedStackTrace).isNull() + } + + @Test + fun `M resolve the given kind W resolveKind { kind explicitly provided }`( + forge: Forge + ) { + // Given + val expectedKind = forge.aString() + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = null, + stacktrace = forge.aNullable { aString() }, + kind = expectedKind + ) + + // When + val resolvedKind = errorEvent.resolveKind() + assertThat(resolvedKind).isEqualTo(expectedKind) + } + + @Test + fun `M resolve the given kind W resolveKind { kind and throwable explicitly provided }`( + forge: Forge + ) { + // Given + val expectedKind = forge.aString() + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = forge.aThrowable(), + stacktrace = forge.aNullable { aString() }, + kind = expectedKind + ) + + // When + val resolvedKind = errorEvent.resolveKind() + assertThat(resolvedKind).isEqualTo(expectedKind) + } + + @Test + fun `M resolve throwable kind W resolveKind { only throwable explicitly provided }`( + forge: Forge + ) { + // Given + val fakeThrowable = forge.aThrowable() + val expectedKind = fakeThrowable.javaClass.canonicalName + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = fakeThrowable, + stacktrace = forge.aNullable { aString() }, + kind = null + ) + + // When + val resolvedKind = errorEvent.resolveKind() + assertThat(resolvedKind).isEqualTo(expectedKind) + } + + @Test + fun `M resolve throwable kind W resolveKind { only throwable explicitly provided, anonymous class }`( + forge: Forge + ) { + // Given + val fakeThrowable = object : Throwable() {} + val expectedKind = fakeThrowable.javaClass.simpleName + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = fakeThrowable, + stacktrace = forge.aNullable { aString() }, + kind = null + ) + + // When + val resolvedKind = errorEvent.resolveKind() + assertThat(resolvedKind).isEqualTo(expectedKind) + } + + @Test + fun `M resolve null W resolveKind { kind nor throwable provided }`( + forge: Forge + ) { + // Given + val errorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = null, + stacktrace = forge.aNullable { aString() }, + kind = null + ) + + // When + val resolvedKind = errorEvent.resolveKind() + assertThat(resolvedKind).isNull() + } +} diff --git a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/utils/ThrowableExtTest.kt b/dd-sdk-android-internal/src/test/java/com/datadog/internal/utils/ThrowableExtTest.kt similarity index 95% rename from dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/utils/ThrowableExtTest.kt rename to dd-sdk-android-internal/src/test/java/com/datadog/internal/utils/ThrowableExtTest.kt index a287095538..e582a09d9d 100644 --- a/dd-sdk-android-core/src/test/kotlin/com/datadog/android/core/internal/utils/ThrowableExtTest.kt +++ b/dd-sdk-android-internal/src/test/java/com/datadog/internal/utils/ThrowableExtTest.kt @@ -4,9 +4,10 @@ * Copyright 2016-Present Datadog, Inc. */ -package com.datadog.android.core.internal.utils +package com.datadog.internal.utils -import com.datadog.android.utils.forge.Configurator +import com.datadog.android.internal.utils.loggableStackTrace +import com.datadog.internal.forge.Configurator import fr.xgouchet.elmyr.annotation.Forgery import fr.xgouchet.elmyr.annotation.StringForgery import fr.xgouchet.elmyr.junit5.ForgeConfiguration diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/anr/ANRDetectorRunnable.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/anr/ANRDetectorRunnable.kt index fb8d1183bf..2566d5c060 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/anr/ANRDetectorRunnable.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/anr/ANRDetectorRunnable.kt @@ -12,6 +12,7 @@ import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.core.feature.event.ThreadDump import com.datadog.android.core.internal.utils.asString import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.GlobalRumMonitor import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumResourceScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumResourceScope.kt index dbf754d65d..b771e2b66f 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumResourceScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumResourceScope.kt @@ -12,6 +12,7 @@ import com.datadog.android.api.storage.DataWriter import com.datadog.android.core.InternalSdkCore import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.GlobalRumMonitor import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt index eb6669a3db..2f48adda0d 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt @@ -16,6 +16,7 @@ import com.datadog.android.core.InternalSdkCore import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.internal.telemetry.InternalTelemetryEvent +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.GlobalRumMonitor import com.datadog.android.rum.RumActionType import com.datadog.android.rum.RumAttributes diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/telemetry/internal/TelemetryEventHandler.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/telemetry/internal/TelemetryEventHandler.kt index 007f69ced8..065af75f97 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/telemetry/internal/TelemetryEventHandler.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/telemetry/internal/TelemetryEventHandler.kt @@ -87,8 +87,8 @@ internal class TelemetryEventHandler( datadogContext = datadogContext, timestamp = timestamp, message = event.message, - stack = event.stacktrace, - kind = event.kind, + stack = event.resolveStacktrace(), + kind = event.resolveKind(), additionalProperties = event.additionalProperties ) } diff --git a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/telemetry/internal/TelemetryEventId.kt b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/telemetry/internal/TelemetryEventId.kt index 1e3e5d0475..9cfd255d16 100644 --- a/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/telemetry/internal/TelemetryEventId.kt +++ b/features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/telemetry/internal/TelemetryEventId.kt @@ -17,7 +17,7 @@ internal data class TelemetryEventId( internal val InternalTelemetryEvent.identity: TelemetryEventId get() { return when (this) { - is InternalTelemetryEvent.Log.Error -> TelemetryEventId(type(), message, kind) + is InternalTelemetryEvent.Log.Error -> TelemetryEventId(type(), message, resolveKind()) is InternalTelemetryEvent.Log.Debug -> TelemetryEventId(type(), message, null) else -> TelemetryEventId(type(), "", null) } diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/anr/ANRDetectorRunnableTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/anr/ANRDetectorRunnableTest.kt index 337fcc7c1e..0ea47f251a 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/anr/ANRDetectorRunnableTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/anr/ANRDetectorRunnableTest.kt @@ -11,6 +11,7 @@ import android.os.Handler import android.os.Looper import com.datadog.android.core.feature.event.ThreadDump import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource import com.datadog.android.rum.utils.config.ApplicationContextTestConfiguration diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumResourceScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumResourceScopeTest.kt index 85cf1ff5e5..ed510d2b2f 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumResourceScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumResourceScopeTest.kt @@ -16,6 +16,7 @@ import com.datadog.android.api.storage.EventBatchWriter import com.datadog.android.api.storage.EventType import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource import com.datadog.android.rum.RumResourceKind diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt index 14ea1d9668..8d8562fb3b 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScopeTest.kt @@ -19,6 +19,7 @@ import com.datadog.android.core.feature.event.ThreadDump import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.internal.telemetry.InternalTelemetryEvent +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.RumActionType import com.datadog.android.rum.RumAttributes import com.datadog.android.rum.RumErrorSource diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/ErrorEventForgeryFactory.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/ErrorEventForgeryFactory.kt index 9c4d8f151e..a7d663f53a 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/ErrorEventForgeryFactory.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/ErrorEventForgeryFactory.kt @@ -7,6 +7,7 @@ package com.datadog.android.rum.utils.forge import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.model.ErrorEvent import com.datadog.tools.unit.forge.aThrowable import com.datadog.tools.unit.forge.exhaustiveAttributes diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/TelemetryErrorEventForgeryFactory.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/TelemetryErrorEventForgeryFactory.kt index 0bffb5b388..40ba8930bd 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/TelemetryErrorEventForgeryFactory.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/utils/forge/TelemetryErrorEventForgeryFactory.kt @@ -7,6 +7,7 @@ package com.datadog.android.rum.utils.forge import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.telemetry.model.TelemetryErrorEvent import com.datadog.tools.unit.forge.aThrowable import fr.xgouchet.elmyr.Forge diff --git a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/telemetry/internal/TelemetryEventHandlerTest.kt b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/telemetry/internal/TelemetryEventHandlerTest.kt index f9817786ea..e997f169ce 100644 --- a/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/telemetry/internal/TelemetryEventHandlerTest.kt +++ b/features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/telemetry/internal/TelemetryEventHandlerTest.kt @@ -17,6 +17,7 @@ import com.datadog.android.api.storage.EventType import com.datadog.android.core.InternalSdkCore import com.datadog.android.core.sampling.Sampler import com.datadog.android.internal.telemetry.InternalTelemetryEvent +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.internal.RumFeature import com.datadog.android.rum.internal.domain.RumContext import com.datadog.android.rum.internal.domain.scope.RumRawEvent @@ -35,6 +36,7 @@ import com.datadog.android.telemetry.model.TelemetryConfigurationEvent import com.datadog.android.telemetry.model.TelemetryDebugEvent import com.datadog.android.telemetry.model.TelemetryErrorEvent import com.datadog.android.telemetry.model.TelemetryUsageEvent +import com.datadog.tools.unit.forge.aThrowable import com.datadog.tools.unit.setStaticValue import fr.xgouchet.elmyr.Forge import fr.xgouchet.elmyr.annotation.Forgery @@ -254,8 +256,16 @@ internal class TelemetryEventHandlerTest { // region Error Event @Test - fun `M create error event W handleEvent(Log Error)`(@Forgery fakeLogErrorEvent: InternalTelemetryEvent.Log.Error) { + fun `M create error event W handleEvent(Log Error, only stacktrace)`(forge: Forge) { // Given + val expectedStackTrace = forge.aString() + val fakeLogErrorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = null, + stacktrace = expectedStackTrace, + kind = null + ) val fakeWrappedEvent = RumRawEvent.TelemetryEventWrapper(fakeLogErrorEvent) fakeDatadogContext = fakeDatadogContext.copy( featuresContext = fakeDatadogContext.featuresContext.toMutableMap().apply { @@ -279,7 +289,178 @@ internal class TelemetryEventHandlerTest { lastValue, fakeLogErrorEvent, noRumContext, - fakeWrappedEvent.eventTime.timestamp + fakeWrappedEvent.eventTime.timestamp, + kind = null, + stacktrace = expectedStackTrace + ) + } + } + + @Test + fun `M create error event W handleEvent(Log Error, only kind)`(forge: Forge) { + // Given + val expectedKind = forge.aString() + val fakeLogErrorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = null, + stacktrace = null, + kind = expectedKind + ) + val fakeWrappedEvent = RumRawEvent.TelemetryEventWrapper(fakeLogErrorEvent) + fakeDatadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext.toMutableMap().apply { + remove(Feature.RUM_FEATURE_NAME) + } + ) + val noRumContext = RumContext( + applicationId = RumContext.NULL_UUID, + sessionId = RumContext.NULL_UUID, + viewId = null, + actionId = null + ) + + // When + testedTelemetryHandler.handleEvent(fakeWrappedEvent, mockWriter) + + // Then + argumentCaptor { + verify(mockWriter).write(eq(mockEventBatchWriter), capture(), eq(EventType.TELEMETRY)) + assertErrorEventMatchesInternalEvent( + lastValue, + fakeLogErrorEvent, + noRumContext, + fakeWrappedEvent.eventTime.timestamp, + kind = expectedKind, + stacktrace = null + ) + } + } + + @Test + fun `M create error event W handleEvent(Log Error, kind and stacktrace)`(forge: Forge) { + // Given + val expectedKind = forge.aString() + val expectedStacktrace = forge.aString() + val fakeLogErrorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = null, + stacktrace = expectedStacktrace, + kind = expectedKind + ) + val fakeWrappedEvent = RumRawEvent.TelemetryEventWrapper(fakeLogErrorEvent) + fakeDatadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext.toMutableMap().apply { + remove(Feature.RUM_FEATURE_NAME) + } + ) + val noRumContext = RumContext( + applicationId = RumContext.NULL_UUID, + sessionId = RumContext.NULL_UUID, + viewId = null, + actionId = null + ) + + // When + testedTelemetryHandler.handleEvent(fakeWrappedEvent, mockWriter) + + // Then + argumentCaptor { + verify(mockWriter).write(eq(mockEventBatchWriter), capture(), eq(EventType.TELEMETRY)) + assertErrorEventMatchesInternalEvent( + lastValue, + fakeLogErrorEvent, + noRumContext, + fakeWrappedEvent.eventTime.timestamp, + kind = expectedKind, + stacktrace = expectedStacktrace + ) + } + } + + @Test + fun `M create error event W handleEvent(Log Error, only throwable)`(forge: Forge) { + // Given + val expectedThrowable = forge.aThrowable() + val expectedKind = expectedThrowable.javaClass.canonicalName + val expectedStacktrace = expectedThrowable.loggableStackTrace() + val fakeLogErrorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = expectedThrowable, + stacktrace = null, + kind = null + ) + val fakeWrappedEvent = RumRawEvent.TelemetryEventWrapper(fakeLogErrorEvent) + fakeDatadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext.toMutableMap().apply { + remove(Feature.RUM_FEATURE_NAME) + } + ) + val noRumContext = RumContext( + applicationId = RumContext.NULL_UUID, + sessionId = RumContext.NULL_UUID, + viewId = null, + actionId = null + ) + + // When + testedTelemetryHandler.handleEvent(fakeWrappedEvent, mockWriter) + + // Then + argumentCaptor { + verify(mockWriter).write(eq(mockEventBatchWriter), capture(), eq(EventType.TELEMETRY)) + assertErrorEventMatchesInternalEvent( + lastValue, + fakeLogErrorEvent, + noRumContext, + fakeWrappedEvent.eventTime.timestamp, + kind = expectedKind, + stacktrace = expectedStacktrace + ) + } + } + + @Test + fun `M create error event W handleEvent(Log Error, throwable, stacktrace and kind)`(forge: Forge) { + // Given + val expectedThrowable = forge.aThrowable() + val expectedKind = forge.aString() + val expectedStacktrace = forge.aString() + val fakeLogErrorEvent = InternalTelemetryEvent.Log.Error( + message = forge.aString(), + additionalProperties = forge.aMap { aString() to aString() }, + error = expectedThrowable, + stacktrace = expectedStacktrace, + kind = expectedKind + ) + val fakeWrappedEvent = RumRawEvent.TelemetryEventWrapper(fakeLogErrorEvent) + fakeDatadogContext = fakeDatadogContext.copy( + featuresContext = fakeDatadogContext.featuresContext.toMutableMap().apply { + remove(Feature.RUM_FEATURE_NAME) + } + ) + val noRumContext = RumContext( + applicationId = RumContext.NULL_UUID, + sessionId = RumContext.NULL_UUID, + viewId = null, + actionId = null + ) + + // When + testedTelemetryHandler.handleEvent(fakeWrappedEvent, mockWriter) + + // Then + argumentCaptor { + verify(mockWriter).write(eq(mockEventBatchWriter), capture(), eq(EventType.TELEMETRY)) + assertErrorEventMatchesInternalEvent( + lastValue, + fakeLogErrorEvent, + noRumContext, + fakeWrappedEvent.eventTime.timestamp, + kind = expectedKind, + stacktrace = expectedStacktrace ) } } @@ -661,6 +842,7 @@ internal class TelemetryEventHandlerTest { rawEvent.eventTime.timestamp ) } + else -> throw IllegalArgumentException( "Unexpected type=${lastValue::class.jvmName} of the captured value." ) @@ -688,13 +870,13 @@ internal class TelemetryEventHandlerTest { firstValue as TelemetryDebugEvent, fakeMetricEvent, fakeRumContext, - rawEvent.eventTime.timestamp + events[0].eventTime.timestamp ) assertDebugEventMatchesMetricInternalEvent( secondValue as TelemetryDebugEvent, fakeMetricEvent, fakeRumContext, - rawEvent.eventTime.timestamp + events[1].eventTime.timestamp ) } } @@ -778,6 +960,54 @@ internal class TelemetryEventHandlerTest { verifyNoInteractions(mockInternalLogger) } + @Test + fun `M write event W handleEvent(){ consecutive error events, same message, different kind }`( + forge: Forge + ) { + // Given + val fakeMessage = forge.aString() + val fakeThrowable = forge.aThrowable() + val fakeLogErrorEventNoKindNoThrowable = InternalTelemetryEvent.Log.Error( + message = fakeMessage, + additionalProperties = forge.aMap { aString() to aString() }, + error = null, + stacktrace = null, + kind = null + ) + val fakeLogErrorEventNoKindWithThrowable = InternalTelemetryEvent.Log.Error( + message = fakeMessage, + additionalProperties = forge.aMap { aString() to aString() }, + error = fakeThrowable, + stacktrace = null, + kind = null + ) + val events = listOf( + RumRawEvent.TelemetryEventWrapper(fakeLogErrorEventNoKindNoThrowable), + RumRawEvent.TelemetryEventWrapper(fakeLogErrorEventNoKindWithThrowable) + ) + + // When + testedTelemetryHandler.handleEvent(events[0], mockWriter) + testedTelemetryHandler.handleEvent(events[1], mockWriter) + + // Then + argumentCaptor { + verify(mockWriter, times(2)).write(eq(mockEventBatchWriter), capture(), eq(EventType.TELEMETRY)) + assertErrorEventMatchesInternalEvent( + firstValue as TelemetryErrorEvent, + fakeLogErrorEventNoKindNoThrowable, + fakeRumContext, + events[0].eventTime.timestamp + ) + assertErrorEventMatchesInternalEvent( + secondValue as TelemetryErrorEvent, + fakeLogErrorEventNoKindWithThrowable, + fakeRumContext, + events[0].eventTime.timestamp + ) + } + } + // endregion // region Api Usage @@ -934,7 +1164,9 @@ internal class TelemetryEventHandlerTest { actual: TelemetryErrorEvent, internalErrorEvent: InternalTelemetryEvent.Log.Error, rumContext: RumContext, - time: Long + time: Long, + stacktrace: String?, + kind: String? ) { assertThat(actual) .hasDate(time + fakeServerOffset) @@ -946,8 +1178,8 @@ internal class TelemetryEventHandlerTest { .hasSessionId(rumContext.sessionId) .hasViewId(rumContext.viewId) .hasActionId(rumContext.actionId) - .hasErrorStack(internalErrorEvent.stacktrace) - .hasErrorKind(internalErrorEvent.kind) + .hasErrorStack(stacktrace) + .hasErrorKind(kind) .hasDeviceArchitecture(fakeDeviceArchitecture) .hasDeviceBrand(fakeDeviceBrand) .hasDeviceModel(fakeDeviceModel) @@ -957,6 +1189,24 @@ internal class TelemetryEventHandlerTest { .hasAdditionalProperties(internalErrorEvent.additionalProperties ?: emptyMap()) } + private fun assertErrorEventMatchesInternalEvent( + actual: TelemetryErrorEvent, + internalErrorEvent: InternalTelemetryEvent.Log.Error, + rumContext: RumContext, + time: Long + ) { + val expectedStacktrace = internalErrorEvent.resolveStacktrace() + val expectedKind = internalErrorEvent.resolveKind() + assertErrorEventMatchesInternalEvent( + actual, + internalErrorEvent, + rumContext, + time, + expectedStacktrace, + expectedKind + ) + } + private fun assertConfigEventMatchesInternalEvent( actual: TelemetryConfigurationEvent, internalConfigurationEvent: InternalTelemetryEvent.Configuration, diff --git a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/handlers/AndroidSpanLogsHandler.kt b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/handlers/AndroidSpanLogsHandler.kt index c4810c6522..98c5b3314f 100644 --- a/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/handlers/AndroidSpanLogsHandler.kt +++ b/features/dd-sdk-android-trace/src/main/kotlin/com/datadog/android/trace/internal/handlers/AndroidSpanLogsHandler.kt @@ -10,6 +10,7 @@ import com.datadog.android.api.InternalLogger import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.log.LogAttributes import com.datadog.legacy.trace.api.DDTags import com.datadog.opentracing.DDSpan diff --git a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/handlers/AndroidSpanLogsHandlerTest.kt b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/handlers/AndroidSpanLogsHandlerTest.kt index 5c6780fa35..8cec1cd920 100644 --- a/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/handlers/AndroidSpanLogsHandlerTest.kt +++ b/features/dd-sdk-android-trace/src/test/kotlin/com/datadog/android/trace/internal/handlers/AndroidSpanLogsHandlerTest.kt @@ -11,6 +11,7 @@ import com.datadog.android.api.feature.Feature import com.datadog.android.api.feature.FeatureScope import com.datadog.android.api.feature.FeatureSdkCore import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.log.LogAttributes import com.datadog.android.trace.utils.verifyLog import com.datadog.android.utils.forge.Configurator diff --git a/features/dd-sdk-android-webview/src/test/kotlin/com/datadog/android/utils/forge/ErrorEventForgeryFactory.kt b/features/dd-sdk-android-webview/src/test/kotlin/com/datadog/android/utils/forge/ErrorEventForgeryFactory.kt index 2d889ef004..49a7f3a3ee 100644 --- a/features/dd-sdk-android-webview/src/test/kotlin/com/datadog/android/utils/forge/ErrorEventForgeryFactory.kt +++ b/features/dd-sdk-android-webview/src/test/kotlin/com/datadog/android/utils/forge/ErrorEventForgeryFactory.kt @@ -7,6 +7,7 @@ package com.datadog.android.utils.forge import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.model.ErrorEvent import com.datadog.tools.unit.forge.aThrowable import com.datadog.tools.unit.forge.exhaustiveAttributes diff --git a/integrations/dd-sdk-android-okhttp/src/main/kotlin/com/datadog/android/okhttp/trace/TracingInterceptor.kt b/integrations/dd-sdk-android-okhttp/src/main/kotlin/com/datadog/android/okhttp/trace/TracingInterceptor.kt index f41b9fb6ae..c82684e3c9 100644 --- a/integrations/dd-sdk-android-okhttp/src/main/kotlin/com/datadog/android/okhttp/trace/TracingInterceptor.kt +++ b/integrations/dd-sdk-android-okhttp/src/main/kotlin/com/datadog/android/okhttp/trace/TracingInterceptor.kt @@ -18,6 +18,7 @@ import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeReso import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.core.sampling.RateBasedSampler import com.datadog.android.core.sampling.Sampler +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.okhttp.TraceContext import com.datadog.android.okhttp.TraceContextInjection import com.datadog.android.okhttp.internal.otel.toOpenTracingContext diff --git a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorContextInjectionSampledTest.kt b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorContextInjectionSampledTest.kt index aa3f2ba28a..202d20dc75 100644 --- a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorContextInjectionSampledTest.kt +++ b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorContextInjectionSampledTest.kt @@ -13,6 +13,7 @@ import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeReso import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.core.sampling.RateBasedSampler import com.datadog.android.core.sampling.Sampler +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.okhttp.TraceContext import com.datadog.android.okhttp.TraceContextInjection import com.datadog.android.okhttp.internal.utils.forge.OkHttpConfigurator diff --git a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNonDdTracerNotSendingSpanTest.kt b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNonDdTracerNotSendingSpanTest.kt index 84533801cb..73417a3ccf 100644 --- a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNonDdTracerNotSendingSpanTest.kt +++ b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNonDdTracerNotSendingSpanTest.kt @@ -12,6 +12,7 @@ import com.datadog.android.api.feature.Feature import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeResolver import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.core.sampling.Sampler +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.okhttp.TraceContextInjection import com.datadog.android.okhttp.utils.assertj.HeadersAssert.Companion.assertThat import com.datadog.android.okhttp.utils.config.DatadogSingletonTestConfiguration diff --git a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNonDdTracerTest.kt b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNonDdTracerTest.kt index e50a289cbe..60ca767318 100644 --- a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNonDdTracerTest.kt +++ b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNonDdTracerTest.kt @@ -13,6 +13,7 @@ import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeReso import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.core.sampling.RateBasedSampler import com.datadog.android.core.sampling.Sampler +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.okhttp.TraceContextInjection import com.datadog.android.okhttp.utils.assertj.HeadersAssert.Companion.assertThat import com.datadog.android.okhttp.utils.config.DatadogSingletonTestConfiguration diff --git a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNotSendingSpanTest.kt b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNotSendingSpanTest.kt index cab9b19bd3..148158d925 100644 --- a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNotSendingSpanTest.kt +++ b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorNotSendingSpanTest.kt @@ -12,6 +12,7 @@ import com.datadog.android.api.feature.Feature import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeResolver import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.core.sampling.Sampler +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.okhttp.TraceContextInjection import com.datadog.android.okhttp.utils.assertj.HeadersAssert.Companion.assertThat import com.datadog.android.okhttp.utils.config.DatadogSingletonTestConfiguration diff --git a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorTest.kt b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorTest.kt index 8fffb9402f..8edcc1dab9 100644 --- a/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorTest.kt +++ b/integrations/dd-sdk-android-okhttp/src/test/kotlin/com/datadog/android/okhttp/trace/TracingInterceptorTest.kt @@ -13,6 +13,7 @@ import com.datadog.android.core.internal.net.DefaultFirstPartyHostHeaderTypeReso import com.datadog.android.core.internal.utils.loggableStackTrace import com.datadog.android.core.sampling.RateBasedSampler import com.datadog.android.core.sampling.Sampler +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.okhttp.TraceContext import com.datadog.android.okhttp.TraceContextInjection import com.datadog.android.okhttp.internal.utils.forge.OkHttpConfigurator diff --git a/reliability/single-fit/rum/build.gradle.kts b/reliability/single-fit/rum/build.gradle.kts index 0af8f8ce0d..670b40853e 100644 --- a/reliability/single-fit/rum/build.gradle.kts +++ b/reliability/single-fit/rum/build.gradle.kts @@ -30,6 +30,7 @@ android { dependencies { implementation(project(":dd-sdk-android-core")) + implementation(project(":dd-sdk-android-internal")) implementation(project(":features:dd-sdk-android-rum")) implementation(libs.kotlin) implementation(libs.bundles.androidXNavigation) diff --git a/reliability/single-fit/rum/src/test/kotlin/com/datadog/android/rum/integration/tests/elmyr/ErrorEventForgeryFactory.kt b/reliability/single-fit/rum/src/test/kotlin/com/datadog/android/rum/integration/tests/elmyr/ErrorEventForgeryFactory.kt index 139bce068b..8cc7d88a0a 100644 --- a/reliability/single-fit/rum/src/test/kotlin/com/datadog/android/rum/integration/tests/elmyr/ErrorEventForgeryFactory.kt +++ b/reliability/single-fit/rum/src/test/kotlin/com/datadog/android/rum/integration/tests/elmyr/ErrorEventForgeryFactory.kt @@ -7,6 +7,7 @@ package com.datadog.android.rum.integration.tests.elmyr import com.datadog.android.core.internal.utils.loggableStackTrace +import com.datadog.android.internal.utils.loggableStackTrace import com.datadog.android.rum.model.ErrorEvent import com.datadog.tools.unit.forge.aThrowable import com.datadog.tools.unit.forge.exhaustiveAttributes