Skip to content

Commit

Permalink
refactor: specify end time for in progress anrs
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Jun 5, 2024
1 parent 37dbdce commit 7e08ef9
Show file tree
Hide file tree
Showing 16 changed files with 65 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ internal class AnrFeatureTest {
// assert ANRs received
val spans = message.findAnrSpans()
val span = spans.single()
assertAnrReceived(span, START_TIME_MS, sampleCount, endTime = 0)
assertAnrReceived(span, START_TIME_MS, sampleCount, endTime = 10000032000)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.embrace.android.embracesdk.anr

import io.embrace.android.embracesdk.arch.DataCaptureServiceOtelConverter
import io.embrace.android.embracesdk.internal.clock.Clock
import io.embrace.android.embracesdk.internal.clock.millisToNanos
import io.embrace.android.embracesdk.internal.payload.Attribute
import io.embrace.android.embracesdk.internal.payload.Span
Expand All @@ -14,7 +15,8 @@ import io.opentelemetry.sdk.trace.IdGenerator
* Maps captured ANRs to OTel constructs.
*/
internal class AnrOtelMapper(
private val anrService: AnrService
private val anrService: AnrService,
private val clock: Clock
) : DataCaptureServiceOtelConverter {

override fun snapshot(isFinalPayload: Boolean): List<Span> {
Expand All @@ -29,7 +31,7 @@ internal class AnrOtelMapper(
parentSpanId = SpanId.getInvalid(),
name = "emb-thread-blockage",
startTimeNanos = interval.startTime.millisToNanos(),
endTimeNanos = interval.endTime?.millisToNanos(),
endTimeNanos = (interval.endTime ?: clock.now()).millisToNanos(),
status = Span.Status.OK,
attributes = attrs,
events = events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.squareup.moshi.Types
import io.embrace.android.embracesdk.arch.DataCaptureServiceOtelConverter
import io.embrace.android.embracesdk.internal.clock.Clock
import io.embrace.android.embracesdk.internal.clock.millisToNanos
import io.embrace.android.embracesdk.internal.payload.Attribute
import io.embrace.android.embracesdk.internal.payload.Span
Expand All @@ -16,7 +17,8 @@ import io.opentelemetry.sdk.trace.IdGenerator

internal class NativeAnrOtelMapper(
private val nativeThreadSamplerService: NativeThreadSamplerService?,
private val serializer: EmbraceSerializer
private val serializer: EmbraceSerializer,
private val clock: Clock
) : DataCaptureServiceOtelConverter {

override fun snapshot(isFinalPayload: Boolean): List<Span> {
Expand All @@ -35,6 +37,7 @@ internal class NativeAnrOtelMapper(
parentSpanId = SpanId.getInvalid(),
name = "emb_native_thread_blockage",
startTimeNanos = interval.threadBlockedTimestamp?.millisToNanos(),
endTimeNanos = clock.now().millisToNanos(),
status = Span.Status.OK,
attributes = attrs,
events = events
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ internal class AnrModuleImpl(
}

override val anrOtelMapper: AnrOtelMapper by singleton {
AnrOtelMapper(anrService)
AnrOtelMapper(anrService, initModule.clock)
}

override val responsivenessMonitorService: ResponsivenessMonitorService by singleton {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ internal class NativeModuleImpl(
}

override val nativeAnrOtelMapper: NativeAnrOtelMapper by singleton {
NativeAnrOtelMapper(nativeThreadSamplerService, initModule.jsonSerializer)
NativeAnrOtelMapper(nativeThreadSamplerService, initModule.jsonSerializer, initModule.clock)
}

override val nativeThreadSamplerInstaller: NativeThreadSamplerInstaller? by singleton {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.embrace.android.embracesdk.anr

import io.embrace.android.embracesdk.fakes.FakeAnrService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.internal.clock.millisToNanos
import io.embrace.android.embracesdk.internal.clock.nanosToMillis
import io.embrace.android.embracesdk.internal.payload.Attribute
import io.embrace.android.embracesdk.internal.payload.Span
Expand All @@ -13,7 +15,6 @@ import io.embrace.android.embracesdk.payload.extensions.clearSamples
import io.opentelemetry.api.trace.SpanId
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test

Expand Down Expand Up @@ -69,6 +70,8 @@ internal class AnrOtelMapperTest {

private val clearedInterval = completedInterval.clearSamples()

private lateinit var clock: FakeClock

private val intervalWithLimitedSample = completedInterval.copy(
anrSampleList = AnrSampleList(
List(100) { k ->
Expand All @@ -84,7 +87,8 @@ internal class AnrOtelMapperTest {
@Before
fun setUp() {
anrService = FakeAnrService()
mapper = AnrOtelMapper(anrService)
clock = FakeClock()
mapper = AnrOtelMapper(anrService, clock)
}

@Test
Expand Down Expand Up @@ -127,7 +131,7 @@ internal class AnrOtelMapperTest {
val span = spans.single()
span.assertCommonOtelCharacteristics()

assertNull(span.endTimeNanos)
assertEquals(clock.now().millisToNanos(), span.endTimeNanos)
val attributes = checkNotNull(span.attributes)
val lastKnownTime =
checkNotNull(attributes.findAttribute("last_known_time_unix_nano").data)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.embrace.android.embracesdk.anr.ndk

import io.embrace.android.embracesdk.config.remote.AnrRemoteConfig
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeNativeThreadSamplerService
import io.embrace.android.embracesdk.internal.clock.millisToNanos
import io.embrace.android.embracesdk.internal.payload.Attribute
Expand All @@ -22,12 +23,12 @@ internal class NativeAnrOtelMapperTest {
@Before
fun setUp() {
service = FakeNativeThreadSamplerService()
mapper = NativeAnrOtelMapper(service, EmbraceSerializer())
mapper = NativeAnrOtelMapper(service, EmbraceSerializer(), FakeClock())
}

@Test
fun `disabled service`() {
val disabledMapper = NativeAnrOtelMapper(null, EmbraceSerializer())
val disabledMapper = NativeAnrOtelMapper(null, EmbraceSerializer(), FakeClock())
assertEquals(emptyList<Span>(), disabledMapper.snapshot(false))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.embrace.android.embracesdk.fakes

import io.embrace.android.embracesdk.anr.AnrOtelMapper
import io.embrace.android.embracesdk.anr.ndk.NativeAnrOtelMapper
import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer

internal fun fakeAnrOtelMapper() = AnrOtelMapper(FakeAnrService(), FakeClock())
internal fun fakeNativeAnrOtelMapper() = NativeAnrOtelMapper(null, EmbraceSerializer(), FakeClock())
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import io.embrace.android.embracesdk.capture.monitor.ResponsivenessMonitorServic
import io.embrace.android.embracesdk.fakes.FakeAnrService
import io.embrace.android.embracesdk.fakes.FakeCurrentSessionSpan
import io.embrace.android.embracesdk.fakes.fakeAnrBehavior
import io.embrace.android.embracesdk.fakes.fakeAnrOtelMapper
import io.embrace.android.embracesdk.injection.AnrModule
import io.embrace.android.embracesdk.internal.SharedObjectLoader
import io.embrace.android.embracesdk.logging.EmbLoggerImpl

internal class FakeAnrModule(
override val anrService: AnrService = FakeAnrService(),
override val anrOtelMapper: AnrOtelMapper = AnrOtelMapper(anrService),
override val anrOtelMapper: AnrOtelMapper = fakeAnrOtelMapper(),
override val responsivenessMonitorService: ResponsivenessMonitorService = NoOpResponsivenessMonitorService(),
override val sigquitDataSource: SigquitDataSource = SigquitDataSource(
SharedObjectLoader(EmbLoggerImpl()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import io.embrace.android.embracesdk.FakeNdkService
import io.embrace.android.embracesdk.anr.ndk.NativeAnrOtelMapper
import io.embrace.android.embracesdk.anr.ndk.NativeThreadSamplerInstaller
import io.embrace.android.embracesdk.anr.ndk.NativeThreadSamplerService
import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer
import io.embrace.android.embracesdk.fakes.fakeNativeAnrOtelMapper
import io.embrace.android.embracesdk.ndk.NativeModule
import io.embrace.android.embracesdk.ndk.NdkService

internal class FakeNativeModule(
override val nativeThreadSamplerService: NativeThreadSamplerService? = null,
override val nativeThreadSamplerInstaller: NativeThreadSamplerInstaller? = null,
override val ndkService: NdkService = FakeNdkService(),
override val nativeAnrOtelMapper: NativeAnrOtelMapper = NativeAnrOtelMapper(null, EmbraceSerializer())
override val nativeAnrOtelMapper: NativeAnrOtelMapper = fakeNativeAnrOtelMapper()
) : NativeModule
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package io.embrace.android.embracesdk.session
import io.embrace.android.embracesdk.FakeDeliveryService
import io.embrace.android.embracesdk.FakeNdkService
import io.embrace.android.embracesdk.FakeSessionPropertiesService
import io.embrace.android.embracesdk.anr.AnrOtelMapper
import io.embrace.android.embracesdk.anr.ndk.NativeAnrOtelMapper
import io.embrace.android.embracesdk.capture.envelope.session.SessionEnvelopeSourceImpl
import io.embrace.android.embracesdk.capture.internal.errors.InternalErrorService
import io.embrace.android.embracesdk.capture.metadata.MetadataService
Expand All @@ -15,7 +13,6 @@ import io.embrace.android.embracesdk.config.local.LocalConfig
import io.embrace.android.embracesdk.event.EventService
import io.embrace.android.embracesdk.event.LogMessageService
import io.embrace.android.embracesdk.fakeBackgroundActivity
import io.embrace.android.embracesdk.fakes.FakeAnrService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeConfigService
import io.embrace.android.embracesdk.fakes.FakeEnvelopeMetadataSource
Expand All @@ -32,6 +29,8 @@ import io.embrace.android.embracesdk.fakes.FakeSessionPayloadSource
import io.embrace.android.embracesdk.fakes.FakeStartupService
import io.embrace.android.embracesdk.fakes.FakeUserService
import io.embrace.android.embracesdk.fakes.FakeWebViewService
import io.embrace.android.embracesdk.fakes.fakeAnrOtelMapper
import io.embrace.android.embracesdk.fakes.fakeNativeAnrOtelMapper
import io.embrace.android.embracesdk.fakes.injection.FakeInitModule
import io.embrace.android.embracesdk.internal.SystemInfo
import io.embrace.android.embracesdk.internal.logs.LogSinkImpl
Expand Down Expand Up @@ -178,8 +177,8 @@ internal class PayloadFactoryBaTest {
currentSessionSpan,
FakeSessionPropertiesService(),
FakeStartupService(),
AnrOtelMapper(FakeAnrService()),
NativeAnrOtelMapper(null, EmbraceSerializer()),
fakeAnrOtelMapper(),
fakeNativeAnrOtelMapper(),
logger
)
val sessionEnvelopeSource = SessionEnvelopeSourceImpl(
Expand All @@ -198,8 +197,8 @@ internal class PayloadFactoryBaTest {
currentSessionSpan,
FakeSessionPropertiesService(),
FakeStartupService(),
AnrOtelMapper(FakeAnrService()),
NativeAnrOtelMapper(null, EmbraceSerializer()),
fakeAnrOtelMapper(),
fakeNativeAnrOtelMapper(),
logger
)
return PayloadFactoryImpl(collator, v2Collator, configService, logger).apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package io.embrace.android.embracesdk.session
import io.embrace.android.embracesdk.FakeDeliveryService
import io.embrace.android.embracesdk.FakeNdkService
import io.embrace.android.embracesdk.FakeSessionPropertiesService
import io.embrace.android.embracesdk.anr.AnrOtelMapper
import io.embrace.android.embracesdk.anr.ndk.NativeAnrOtelMapper
import io.embrace.android.embracesdk.capture.envelope.session.SessionEnvelopeSourceImpl
import io.embrace.android.embracesdk.capture.internal.errors.InternalErrorService
import io.embrace.android.embracesdk.capture.metadata.MetadataService
Expand All @@ -14,7 +12,6 @@ import io.embrace.android.embracesdk.config.LocalConfigParser
import io.embrace.android.embracesdk.config.local.LocalConfig
import io.embrace.android.embracesdk.event.EventService
import io.embrace.android.embracesdk.event.LogMessageService
import io.embrace.android.embracesdk.fakes.FakeAnrService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeConfigService
import io.embrace.android.embracesdk.fakes.FakeEnvelopeMetadataSource
Expand All @@ -30,6 +27,8 @@ import io.embrace.android.embracesdk.fakes.FakeSessionIdTracker
import io.embrace.android.embracesdk.fakes.FakeSessionPayloadSource
import io.embrace.android.embracesdk.fakes.FakeStartupService
import io.embrace.android.embracesdk.fakes.FakeUserService
import io.embrace.android.embracesdk.fakes.fakeAnrOtelMapper
import io.embrace.android.embracesdk.fakes.fakeNativeAnrOtelMapper
import io.embrace.android.embracesdk.fakes.injection.FakeInitModule
import io.embrace.android.embracesdk.internal.SystemInfo
import io.embrace.android.embracesdk.internal.logs.LogSinkImpl
Expand Down Expand Up @@ -188,8 +187,8 @@ internal class PayloadFactorySessionTest {
currentSessionSpan,
FakeSessionPropertiesService(),
FakeStartupService(),
AnrOtelMapper(FakeAnrService()),
NativeAnrOtelMapper(null, EmbraceSerializer()),
fakeAnrOtelMapper(),
fakeNativeAnrOtelMapper(),
logger
)
service = PayloadFactoryImpl(v1Collator, v2Collator, FakeConfigService(), logger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package io.embrace.android.embracesdk.session
import io.embrace.android.embracesdk.FakeDeliveryService
import io.embrace.android.embracesdk.FakeNdkService
import io.embrace.android.embracesdk.FakeSessionPropertiesService
import io.embrace.android.embracesdk.anr.AnrOtelMapper
import io.embrace.android.embracesdk.anr.ndk.NativeAnrOtelMapper
import io.embrace.android.embracesdk.capture.envelope.session.SessionEnvelopeSourceImpl
import io.embrace.android.embracesdk.capture.internal.errors.EmbraceInternalErrorService
import io.embrace.android.embracesdk.capture.webview.WebViewService
Expand All @@ -15,7 +13,6 @@ import io.embrace.android.embracesdk.config.local.SessionLocalConfig
import io.embrace.android.embracesdk.config.remote.RemoteConfig
import io.embrace.android.embracesdk.event.EventService
import io.embrace.android.embracesdk.event.LogMessageService
import io.embrace.android.embracesdk.fakes.FakeAnrService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeConfigService
import io.embrace.android.embracesdk.fakes.FakeEnvelopeMetadataSource
Expand All @@ -31,12 +28,13 @@ import io.embrace.android.embracesdk.fakes.FakeSessionPayloadSource
import io.embrace.android.embracesdk.fakes.FakeStartupService
import io.embrace.android.embracesdk.fakes.FakeUserService
import io.embrace.android.embracesdk.fakes.FakeWebViewService
import io.embrace.android.embracesdk.fakes.fakeAnrOtelMapper
import io.embrace.android.embracesdk.fakes.fakeAutoDataCaptureBehavior
import io.embrace.android.embracesdk.fakes.fakeDataCaptureEventBehavior
import io.embrace.android.embracesdk.fakes.fakeNativeAnrOtelMapper
import io.embrace.android.embracesdk.fakes.fakeSession
import io.embrace.android.embracesdk.fakes.fakeSessionBehavior
import io.embrace.android.embracesdk.fakes.injection.FakeInitModule
import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer
import io.embrace.android.embracesdk.internal.spans.CurrentSessionSpan
import io.embrace.android.embracesdk.internal.spans.EmbraceSpanData
import io.embrace.android.embracesdk.internal.spans.SpanRepository
Expand Down Expand Up @@ -158,8 +156,8 @@ internal class SessionHandlerTest {
initModule.openTelemetryModule.currentSessionSpan,
FakeSessionPropertiesService(),
FakeStartupService(),
AnrOtelMapper(FakeAnrService()),
NativeAnrOtelMapper(null, EmbraceSerializer()),
fakeAnrOtelMapper(),
fakeNativeAnrOtelMapper(),
logger
)
val v2Collator = V2PayloadMessageCollator(
Expand All @@ -177,8 +175,8 @@ internal class SessionHandlerTest {
currentSessionSpan,
FakeSessionPropertiesService(),
FakeStartupService(),
AnrOtelMapper(FakeAnrService()),
NativeAnrOtelMapper(null, EmbraceSerializer()),
fakeAnrOtelMapper(),
fakeNativeAnrOtelMapper(),
logger,
)
payloadFactory = PayloadFactoryImpl(payloadMessageCollator, v2Collator, configService, logger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.embrace.android.embracesdk.FakeSessionPropertiesService
import io.embrace.android.embracesdk.anr.AnrOtelMapper
import io.embrace.android.embracesdk.anr.ndk.NativeAnrOtelMapper
import io.embrace.android.embracesdk.fakes.FakeAnrService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeEventService
import io.embrace.android.embracesdk.fakes.FakeGatingService
import io.embrace.android.embracesdk.fakes.FakeInternalErrorService
Expand Down Expand Up @@ -54,6 +55,7 @@ internal class V1PayloadMessageCollatorTest {
data = listOf(fakeCompletedAnrInterval, fakeInProgressAnrInterval)
}

val clock = FakeClock()
collator = V1PayloadMessageCollator(
gatingService = gatingService,
nativeThreadSamplerService = null,
Expand All @@ -69,8 +71,8 @@ internal class V1PayloadMessageCollatorTest {
currentSessionSpan = initModule.openTelemetryModule.currentSessionSpan,
sessionPropertiesService = FakeSessionPropertiesService(),
startupService = FakeStartupService(),
anrOtelMapper = AnrOtelMapper(anrService),
nativeAnrOtelMapper = NativeAnrOtelMapper(null, EmbraceSerializer()),
anrOtelMapper = AnrOtelMapper(anrService, clock),
nativeAnrOtelMapper = NativeAnrOtelMapper(null, EmbraceSerializer(), clock),
logger = initModule.logger
)
}
Expand Down
Loading

0 comments on commit 7e08ef9

Please sign in to comment.