Skip to content

Commit

Permalink
Detect and convert nanosecond timestamps for all timestamp parameters (
Browse files Browse the repository at this point in the history
…#845)

## Goal

Use nanosecond fallback for all timestamp parameters. This is because the hosted SDKs are passing in nanosecond time because that's what iOS expects, so we'll just support it on every parameter, rather than just the ones that had previously been in nanoseconds so customers might be using it.

## Testing

Added tests in every layer
  • Loading branch information
bidetofevil committed May 15, 2024
2 parents 77cd898 + e81184c commit 30194c1
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ internal class EmbraceSpanImpl(
false
} else {
var successful: Boolean
val attemptedStartTimeMs = startTimeMs ?: openTelemetryClock.now().nanosToMillis()
val attemptedStartTimeMs = startTimeMs?.normalizeTimestampAsMillis() ?: openTelemetryClock.now().nanosToMillis()
synchronized(startedSpan) {
startedSpan.set(spanBuilder.startSpan(attemptedStartTimeMs))
successful = startedSpan.get() != null
Expand All @@ -74,7 +74,7 @@ internal class EmbraceSpanImpl(
false
} else {
var successful = false
val attemptedEndTimeMs = endTimeMs ?: openTelemetryClock.now().nanosToMillis()
val attemptedEndTimeMs = endTimeMs?.normalizeTimestampAsMillis() ?: openTelemetryClock.now().nanosToMillis()

synchronized(startedSpan) {
startedSpan.get()?.let { spanToStop ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal class EmbraceTracer(
spanService.startSpan(
name = name,
parent = parent,
startTimeMs = startTimeMs,
startTimeMs = startTimeMs?.normalizeTimestampAsMillis(),
internal = false
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ internal class InternalTracer(
}

override fun stopSpan(spanId: String, errorCode: ErrorCode?, endTimeMs: Long?): Boolean =
spanRepository.getSpan(spanId = spanId)?.stop(errorCode = errorCode, endTimeMs = endTimeMs) ?: false
spanRepository.getSpan(spanId = spanId)?.stop(
errorCode = errorCode,
endTimeMs = endTimeMs?.normalizeTimestampAsMillis()
) ?: false

override fun <T> recordSpan(
name: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,22 @@ internal class EmbraceSpanImplTest {
}
}

@Test
fun `starting and stopping span with nanosecond timestamps`() {
with(embraceSpan) {
val expectedStartTimeMs = fakeClock.now() + 99
val expectedEndTimeMs = fakeClock.now() + 505
assertTrue(start(startTimeMs = expectedStartTimeMs.millisToNanos()))
assertTrue(stop(errorCode = ErrorCode.FAILURE, endTimeMs = expectedEndTimeMs.millisToNanos()))
assertSnapshot(
expectedStartTimeMs = expectedStartTimeMs,
expectedEndTimeMs = expectedEndTimeMs,
expectedStatus = Span.Status.ERROR
)
validateStoppedSpan()
}
}

@Test
fun `check adding events`() {
with(embraceSpan) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,13 @@ internal class EmbraceTracerTest {
val parent = checkNotNull(embraceTracer.startSpan(name = "test-span"))
clock.tick(20L)
val childStartTimeMs = clock.now() - 10L
val child =
checkNotNull(embraceTracer.startSpan(name = "child-span", parent = parent, startTimeMs = childStartTimeMs))
val child = checkNotNull(
embraceTracer.startSpan(
name = "child-span",
parent = parent,
startTimeMs = childStartTimeMs,
)
)
assertTrue(parent.stop())
assertTrue(child.stop())
val spans = spanSink.flushSpans()
Expand Down Expand Up @@ -294,6 +299,26 @@ internal class EmbraceTracerTest {
}
}

@Test
fun `start and stop span with nanosecond timestamp`() {
spanSink.flushSpans()
val expectedStartTimeNanos = clock.nowInNanos()
val span = checkNotNull(
embraceTracer.startSpan(
name = "fallback-span",
parent = null,
startTimeMs = expectedStartTimeNanos
)
)
clock.tick(10L)
val expectedEndTimeNanos = clock.nowInNanos()
assertTrue(span.stop(endTimeMs = expectedEndTimeNanos))
with(verifyPublicSpan("fallback-span")) {
assertEquals(expectedStartTimeNanos, startTimeNanos)
assertEquals(expectedEndTimeNanos, endTimeNanos)
}
}

@Test
fun `recording completed spans fallback normalizes timestamps to millis when appropriate`() {
val expectedName = "test-span"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ internal class InternalTracerTest {
}
}

@Test
fun `start and stop span with nanosecond timestamp`() {
spanSink.flushSpans()
val expectedStartTimeNanos = clock.nowInNanos()
val spanId = checkNotNull(internalTracer.startSpan(name = "my-span", startTimeMs = expectedStartTimeNanos))
clock.tick(10L)
val expectedEndTimeNanos = clock.nowInNanos()
assertTrue(internalTracer.stopSpan(spanId = spanId, endTimeMs = expectedEndTimeNanos))
with(verifyPublicSpan("my-span")) {
assertEquals(expectedStartTimeNanos, startTimeNanos)
assertEquals(expectedEndTimeNanos, endTimeNanos)
}
}

@Test
fun `verify event timestamp fallback`() {
spanSink.flushSpans()
Expand Down

0 comments on commit 30194c1

Please sign in to comment.