Skip to content

Commit

Permalink
poc: schema types
Browse files Browse the repository at this point in the history
  • Loading branch information
fractalwrench committed Mar 7, 2024
1 parent b4d2c94 commit 687a29b
Show file tree
Hide file tree
Showing 16 changed files with 102 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal interface SpanDataSource : DataSource<SpanService> {
*/
internal fun <T> SpanService.startSpanCapture(obj: T, mapper: T.() -> StartSpanData): EmbraceSpan? {
val data = obj.mapper()
return createSpan(data.spanName)?.apply {
return createSpan(data.schemaType.name)?.apply {
data.attributes.forEach {
addAttribute(it.key, it.value)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
package io.embrace.android.embracesdk.arch.destination

import io.embrace.android.embracesdk.Severity
import io.embrace.android.embracesdk.arch.schema.TelemetryType
import io.embrace.android.embracesdk.arch.schema.SchemaType

/**
* Represents a Log event that can be added to the current session span.
*
*
* @param embType the type of the span. Used to differentiate data from different sources
* @param schemaType the type of the span. Used to differentiate data from different sources
* by the backend.
* @param severity the severity of the log
* @param message the message of the log
* @param attributes the attributes of the span. emb-type is automatically added to these.
*/
internal class LogEventData(
embType: TelemetryType,
val schemaType: SchemaType,
val severity: Severity,
val message: String,
attributes: Map<String, String>? = null
val message: String
) {
val attributes = (attributes ?: emptyMap()).plus(Pair("emb.type", embType.description))
val attributes = schemaType.attrs.plus(Pair("emb.type", schemaType.telemetryType.description))
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package io.embrace.android.embracesdk.arch.destination

import io.embrace.android.embracesdk.arch.schema.TelemetryType
import io.embrace.android.embracesdk.arch.schema.SchemaType

/**
* Represents a span event that can be added to the current session span.
*
* @param embType the type of the event. Used to differentiate data from different sources
* @param schemaType the type of the event. Used to differentiate data from different sources
* by the backend.
* @param spanName the name of the span event.
* @param spanStartTimeMs the start time of the span event in milliseconds.
* @param attributes the attributes of the span event. emb-type is automatically added to these.
*/
internal class SpanEventData(
embType: TelemetryType,
val spanName: String,
val spanStartTimeMs: Long,
attributes: Map<String, String>? = null
val schemaType: SchemaType,
val spanStartTimeMs: Long
) {
val attributes = (attributes ?: emptyMap()).plus(Pair("emb.type", embType.description))
val attributes = schemaType.attrs.plus(Pair("emb.type", schemaType.telemetryType.description))
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package io.embrace.android.embracesdk.arch.destination

import io.embrace.android.embracesdk.arch.schema.TelemetryType
import io.embrace.android.embracesdk.arch.schema.SchemaType

/**
* Holds the information required to start a span.
*
* @param embType the type of the span. Used to differentiate data from different sources
* @param schemaType the type of the span. Used to differentiate data from different sources
* by the backend.
* @param spanName the name of the span.
* @param spanStartTimeMs the start time of the span event in milliseconds.
* @param attributes the attributes of the span. emb-type is automatically added to these.
*/
internal class StartSpanData(
embType: TelemetryType,
val spanName: String,
val schemaType: SchemaType,
val spanStartTimeMs: Long,
attributes: Map<String, String>? = null
) {
val attributes = (attributes ?: emptyMap()).plus(Pair("emb.type", embType.description))
val attributes = schemaType.attrs.plus(Pair("emb.type", schemaType.telemetryType.description))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package io.embrace.android.embracesdk.arch.schema

import io.embrace.android.embracesdk.internal.logs.EmbraceLogAttributes
import io.embrace.android.embracesdk.internal.utils.toNonNullMap
import io.embrace.android.embracesdk.payload.AppExitInfoData

internal sealed class SchemaType(
val telemetryType: TelemetryType,
val name: String,
) {
abstract val attrs: Map<String, String>

internal class CustomBreadcrumb(message: String) : SchemaType(
EmbType.System.Breadcrumb,
"custom-breadcrumb"
) {
override val attrs = mapOf("message" to message)
}

internal class ViewBreadcrumb(viewName: String) : SchemaType(
EmbType.Ux.View,
"view-breadcrumb"
) {
override val attrs = mapOf("view.name" to viewName)
}

internal class AeiLog(message: AppExitInfoData) : SchemaType(
EmbType.System.Exit,
"aei-record"
) {
override val attrs = mapOf(
"session-id" to message.sessionId,
"session-id-error" to message.sessionIdError,
"process-importance" to message.importance.toString(),
"pss" to message.pss.toString(),
"rs" to message.reason.toString(),
"rss" to message.rss.toString(),
"exit-status" to message.status.toString(),
"timestamp" to message.timestamp.toString(),
"description" to message.description,
"trace-status" to message.traceStatus
).toNonNullMap()
}

internal class Log(attributes: EmbraceLogAttributes) : SchemaType(
EmbType.System.Log,
"emb-log"
) {
override val attrs = attributes.toMap()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ import io.embrace.android.embracesdk.arch.destination.LogEventData
import io.embrace.android.embracesdk.arch.destination.LogEventMapper
import io.embrace.android.embracesdk.arch.destination.LogWriter
import io.embrace.android.embracesdk.arch.limits.UpToLimitStrategy
import io.embrace.android.embracesdk.arch.schema.EmbType
import io.embrace.android.embracesdk.arch.schema.SchemaType
import io.embrace.android.embracesdk.capture.metadata.MetadataService
import io.embrace.android.embracesdk.capture.user.UserService
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.config.behavior.AppExitInfoBehavior
import io.embrace.android.embracesdk.internal.utils.BuildVersionChecker
import io.embrace.android.embracesdk.internal.utils.VersionChecker
import io.embrace.android.embracesdk.internal.utils.toNonNullMap
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.Companion.logDebug
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.Companion.logInfoWithException
import io.embrace.android.embracesdk.logging.InternalStaticEmbraceLogger.Companion.logWarningWithException
Expand Down Expand Up @@ -48,7 +47,6 @@ internal class AeiDataSourceImpl(
) {

companion object {
private const val LOG_NAME = "aei-record"
private const val SDK_AEI_SEND_LIMIT = 32
}

Expand Down Expand Up @@ -210,24 +208,11 @@ internal class AeiDataSourceImpl(

override fun toLogEventData(obj: BlobMessage): LogEventData {
val message: AppExitInfoData = obj.applicationExits.single()
val attrs = mapOf(
"session-id" to message.sessionId,
"session-id-error" to message.sessionIdError,
"process-importance" to message.importance.toString(),
"pss" to message.pss.toString(),
"rs" to message.reason.toString(),
"rss" to message.rss.toString(),
"exit-status" to message.status.toString(),
"timestamp" to message.timestamp.toString(),
"blob" to message.trace,
"description" to message.description,
"trace-status" to message.traceStatus
)
val schemaType = SchemaType.AeiLog(message)
return LogEventData(
EmbType.System.Exit,
schemaType = schemaType,
severity = Severity.INFO,
message = LOG_NAME,
attributes = attrs.toNonNullMap()
message = message.trace ?: ""
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import io.embrace.android.embracesdk.arch.destination.SessionSpanWriter
import io.embrace.android.embracesdk.arch.destination.SpanEventData
import io.embrace.android.embracesdk.arch.destination.SpanEventMapper
import io.embrace.android.embracesdk.arch.limits.UpToLimitStrategy
import io.embrace.android.embracesdk.arch.schema.EmbType
import io.embrace.android.embracesdk.arch.schema.SchemaType
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.internal.clock.millisToNanos
import io.embrace.android.embracesdk.payload.CustomBreadcrumb
Expand All @@ -22,11 +22,6 @@ internal class CustomBreadcrumbDataSource(
),
SpanEventMapper<CustomBreadcrumb> {

companion object {
internal const val EVENT_NAME = "custom-breadcrumb"
internal const val ATTR_KEY_MESSAGE = "message"
}

fun logCustom(message: String, timestamp: Long) {
alterSessionSpan(
inputValidation = {
Expand All @@ -39,10 +34,10 @@ internal class CustomBreadcrumbDataSource(
)
}

override fun toSpanEventData(obj: CustomBreadcrumb) = SpanEventData(
EmbType.System.Breadcrumb,
EVENT_NAME,
obj.timestamp.millisToNanos(),
mapOf("message" to (obj.message ?: ""))
)
override fun toSpanEventData(obj: CustomBreadcrumb): SpanEventData {
return SpanEventData(
SchemaType.CustomBreadcrumb(obj.message ?: ""),
obj.timestamp.millisToNanos()
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.embrace.android.embracesdk.arch.datasource.startSpanCapture
import io.embrace.android.embracesdk.arch.destination.StartSpanData
import io.embrace.android.embracesdk.arch.destination.StartSpanMapper
import io.embrace.android.embracesdk.arch.limits.UpToLimitStrategy
import io.embrace.android.embracesdk.arch.schema.EmbType
import io.embrace.android.embracesdk.arch.schema.SchemaType
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.internal.clock.Clock
import io.embrace.android.embracesdk.internal.spans.SpanService
Expand All @@ -26,10 +26,6 @@ internal class FragmentBreadcrumbDataSource(
),
StartSpanMapper<FragmentBreadcrumb> {

companion object {
internal const val SPAN_NAME = "screen-view"
}

private val fragmentSpans: MutableMap<String, EmbraceSpan> = mutableMapOf()

/**
Expand Down Expand Up @@ -74,10 +70,8 @@ internal class FragmentBreadcrumbDataSource(

override fun toStartSpanData(obj: FragmentBreadcrumb): StartSpanData = with(obj) {
StartSpanData(
embType = EmbType.Ux.View,
spanName = SPAN_NAME,
schemaType = SchemaType.ViewBreadcrumb(name),
spanStartTimeMs = start,
attributes = mapOf("view.name" to name)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import io.embrace.android.embracesdk.LogExceptionType
import io.embrace.android.embracesdk.Severity
import io.embrace.android.embracesdk.arch.destination.LogEventData
import io.embrace.android.embracesdk.arch.destination.LogWriter
import io.embrace.android.embracesdk.arch.schema.EmbType
import io.embrace.android.embracesdk.arch.schema.SchemaType
import io.embrace.android.embracesdk.capture.metadata.MetadataService
import io.embrace.android.embracesdk.config.ConfigService
import io.embrace.android.embracesdk.config.behavior.LogMessageBehavior
Expand Down Expand Up @@ -129,10 +129,9 @@ internal class EmbraceLogService(
attributes.setLogId(Uuid.getEmbUuid())

val logEventData = LogEventData(
EmbType.System.Log,
schemaType = SchemaType.Log(attributes),
message = trimToMaxLength(message),
severity = severity,
attributes = attributes.toMap()
)

logWriter.addLog(logEventData) { logEventData }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ internal class CurrentSessionSpanImpl(
override fun <T> addEvent(obj: T, mapper: T.() -> SpanEventData): Boolean {
val currentSession = sessionSpan.get() ?: return false
val event = obj.mapper()
return currentSession.addEvent(event.spanName, event.spanStartTimeMs, event.attributes)
return currentSession.addEvent(event.schemaType.name, event.spanStartTimeMs, event.attributes)
}

override fun addAttribute(attribute: SpanAttributeData): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package io.embrace.android.embracesdk.arch

import io.embrace.android.embracesdk.arch.datasource.startSpanCapture
import io.embrace.android.embracesdk.arch.destination.StartSpanData
import io.embrace.android.embracesdk.arch.schema.EmbType
import io.embrace.android.embracesdk.arch.schema.SchemaType
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.injection.FakeInitModule
import io.embrace.android.embracesdk.internal.spans.SpanServiceImpl
Expand All @@ -22,13 +22,11 @@ internal class SpanDataSourceKtTest {
service.initializeService(1500000000000)

val data = StartSpanData(
EmbType.Ux.View,
"spanName",
1500000000000,
mapOf("key" to "value")
SchemaType.ViewBreadcrumb("my-view"),
1500000000000
)
assertEquals("ux.view", data.attributes["emb.type"])
assertEquals("value", data.attributes["key"])
assertEquals("my-view", data.attributes["view.name"])

val span = service.startSpanCapture("") { data }
checkNotNull(span)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,11 @@ internal class AeiDataSourceImplTest {
assertEquals(RSS.toString(), attrs["rss"])
assertEquals(STATUS.toString(), attrs["exit-status"])
assertEquals(DESCRIPTION, attrs["description"])
assertEquals(TRACE, attrs["blob"])
assertEquals("", attrs["session-id-error"])
assertNull(attrs["trace-status"])

val logEventData = logWriter.logEvents.single()
assertEquals(TRACE, logEventData.message)
}

@Test
Expand Down Expand Up @@ -316,8 +318,8 @@ internal class AeiDataSourceImplTest {
startApplicationExitInfoService()

// then a truncated trace should be sent
val attrs = getAeiLogAttrs()
assertEquals("a".repeat(100), attrs["blob"])
val logEventData = logWriter.logEvents.single()
assertEquals("a".repeat(100), logEventData.message)
}

@Test
Expand Down Expand Up @@ -356,7 +358,7 @@ internal class AeiDataSourceImplTest {

private fun getAeiLogAttrs(): Map<String, String> {
val logEventData = logWriter.logEvents.single()
assertEquals("aei-record", logEventData.message)
assertEquals("aei-record", logEventData.schemaType.name)
assertEquals(Severity.INFO, logEventData.severity)
assertEquals("system.exit", logEventData.attributes["emb.type"])
return logEventData.attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal class CustomBreadcrumbDataSourceTest {
fun `add breadcrumb`() {
source.logCustom("Hello, world!", 15000000000)
with(writer.addedEvents.single()) {
assertEquals("custom-breadcrumb", spanName)
assertEquals("custom-breadcrumb", this.schemaType.name)
assertEquals(15000000000.millisToNanos(), spanStartTimeMs)
assertEquals(
mapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal class FragmentBreadcrumbDataSourceTest {
dataSource.startFragment("my_fragment")

val span = spanService.createdSpans.single()
assertEquals("screen-view", span.name)
assertEquals("view-breadcrumb", span.name)
assertEquals(EmbraceAttributes.Type.PERFORMANCE, span.type)
assertTrue(span.isRecording)
assertEquals(
Expand All @@ -53,7 +53,7 @@ internal class FragmentBreadcrumbDataSourceTest {
dataSource.endFragment("my_fragment")

val span = spanService.createdSpans.single()
assertEquals("screen-view", span.name)
assertEquals("view-breadcrumb", span.name)
assertEquals(EmbraceAttributes.Type.PERFORMANCE, span.type)
assertFalse(span.isRecording)
assertEquals(
Expand Down
Loading

0 comments on commit 687a29b

Please sign in to comment.