-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a7b954f
commit 5c198c4
Showing
6 changed files
with
243 additions
and
0 deletions.
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
...ace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/payload/Attribute.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package io.embrace.android.embracesdk.internal.payload | ||
|
||
import com.squareup.moshi.Json | ||
import com.squareup.moshi.JsonClass | ||
|
||
/** | ||
* A key-value pair that provides additional context to the span | ||
* | ||
* @param key The name of the attribute | ||
* @param data The value of the attribute | ||
*/ | ||
@JsonClass(generateAdapter = true) | ||
internal data class Attribute( | ||
|
||
/* The name of the attribute */ | ||
@Json(name = "key") | ||
val key: String? = null, | ||
|
||
/* The value of the attribute */ | ||
@Json(name = "value") | ||
val data: String? = null | ||
) |
73 changes: 73 additions & 0 deletions
73
embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/payload/Span.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package io.embrace.android.embracesdk.internal.payload | ||
|
||
import com.squareup.moshi.Json | ||
import com.squareup.moshi.JsonClass | ||
|
||
/** | ||
* A span represents a single unit of work done in the app. It can be a network request, a database | ||
* query, a view transition, etc. It has a start time, an end time, and attributes that describe it. | ||
* | ||
* @param traceId The ID of the trace that this span is part of | ||
* @param spanId A value that uniquely identifies a span instance | ||
* @param parentSpanId A value that uniquely identifies the parent span | ||
* @param name The name of the span | ||
* @param startTimeUnixNano The time the span started, in nanoseconds since the Unix epoch | ||
* @param endTimeUnixNano The time the span ended, in nanoseconds since the Unix epoch | ||
* @param status The status of the span. Can be one of 'Unset', 'Error', or 'Ok' | ||
* @param events | ||
* @param attributes | ||
*/ | ||
@JsonClass(generateAdapter = true) | ||
internal data class Span( | ||
|
||
/* The ID of the trace that this span is part of */ | ||
@Json(name = "trace_id") | ||
val traceId: String? = null, | ||
|
||
/* A value that uniquely identifies a span instance */ | ||
@Json(name = "span_id") | ||
val spanId: String? = null, | ||
|
||
/* A value that uniquely identifies the parent span */ | ||
@Json(name = "parent_span_id") | ||
val parentSpanId: String? = null, | ||
|
||
/* The name of the span */ | ||
@Json(name = "name") | ||
val name: String? = null, | ||
|
||
/* The time the span started, in nanoseconds since the Unix epoch */ | ||
@Json(name = "start_time_unix_nano") | ||
val startTimeUnixNano: Long? = null, | ||
|
||
/* The time the span ended, in nanoseconds since the Unix epoch */ | ||
@Json(name = "end_time_unix_nano") | ||
val endTimeUnixNano: Long? = null, | ||
|
||
/* The status of the span. Can be one of 'Unset', 'Error', or 'Ok' */ | ||
@Json(name = "status") | ||
val status: Status? = null, | ||
|
||
@Json(name = "events") | ||
val events: List<SpanEvent>? = null, | ||
|
||
@Json(name = "attributes") | ||
val attributes: List<Attribute>? = null | ||
) { | ||
|
||
/** | ||
* The status of the span. Can be one of 'Unset', 'Error', or 'Ok' | ||
* | ||
* Values: UNSET,ERROR,OK | ||
*/ | ||
internal enum class Status(val value: String) { | ||
@Json(name = "Unset") | ||
UNSET("Unset"), | ||
|
||
@Json(name = "Error") | ||
ERROR("Error"), | ||
|
||
@Json(name = "Ok") | ||
OK("Ok") | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...ace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/payload/SpanEvent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package io.embrace.android.embracesdk.internal.payload | ||
|
||
import com.squareup.moshi.Json | ||
import com.squareup.moshi.JsonClass | ||
|
||
/** | ||
* An event that occurred during a span | ||
* | ||
* @param name The name of the event | ||
* @param timeUnixNano The time the event occurred, in nanoseconds since the Unix epoch | ||
* @param attributes | ||
*/ | ||
@JsonClass(generateAdapter = true) | ||
internal data class SpanEvent( | ||
|
||
/* The name of the event */ | ||
@Json(name = "name") | ||
val name: String? = null, | ||
|
||
/* The time the event occurred, in nanoseconds since the Unix epoch */ | ||
@Json(name = "time_unix_nano") | ||
val timeUnixNano: Long? = null, | ||
|
||
@Json(name = "attributes") | ||
val attributes: List<Attribute>? = null | ||
) |
32 changes: 32 additions & 0 deletions
32
...ce-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/payload/SpanMapper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package io.embrace.android.embracesdk.internal.payload | ||
|
||
import io.opentelemetry.api.common.Attributes | ||
import io.opentelemetry.api.trace.StatusCode | ||
import io.opentelemetry.sdk.trace.data.EventData | ||
import io.opentelemetry.sdk.trace.data.SpanData | ||
|
||
internal fun SpanData.toNewPayload() = Span( | ||
traceId = traceId, | ||
spanId = spanId, | ||
parentSpanId = parentSpanId, | ||
name = name, | ||
startTimeUnixNano = startEpochNanos, | ||
endTimeUnixNano = endEpochNanos, | ||
status = when (status.statusCode) { | ||
StatusCode.UNSET -> Span.Status.UNSET | ||
StatusCode.OK -> Span.Status.OK | ||
StatusCode.ERROR -> Span.Status.ERROR | ||
else -> Span.Status.UNSET | ||
Check warning on line 19 in embrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/payload/SpanMapper.kt Codecov / codecov/patchembrace-android-sdk/src/main/java/io/embrace/android/embracesdk/internal/payload/SpanMapper.kt#L17-L19
|
||
}, | ||
events = events.map(EventData::toNewPayload), | ||
attributes = attributes.toNewPayload() | ||
) | ||
|
||
internal fun EventData.toNewPayload() = SpanEvent( | ||
name = name, | ||
timeUnixNano = epochNanos, | ||
attributes = attributes.toNewPayload() | ||
) | ||
|
||
internal fun Attributes.toNewPayload(): List<Attribute> = | ||
asMap().map { (key, value) -> Attribute(key.key, value.toString()) } |
49 changes: 49 additions & 0 deletions
49
embrace-android-sdk/src/test/java/io/embrace/android/embracesdk/fakes/FakeSpanData.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package io.embrace.android.embracesdk.fakes | ||
|
||
import io.opentelemetry.api.common.Attributes | ||
import io.opentelemetry.api.trace.SpanContext | ||
import io.opentelemetry.api.trace.SpanKind | ||
import io.opentelemetry.sdk.common.InstrumentationLibraryInfo | ||
import io.opentelemetry.sdk.resources.Resource | ||
import io.opentelemetry.sdk.trace.data.EventData | ||
import io.opentelemetry.sdk.trace.data.LinkData | ||
import io.opentelemetry.sdk.trace.data.SpanData | ||
import io.opentelemetry.sdk.trace.data.StatusData | ||
|
||
internal class FakeSpanData( | ||
private var name: String = "fake-span", | ||
private var kind: SpanKind = SpanKind.INTERNAL, | ||
private var spanContext: SpanContext = SpanContext.getInvalid(), | ||
private var parentSpanContext: SpanContext = SpanContext.getInvalid(), | ||
private var status: StatusData = StatusData.unset(), | ||
private var startEpochNanos: Long = 0L, | ||
private var attributes: Attributes = Attributes.builder().put("my-key", "my-value").build(), | ||
private var events: MutableList<EventData> = mutableListOf( | ||
EventData.create( | ||
0L, | ||
"fake-event", | ||
Attributes.builder().put("my-key", "my-value").build() | ||
) | ||
), | ||
private var links: MutableList<LinkData> = mutableListOf(), | ||
private var endEpochNanos: Long = 0L, | ||
private var hasEnded: Boolean = true, | ||
private var resource: Resource = Resource.empty() | ||
) : SpanData { | ||
override fun getName(): String = name | ||
override fun getKind(): SpanKind = kind | ||
override fun getSpanContext(): SpanContext = spanContext | ||
override fun getParentSpanContext(): SpanContext = parentSpanContext | ||
override fun getStatus(): StatusData = status | ||
override fun getStartEpochNanos(): Long = startEpochNanos | ||
override fun getAttributes(): Attributes = attributes | ||
override fun getEvents(): MutableList<EventData> = events | ||
override fun getLinks(): MutableList<LinkData> = links | ||
override fun getEndEpochNanos(): Long = endEpochNanos | ||
override fun hasEnded(): Boolean = hasEnded | ||
override fun getTotalRecordedEvents(): Int = events.size | ||
override fun getTotalRecordedLinks(): Int = links.size | ||
override fun getTotalAttributeCount(): Int = attributes.size() | ||
override fun getInstrumentationLibraryInfo() = InstrumentationLibraryInfo.empty() | ||
override fun getResource(): Resource = resource | ||
} |
41 changes: 41 additions & 0 deletions
41
...ndroid-sdk/src/test/java/io/embrace/android/embracesdk/internal/payload/SpanMapperTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package io.embrace.android.embracesdk.internal.payload | ||
|
||
import io.embrace.android.embracesdk.fakes.FakeSpanData | ||
import io.opentelemetry.sdk.trace.data.SpanData | ||
import org.junit.Assert.assertEquals | ||
import org.junit.Test | ||
|
||
internal class SpanMapperTest { | ||
|
||
@Test | ||
fun toSpan() { | ||
val input: SpanData = FakeSpanData() | ||
val output = input.toNewPayload() | ||
|
||
assertEquals(input.traceId, output.traceId) | ||
assertEquals(input.spanId, output.spanId) | ||
assertEquals(input.parentSpanId, output.parentSpanId) | ||
assertEquals(input.name, output.name) | ||
assertEquals(input.startEpochNanos, output.startTimeUnixNano) | ||
assertEquals(input.endEpochNanos, output.endTimeUnixNano) | ||
assertEquals(input.status.statusCode.name, checkNotNull(output.status).name) | ||
|
||
// validate event copied | ||
val inputEvent = input.events.single() | ||
val outputEvent = checkNotNull(output.events).single() | ||
assertEquals(inputEvent.name, outputEvent.name) | ||
assertEquals(inputEvent.epochNanos, outputEvent.timeUnixNano) | ||
|
||
// test event attributes | ||
val inputEventAttrs = checkNotNull(inputEvent.attributes?.asMap()) | ||
val outputEventAttrs = checkNotNull(outputEvent.attributes?.single()) | ||
assertEquals(inputEventAttrs.keys.single().key, outputEventAttrs.key) | ||
assertEquals(inputEventAttrs.values.single(), outputEventAttrs.data) | ||
|
||
// test attributes | ||
val inputAttrs = checkNotNull(input.attributes?.asMap()) | ||
val outputAttrs = checkNotNull(output.attributes?.single()) | ||
assertEquals(inputAttrs.keys.single().key, outputAttrs.key) | ||
assertEquals(inputAttrs.values.single(), outputAttrs.data) | ||
} | ||
} |