Skip to content

Commit 26955af

Browse files
committed
feat: alter default clock implementation
1 parent d29c7f6 commit 26955af

File tree

10 files changed

+79
-24
lines changed

10 files changed

+79
-24
lines changed

android-agent/src/main/kotlin/io/opentelemetry/android/agent/dsl/OpenTelemetryConfiguration.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.android.agent.dsl
77

88
import io.opentelemetry.android.Incubating
9+
import io.opentelemetry.android.OtelAndroidClock
910
import io.opentelemetry.android.agent.dsl.instrumentation.InstrumentationConfiguration
1011
import io.opentelemetry.android.config.OtelRumConfig
1112
import io.opentelemetry.android.features.diskbuffering.DiskBufferingConfig
@@ -19,6 +20,10 @@ import io.opentelemetry.sdk.common.Clock
1920
@OpenTelemetryDslMarker
2021
class OpenTelemetryConfiguration internal constructor(
2122
internal val rumConfig: OtelRumConfig = OtelRumConfig(),
23+
/**
24+
* Configures the [Clock] used for capturing telemetry.
25+
*/
26+
var clock: Clock = OtelAndroidClock(),
2227
) {
2328
internal val exportConfig = HttpExportConfiguration()
2429
internal val sessionConfig = SessionConfiguration()
@@ -29,11 +34,6 @@ class OpenTelemetryConfiguration internal constructor(
2934
diskBuffering {}
3035
}
3136

32-
/**
33-
* Configures the [Clock] used for capturing telemetry.
34-
*/
35-
var clock: Clock = Clock.getDefault()
36-
3737
/**
3838
* Configures how OpenTelemetry should export telemetry over HTTP.
3939
*/
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.android.agent
7+
8+
import io.opentelemetry.sdk.common.Clock
9+
10+
class FakeClock : Clock {
11+
override fun now(): Long = 0
12+
13+
override fun nanoTime(): Long = 0
14+
}

android-agent/src/test/kotlin/io/opentelemetry/android/agent/dsl/ClockConfigTest.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@
55

66
package io.opentelemetry.android.agent.dsl
77

8-
import io.opentelemetry.sdk.common.Clock
8+
import androidx.test.ext.junit.runners.AndroidJUnit4
9+
import io.opentelemetry.android.OtelAndroidClock
10+
import io.opentelemetry.android.agent.FakeClock
911
import org.junit.Assert.assertSame
12+
import org.junit.Assert.assertTrue
1013
import org.junit.Test
14+
import org.junit.runner.RunWith
1115

16+
@RunWith(AndroidJUnit4::class)
1217
class ClockConfigTest {
1318
@Test
1419
fun testDefaults() {
1520
val otelConfig = OpenTelemetryConfiguration()
16-
assertSame(Clock.getDefault(), otelConfig.clock)
21+
assertTrue(otelConfig.clock is OtelAndroidClock)
1722
}
1823

1924
@Test
2025
fun testOverride() {
21-
val fakeClock =
22-
object : Clock {
23-
override fun now(): Long = 0
24-
25-
override fun nanoTime(): Long = 0
26-
}
26+
val fakeClock = FakeClock()
2727
val otelConfig =
2828
OpenTelemetryConfiguration().apply {
2929
clock = fakeClock

android-agent/src/test/kotlin/io/opentelemetry/android/agent/dsl/DiskBufferingConfigTest.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.android.agent.dsl
77

8+
import io.opentelemetry.android.agent.FakeClock
89
import io.opentelemetry.android.config.OtelRumConfig
910
import io.opentelemetry.android.features.diskbuffering.DiskBufferingConfig
1011
import org.junit.Assert.assertFalse
@@ -14,14 +15,14 @@ import org.junit.Test
1415
class DiskBufferingConfigTest {
1516
@Test
1617
fun testDefaults() {
17-
val otelConfig = OpenTelemetryConfiguration()
18+
val otelConfig = OpenTelemetryConfiguration(clock = FakeClock())
1819
assertTrue(otelConfig.diskBufferingConfig.enabled)
1920
assertTrue(otelConfig.rumConfig.getDiskBufferingConfig().enabled)
2021
}
2122

2223
@Test
2324
fun testOverride() {
24-
val otelConfig = OpenTelemetryConfiguration()
25+
val otelConfig = OpenTelemetryConfiguration(clock = FakeClock())
2526
otelConfig.diskBuffering {
2627
enabled(false)
2728
}
@@ -36,6 +37,7 @@ class DiskBufferingConfigTest {
3637
OtelRumConfig().setDiskBufferingConfig(
3738
DiskBufferingConfig.create(enabled = true),
3839
),
40+
FakeClock(),
3941
)
4042
assertTrue(otelConfig.diskBufferingConfig.enabled)
4143
assertTrue(otelConfig.rumConfig.getDiskBufferingConfig().enabled)

android-agent/src/test/kotlin/io/opentelemetry/android/agent/dsl/GlobalAttributesConfigTest.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55

66
package io.opentelemetry.android.agent.dsl
77

8+
import io.opentelemetry.android.agent.FakeClock
89
import io.opentelemetry.api.common.Attributes
910
import org.junit.Assert.assertEquals
1011
import org.junit.Test
1112

1213
class GlobalAttributesConfigTest {
1314
@Test
1415
fun testDefaults() {
15-
val otelConfig = OpenTelemetryConfiguration()
16+
val otelConfig = OpenTelemetryConfiguration(clock = FakeClock())
1617
val attrs = otelConfig.rumConfig.getGlobalAttributesSupplier().get()
1718
assertEquals(Attributes.empty(), attrs)
1819
}
@@ -21,7 +22,7 @@ class GlobalAttributesConfigTest {
2122
fun testOverride() {
2223
val expectedAttrs = Attributes.builder().put("key", "value").build()
2324
val otelConfig =
24-
OpenTelemetryConfiguration().apply {
25+
OpenTelemetryConfiguration(clock = FakeClock()).apply {
2526
globalAttributes {
2627
expectedAttrs
2728
}

android-agent/src/test/kotlin/io/opentelemetry/android/agent/dsl/HttpExportConfigurationTest.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,23 @@
55

66
package io.opentelemetry.android.agent.dsl
77

8+
import io.opentelemetry.android.agent.FakeClock
89
import io.opentelemetry.android.agent.connectivity.Compression
910
import io.opentelemetry.android.agent.connectivity.HttpEndpointConnectivity
11+
import org.junit.Before
1012
import org.junit.Test
1113
import org.junit.jupiter.api.Assertions.assertEquals
1214

1315
internal class HttpExportConfigurationTest {
16+
private lateinit var otelConfig: OpenTelemetryConfiguration
17+
18+
@Before
19+
fun setUp() {
20+
otelConfig = OpenTelemetryConfiguration(clock = FakeClock())
21+
}
22+
1423
@Test
1524
fun testDefaults() {
16-
val otelConfig = OpenTelemetryConfiguration()
1725
val config = otelConfig.exportConfig
1826
val expectedHeaders = emptyMap<String, String>()
1927
val expectedCompression = Compression.GZIP
@@ -31,7 +39,6 @@ internal class HttpExportConfigurationTest {
3139

3240
@Test
3341
fun testBaseValueOverride() {
34-
val otelConfig = OpenTelemetryConfiguration()
3542
val url = "http://localhost:4318/"
3643
val headers = mapOf("my-header" to "my-value")
3744
val config =
@@ -49,7 +56,6 @@ internal class HttpExportConfigurationTest {
4956

5057
@Test
5158
fun testIndividualEndpointOverrides() {
52-
val otelConfig = OpenTelemetryConfiguration()
5359
val baseUrl = "http://localhost:4318/"
5460
val baseHeaders = mapOf("my-header" to "my-value")
5561

@@ -107,7 +113,6 @@ internal class HttpExportConfigurationTest {
107113

108114
@Test
109115
fun testIndividualEndpointOverrides2() {
110-
val otelConfig = OpenTelemetryConfiguration()
111116
val baseUrl = "http://localhost:4318/"
112117
val baseHeaders = mapOf("my-header" to "my-value")
113118

android-agent/src/test/kotlin/io/opentelemetry/android/agent/dsl/SessionConfigurationTest.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.android.agent.dsl
77

8+
import io.opentelemetry.android.agent.FakeClock
89
import org.junit.Test
910
import org.junit.jupiter.api.Assertions.assertEquals
1011
import kotlin.time.Duration.Companion.hours
@@ -13,7 +14,7 @@ import kotlin.time.Duration.Companion.minutes
1314
internal class SessionConfigurationTest {
1415
@Test
1516
fun testDefaults() {
16-
val otelConfig = OpenTelemetryConfiguration()
17+
val otelConfig = OpenTelemetryConfiguration(clock = FakeClock())
1718
assertEquals(15.minutes, otelConfig.sessionConfig.backgroundInactivityTimeout)
1819
assertEquals(4.hours, otelConfig.sessionConfig.maxLifetime)
1920
}
@@ -23,7 +24,7 @@ internal class SessionConfigurationTest {
2324
val customTimeout = 30.minutes
2425
val customLifetime = 2.hours
2526
val otelConfig =
26-
OpenTelemetryConfiguration().apply {
27+
OpenTelemetryConfiguration(clock = FakeClock()).apply {
2728
session {
2829
backgroundInactivityTimeout = customTimeout
2930
maxLifetime = customLifetime

core/api/core.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ public final class io/opentelemetry/android/OpenTelemetryRumBuilder$Companion {
3434
public final fun create (Landroid/content/Context;Lio/opentelemetry/android/config/OtelRumConfig;)Lio/opentelemetry/android/OpenTelemetryRumBuilder;
3535
}
3636

37+
public final class io/opentelemetry/android/OtelAndroidClock : io/opentelemetry/sdk/common/Clock {
38+
public fun <init> ()V
39+
public fun nanoTime ()J
40+
public fun now ()J
41+
}
42+
3743
public final class io/opentelemetry/android/RumBuilder {
3844
public static final field INSTANCE Lio/opentelemetry/android/RumBuilder;
3945
public static final fun builder (Landroid/content/Context;)Lio/opentelemetry/android/OpenTelemetryRumBuilder;

core/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class OpenTelemetryRumBuilder internal constructor(
9292
): OpenTelemetryRumBuilder = OpenTelemetryRumBuilder(context, config)
9393
}
9494

95-
private var clock: Clock = Clock.getDefault()
95+
private var clock: Clock = OtelAndroidClock()
9696
private val tracerProviderCustomizers: MutableList<BiFunction<SdkTracerProviderBuilder, Context, SdkTracerProviderBuilder>> =
9797
mutableListOf()
9898
private val meterProviderCustomizers: MutableList<BiFunction<SdkMeterProviderBuilder, Context, SdkMeterProviderBuilder>> =
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.android
7+
8+
import android.os.SystemClock
9+
import io.opentelemetry.sdk.common.Clock
10+
11+
/**
12+
* An implementation of [Clock] that takes a baseline by subtracting
13+
* [SystemClock.elapsedRealtimeNanos] from [System.currentTimeMillis] and then
14+
* adds that baseline to [SystemClock.elapsedRealtimeNanos] to provide a monotonic wall-clock time.
15+
*
16+
* This avoids the downside of [System.currentTimeMillis] not being monotonic on Android (i.e.
17+
* the clock doesn't consistently tick when the process is in the backround or cached). It also
18+
* avoids the problem of [SystemClock.elapsedRealtimeNanos] not providing wall-clock time.
19+
*/
20+
class OtelAndroidClock : Clock {
21+
private val baseline = System.currentTimeMillis() - nanoTime()
22+
23+
override fun now(): Long = baseline + nanoTime()
24+
25+
override fun nanoTime(): Long = SystemClock.elapsedRealtimeNanos()
26+
}

0 commit comments

Comments
 (0)