Skip to content

Commit

Permalink
allow auto termination of spans
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Dec 6, 2024
1 parent 370b045 commit 7d42475
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 47 deletions.
38 changes: 16 additions & 22 deletions embrace-android-api/api/embrace-android-api.api
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ public abstract interface class io/embrace/android/embracesdk/internal/api/SdkAp

public final class io/embrace/android/embracesdk/internal/api/SdkApi$DefaultImpls {
public static fun createSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Lio/embrace/android/embracesdk/spans/EmbraceSpan;
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLjava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJ)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/EmbraceSpan;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;JJLjava/util/Map;Ljava/util/List;)Z
public static fun recordSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
public static fun recordSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
public static fun recordSpan (Lio/embrace/android/embracesdk/internal/api/SdkApi;Ljava/lang/String;Ljava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
Expand Down Expand Up @@ -289,12 +289,12 @@ public abstract interface class io/embrace/android/embracesdk/spans/TracingApi {
public abstract fun createSpan (Ljava/lang/String;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Lio/embrace/android/embracesdk/spans/EmbraceSpan;
public abstract fun createSpan (Ljava/lang/String;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Lio/embrace/android/embracesdk/spans/EmbraceSpan;
public abstract fun getSpan (Ljava/lang/String;)Lio/embrace/android/embracesdk/spans/EmbraceSpan;
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Ljava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLjava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJ)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/EmbraceSpan;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Ljava/util/Map;Ljava/util/List;)Z
public abstract fun recordCompletedSpan (Ljava/lang/String;JJLjava/util/Map;Ljava/util/List;)Z
public abstract fun recordSpan (Ljava/lang/String;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
public abstract fun recordSpan (Ljava/lang/String;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
public abstract fun recordSpan (Ljava/lang/String;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Ljava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
Expand All @@ -308,17 +308,11 @@ public final class io/embrace/android/embracesdk/spans/TracingApi$DefaultImpls {
public static fun createSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Lio/embrace/android/embracesdk/spans/EmbraceSpan;
public static synthetic fun createSpan$default (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;ILjava/lang/Object;)Lio/embrace/android/embracesdk/spans/EmbraceSpan;
public static synthetic fun createSpan$default (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;ILjava/lang/Object;)Lio/embrace/android/embracesdk/spans/EmbraceSpan;
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLjava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;)Z
public static synthetic fun recordCompletedSpan$default (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/AutoTerminationMode;ILjava/lang/Object;)Z
public static synthetic fun recordCompletedSpan$default (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;ILjava/lang/Object;)Z
public static synthetic fun recordCompletedSpan$default (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;ILjava/lang/Object;)Z
public static synthetic fun recordCompletedSpan$default (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;ILjava/lang/Object;)Z
public static synthetic fun recordCompletedSpan$default (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Ljava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;ILjava/lang/Object;)Z
public static synthetic fun recordCompletedSpan$default (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLjava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;ILjava/lang/Object;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJ)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/EmbraceSpan;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLio/embrace/android/embracesdk/spans/ErrorCode;Lio/embrace/android/embracesdk/spans/EmbraceSpan;)Z
public static fun recordCompletedSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;JJLjava/util/Map;Ljava/util/List;)Z
public static fun recordSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
public static fun recordSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;Lio/embrace/android/embracesdk/spans/EmbraceSpan;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
public static fun recordSpan (Lio/embrace/android/embracesdk/spans/TracingApi;Ljava/lang/String;Ljava/util/Map;Ljava/util/List;Lio/embrace/android/embracesdk/spans/AutoTerminationMode;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ public interface TracingApi {
name: String,
startTimeMs: Long,
endTimeMs: Long,
autoTerminationMode: AutoTerminationMode = AutoTerminationMode.NONE,
): Boolean =
recordCompletedSpan(
name = name,
Expand All @@ -147,7 +146,6 @@ public interface TracingApi {
startTimeMs: Long,
endTimeMs: Long,
errorCode: ErrorCode?,
autoTerminationMode: AutoTerminationMode = AutoTerminationMode.NONE,
): Boolean =
recordCompletedSpan(
name = name,
Expand All @@ -168,7 +166,6 @@ public interface TracingApi {
startTimeMs: Long,
endTimeMs: Long,
parent: EmbraceSpan?,
autoTerminationMode: AutoTerminationMode = AutoTerminationMode.NONE,
): Boolean =
recordCompletedSpan(
name = name,
Expand All @@ -191,7 +188,6 @@ public interface TracingApi {
endTimeMs: Long,
errorCode: ErrorCode?,
parent: EmbraceSpan?,
autoTerminationMode: AutoTerminationMode = AutoTerminationMode.NONE,
): Boolean = recordCompletedSpan(
name = name,
startTimeMs = startTimeMs,
Expand All @@ -213,7 +209,6 @@ public interface TracingApi {
endTimeMs: Long,
attributes: Map<String, String>?,
events: List<EmbraceSpanEvent>?,
autoTerminationMode: AutoTerminationMode = AutoTerminationMode.NONE,
): Boolean = recordCompletedSpan(
name = name,
startTimeMs = startTimeMs,
Expand All @@ -239,7 +234,6 @@ public interface TracingApi {
parent: EmbraceSpan?,
attributes: Map<String, String>?,
events: List<EmbraceSpanEvent>?,
autoTerminationMode: AutoTerminationMode = AutoTerminationMode.NONE,
): Boolean

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package io.embrace.android.embracesdk.internal.envelope.session

import io.embrace.android.embracesdk.internal.arch.schema.AppTerminationCause
import io.embrace.android.embracesdk.internal.arch.schema.EmbType
import io.embrace.android.embracesdk.internal.clock.Clock
import io.embrace.android.embracesdk.internal.logging.EmbLogger
import io.embrace.android.embracesdk.internal.payload.SessionPayload
import io.embrace.android.embracesdk.internal.payload.Span
import io.embrace.android.embracesdk.internal.payload.toNewPayload
import io.embrace.android.embracesdk.internal.session.captureDataSafely
import io.embrace.android.embracesdk.internal.session.lifecycle.ProcessStateService
import io.embrace.android.embracesdk.internal.session.orchestrator.SessionSnapshotType
import io.embrace.android.embracesdk.internal.spans.CurrentSessionSpan
import io.embrace.android.embracesdk.internal.spans.EmbraceSpanData
Expand All @@ -19,6 +21,8 @@ internal class SessionPayloadSourceImpl(
private val currentSessionSpan: CurrentSessionSpan,
private val spanRepository: SpanRepository,
private val otelPayloadMapper: OtelPayloadMapper,
private val processStateService: ProcessStateService,
private val clock: Clock,
private val logger: EmbLogger,
) : SessionPayloadSource {

Expand All @@ -31,6 +35,10 @@ internal class SessionPayloadSourceImpl(
val isCacheAttempt = endType == SessionSnapshotType.PERIODIC_CACHE
val includeSnapshots = endType != SessionSnapshotType.JVM_CRASH

if (!endType.forceQuit && processStateService.isInBackground) {
spanRepository.autoTerminateSpans(clock.now())
}

// Snapshots should only be included if the process is expected to last beyond the current session
val snapshots: List<Span>? = if (includeSnapshots) {
retrieveSpanSnapshots(isCacheAttempt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ internal class PayloadSourceModuleImpl(
otelModule.currentSessionSpan,
otelModule.spanRepository,
otelPayloadMapperProvider(),
essentialServiceModule.processStateService,
initModule.clock,
initModule.logger
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ class EmbraceTracer(
parent: EmbraceSpan?,
attributes: Map<String, String>?,
events: List<EmbraceSpanEvent>?,
autoTerminationMode: AutoTerminationMode,
): Boolean = spanService.recordCompletedSpan(
name = name,
startTimeMs = startTimeMs.normalizeTimestampAsMillis(),
Expand All @@ -77,7 +76,6 @@ class EmbraceTracer(
private = false,
attributes = attributes ?: emptyMap(),
events = events ?: emptyList(),
autoTerminationMode = autoTerminationMode,
errorCode = errorCode
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.embrace.android.embracesdk.internal.spans

import io.embrace.android.embracesdk.internal.arch.schema.EmbType
import io.embrace.android.embracesdk.internal.utils.lockAndRun
import io.embrace.android.embracesdk.spans.AutoTerminationMode
import io.embrace.android.embracesdk.spans.EmbraceSpan
import io.embrace.android.embracesdk.spans.ErrorCode
import java.util.concurrent.ConcurrentHashMap
Expand Down Expand Up @@ -100,5 +101,23 @@ class SpanRepository {
spanUpdateNotifier?.invoke()
}

/**
* Automatically terminates root spans
*/
fun autoTerminateSpans(now: Long) { // TODO: move out of collection
// TODO: pass consistent endTimeMs
activeSpans.forEach { entry ->
val span = entry.value
if (span.parent == null && entry.value.autoTerminationMode == AutoTerminationMode.ON_BACKGROUND) {
span.stop(endTimeMs = now)

// span.pare
// TODO: obtain the span children

entry.value
}
}
}

private fun notTracked(spanId: String): Boolean = activeSpans[spanId] == null && completedSpans[spanId] == null
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package io.embrace.android.embracesdk.internal.envelope.session

import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.FakeCurrentSessionSpan
import io.embrace.android.embracesdk.fakes.FakePersistableEmbraceSpan
import io.embrace.android.embracesdk.fakes.FakeProcessStateService
import io.embrace.android.embracesdk.fakes.FakeSpanData
import io.embrace.android.embracesdk.internal.arch.schema.EmbType
import io.embrace.android.embracesdk.internal.logging.EmbLoggerImpl
Expand Down Expand Up @@ -49,6 +51,8 @@ internal class SessionPayloadSourceImplTest {
crashId: String?,
): List<Span> = emptyList()
},
FakeProcessStateService(),
FakeClock(),
EmbLoggerImpl()
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ internal class PayloadFactoryBaTest {
currentSessionSpan,
spanRepository,
FakeOtelPayloadMapper(),
FakeProcessStateService(),
FakeClock(),
logger
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import io.embrace.android.embracesdk.fakes.FakeMemoryCleanerService
import io.embrace.android.embracesdk.fakes.FakeMetadataService
import io.embrace.android.embracesdk.fakes.FakeOtelPayloadMapper
import io.embrace.android.embracesdk.fakes.FakePreferenceService
import io.embrace.android.embracesdk.fakes.FakeProcessStateService
import io.embrace.android.embracesdk.fakes.FakeSessionIdTracker
import io.embrace.android.embracesdk.fakes.FakeSessionPropertiesService
import io.embrace.android.embracesdk.fakes.FakeUserService
Expand Down Expand Up @@ -97,6 +98,8 @@ internal class SessionHandlerTest {
currentSessionSpan,
spanRepository,
FakeOtelPayloadMapper(),
FakeProcessStateService(),
FakeClock(),
logger
)
val payloadSourceModule = FakePayloadSourceModule(
Expand Down
Loading

0 comments on commit 7d42475

Please sign in to comment.