Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instrumentation API part 9 #486

Merged
merged 9 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion android-agent/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ android {

dependencies {
implementation(project(":common"))
implementation(project(":instrumentation:startup")) // todo remove during the initializationevents adaptation work.
implementation(project(":instrumentation:common-api"))
implementation(libs.androidx.core)
implementation(libs.androidx.navigation.fragment)
implementation(libs.androidx.lifecycle.process)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
import io.opentelemetry.android.features.diskbuffering.SignalFromDiskExporter;
import io.opentelemetry.android.features.diskbuffering.scheduler.ExportScheduleHandler;
import io.opentelemetry.android.instrumentation.common.InstrumentedApplication;
import io.opentelemetry.android.instrumentation.startup.InitializationEvents;
import io.opentelemetry.android.instrumentation.startup.SdkInitializationEvents;
import io.opentelemetry.android.internal.features.networkattrs.NetworkAttributesSpanAppender;
import io.opentelemetry.android.internal.features.persistence.DiskManager;
import io.opentelemetry.android.internal.features.persistence.SimpleTemporaryFileProvider;
import io.opentelemetry.android.internal.initialization.InitializationEvents;
import io.opentelemetry.android.internal.processors.GlobalAttributesLogRecordAppender;
import io.opentelemetry.android.internal.services.CacheStorage;
import io.opentelemetry.android.internal.services.Preferences;
Expand Down Expand Up @@ -51,9 +50,7 @@
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
Expand Down Expand Up @@ -89,7 +86,6 @@ public final class OpenTelemetryRumBuilder {
(a) -> a;

private Resource resource;
private InitializationEvents initializationEvents = InitializationEvents.NO_OP;

private static TextMapPropagator buildDefaultPropagator() {
return TextMapPropagator.composite(
Expand Down Expand Up @@ -277,7 +273,8 @@ public OpenTelemetryRum build() {
}

OpenTelemetryRum build(ServiceManager serviceManager) {
applyConfiguration(serviceManager);
InitializationEvents initializationEvents = InitializationEvents.get();
applyConfiguration(serviceManager, initializationEvents);

DiskBufferingConfiguration diskBufferingConfiguration =
config.getDiskBufferingConfiguration();
Expand Down Expand Up @@ -374,18 +371,10 @@ public OpenTelemetryRumBuilder addOtelSdkReadyListener(Consumer<OpenTelemetrySdk
}

/** Leverage the configuration to wire up various instrumentation components. */
private void applyConfiguration(ServiceManager serviceManager) {
private void applyConfiguration(
ServiceManager serviceManager, InitializationEvents initializationEvents) {
if (config.shouldGenerateSdkInitializationEvents()) {
if (initializationEvents == InitializationEvents.NO_OP) {
SdkInitializationEvents sdkInitEvents = new SdkInitializationEvents();
addOtelSdkReadyListener(sdkInitEvents::finish);
initializationEvents = sdkInitEvents;
}
Map<String, String> configMap = new HashMap<>();
// TODO: Convert config to map
// breedx-splk: Left incomplete for now, because I think Cesar is making changes around
// this
initializationEvents.recordConfiguration(configMap);
initializationEvents.recordConfiguration(config);
}
initializationEvents.sdkInitializationStarted();

Expand Down Expand Up @@ -485,9 +474,4 @@ private ContextPropagators buildFinalPropagators() {
TextMapPropagator defaultPropagator = buildDefaultPropagator();
return ContextPropagators.create(propagatorCustomizer.apply(defaultPropagator));
}

OpenTelemetryRumBuilder setInitializationEvents(InitializationEvents initializationEvents) {
this.initializationEvents = initializationEvents;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.internal.initialization

import io.opentelemetry.android.config.OtelRumConfig
import io.opentelemetry.sdk.trace.export.SpanExporter
import java.util.ServiceLoader.load

/**
* This class is internal and not for public use. Its APIs are unstable and can change at any time.
*/
interface InitializationEvents {
fun sdkInitializationStarted()

fun recordConfiguration(config: OtelRumConfig)

fun currentNetworkProviderInitialized()

fun networkMonitorInitialized()

fun anrMonitorInitialized()

fun slowRenderingDetectorInitialized()

fun crashReportingInitialized()

fun spanExporterInitialized(spanExporter: SpanExporter)

companion object {
private var instance: InitializationEvents? = null

@JvmStatic
fun get(): InitializationEvents {
if (instance == null) {
val initializationEvents = load(InitializationEvents::class.java).firstOrNull()
if (initializationEvents != null) {
set(initializationEvents)
} else {
set(NO_OP)
}
}

return instance!!
}

@JvmStatic
fun set(initializationEvents: InitializationEvents) {
if (instance == null) {
instance = initializationEvents
}
}

@JvmStatic
fun resetForTest() {
instance = null
}

val NO_OP: InitializationEvents =
object : InitializationEvents {
override fun sdkInitializationStarted() {}

override fun recordConfiguration(config: OtelRumConfig) {}

override fun currentNetworkProviderInitialized() {}

override fun networkMonitorInitialized() {}

override fun anrMonitorInitialized() {}

override fun slowRenderingDetectorInitialized() {}

override fun crashReportingInitialized() {}

override fun spanExporterInitialized(spanExporter: SpanExporter) {}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import io.opentelemetry.android.features.diskbuffering.DiskBufferingConfiguration;
import io.opentelemetry.android.features.diskbuffering.SignalFromDiskExporter;
import io.opentelemetry.android.features.diskbuffering.scheduler.ExportScheduleHandler;
import io.opentelemetry.android.instrumentation.startup.InitializationEvents;
import io.opentelemetry.android.internal.initialization.InitializationEvents;
import io.opentelemetry.android.internal.services.CacheStorage;
import io.opentelemetry.android.internal.services.Preferences;
import io.opentelemetry.android.internal.services.ServiceManager;
Expand Down Expand Up @@ -105,12 +105,14 @@ public void setup() {
mocks = MockitoAnnotations.openMocks(this);
when(application.getApplicationContext()).thenReturn(applicationContext);
when(application.getMainLooper()).thenReturn(looper);
InitializationEvents.set(initializationEvents);
}

@After
public void tearDown() throws Exception {
SignalFromDiskExporter.resetForTesting();
mocks.close();
InitializationEvents.resetForTest();
}

@Test
Expand Down Expand Up @@ -302,9 +304,7 @@ public void diskBufferingEnabled() {
.build());
ArgumentCaptor<SpanExporter> exporterCaptor = ArgumentCaptor.forClass(SpanExporter.class);

OpenTelemetryRum.builder(application, config)
.setInitializationEvents(initializationEvents)
.build(serviceManager);
OpenTelemetryRum.builder(application, config).build(serviceManager);

assertThat(SignalFromDiskExporter.get()).isNotNull();
verify(scheduleHandler).enable();
Expand Down Expand Up @@ -333,9 +333,7 @@ public void diskBufferingEnabled_when_exception_thrown() {
.setExportScheduleHandler(scheduleHandler)
.build());

OpenTelemetryRum.builder(application, config)
.setInitializationEvents(initializationEvents)
.build(serviceManager);
OpenTelemetryRum.builder(application, config).build(serviceManager);

verify(initializationEvents).spanExporterInitialized(exporterCaptor.capture());
verify(scheduleHandler, never()).enable();
Expand Down Expand Up @@ -366,9 +364,7 @@ public void diskBufferingDisabled() {
.setExportScheduleHandler(scheduleHandler)
.build());

OpenTelemetryRum.builder(application, config)
.setInitializationEvents(initializationEvents)
.build();
OpenTelemetryRum.builder(application, config).build();

verify(initializationEvents).spanExporterInitialized(exporterCaptor.capture());
verify(scheduleHandler, never()).enable();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.internal.initialization

import io.mockk.mockk
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test

class InitializationEventsTest {
@AfterEach
fun tearDown() {
InitializationEvents.resetForTest()
}

@Test
fun `Verify service loading`() {
val initializationEvents = InitializationEvents.get()
assertThat(initializationEvents).isInstanceOf(TestInitializationEvents::class.java)
}

@Test
fun `Verify setting instance once`() {
val initializationEvents = mockk<InitializationEvents>()
InitializationEvents.set(initializationEvents)

assertThat(InitializationEvents.get()).isEqualTo(initializationEvents)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.internal.initialization

import io.opentelemetry.android.config.OtelRumConfig
import io.opentelemetry.sdk.trace.export.SpanExporter

class TestInitializationEvents : InitializationEvents {
override fun sdkInitializationStarted() {
}

override fun recordConfiguration(config: OtelRumConfig) {
}

override fun currentNetworkProviderInitialized() {
}

override fun networkMonitorInitialized() {
}

override fun anrMonitorInitialized() {
}

override fun slowRenderingDetectorInitialized() {
}

override fun crashReportingInitialized() {
}

override fun spanExporterInitialized(spanExporter: SpanExporter) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.opentelemetry.android.internal.initialization.TestInitializationEvents
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
id("otel.errorprone-conventions")
id("kotlin-kapt")
}

val javaVersion = rootProject.extra["java_version"] as JavaVersion
Expand Down Expand Up @@ -44,6 +45,8 @@ tasks.withType<Test> {
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
dependencies {
implementation(libs.findLibrary("findbugs-jsr305").get())
compileOnly(libs.findLibrary("auto-service-annotations").get())
kapt(libs.findLibrary("auto-service-processor").get())
testImplementation(libs.findLibrary("assertj-core").get())
testImplementation(libs.findBundle("mocking").get())
testImplementation(libs.findBundle("junit").get())
Expand Down
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ spotless = "6.25.0"
kotlin = "2.0.0"
androidPlugin = "8.5.1"
junitKtx = "1.2.1"
autoService = "1.1.1"

[libraries]
opentelemetry-platform = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom", version.ref = "opentelemetry-instrumentation" }
Expand All @@ -36,6 +37,8 @@ opentelemetry-exporter-logging = { module = "io.opentelemetry:opentelemetry-expo
opentelemetry-diskBuffering = { module = "io.opentelemetry.contrib:opentelemetry-disk-buffering", version.ref = "opentelemetry-contrib" }
opentelemetry-exporter-otlp = { module = "io.opentelemetry:opentelemetry-exporter-otlp", version.ref = "opentelemetry" }
volley = "com.android.volley:volley:1.2.1"
auto-service-annotations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "autoService" }
auto-service-processor = { module = "com.google.auto.service:auto-service", version.ref = "autoService" }

#Test tools
opentelemetry-sdk-testing = { module = "io.opentelemetry:opentelemetry-sdk-testing", version.ref = "opentelemetry" }
Expand Down
2 changes: 1 addition & 1 deletion instrumentation/startup/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ android {
dependencies {
api(platform(libs.opentelemetry.platform))
api(libs.opentelemetry.api)
api(project(":android-agent"))
api(project(":common"))
api(project(":instrumentation:common-api"))
implementation(libs.androidx.core)
implementation(libs.opentelemetry.semconv)
implementation(libs.opentelemetry.sdk)
Expand Down

This file was deleted.

Loading