Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specify end time for in progress anrs #923

Merged
merged 1 commit into from
Jun 6, 2024
Merged
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
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 @@ -7,6 +7,7 @@ import io.embrace.android.embracesdk.anr.sigquit.SigquitDataSource
import io.embrace.android.embracesdk.capture.monitor.NoOpResponsivenessMonitorService
import io.embrace.android.embracesdk.capture.monitor.ResponsivenessMonitorService
import io.embrace.android.embracesdk.fakes.FakeAnrService
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeCurrentSessionSpan
import io.embrace.android.embracesdk.fakes.fakeAnrBehavior
import io.embrace.android.embracesdk.injection.AnrModule
Expand All @@ -15,7 +16,7 @@ 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 = AnrOtelMapper(anrService, FakeClock()),
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,6 +4,7 @@ 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.fakes.FakeClock
import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer
import io.embrace.android.embracesdk.ndk.NativeModule
import io.embrace.android.embracesdk.ndk.NdkService
Expand All @@ -12,5 +13,5 @@ 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 = NativeAnrOtelMapper(null, EmbraceSerializer(), FakeClock())
) : 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