Skip to content

Instantly share code, notes, and snippets.

@developersteve
Created February 8, 2024 03:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save developersteve/1af38e6ecda822dd0ce9c6376449c7a1 to your computer and use it in GitHub Desktop.
Save developersteve/1af38e6ecda822dd0ce9c6376449c7a1 to your computer and use it in GitHub Desktop.
import android.app.Application
import io.opentelemetry.android.OpenTelemetryRum
import io.opentelemetry.android.OpenTelemetryRumBuilder
import io.opentelemetry.android.RumConstants
import io.opentelemetry.android.RuntimeDetailsExtractor
import io.opentelemetry.android.config.OtelRumConfig
import io.opentelemetry.android.instrumentation.ScreenNameExtractor
import io.opentelemetry.android.instrumentation.activity.VisibleScreenTracker
import io.opentelemetry.android.instrumentation.crash.CrashReporter
import io.opentelemetry.android.instrumentation.lifecycle.AndroidLifecycleInstrumentation
import io.opentelemetry.android.instrumentation.network.CurrentNetworkProvider
import io.opentelemetry.android.instrumentation.startup.AppStartupTimer
import io.opentelemetry.api.OpenTelemetry
import io.opentelemetry.api.common.Attributes
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.sdk.resources.Resource
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter
import java.util.Objects
import java.util.function.Function
/**
* Singleton object responsible for initializing and configuring with OpenTelemetry RUM.
*/
object RumInitializer {
private var openTelemetryRum: OpenTelemetryRum? = null
/**
* Initializes with OpenTelemetry RUM.
*
* @param application The application context.
*/
fun init(application: Application){
// Create instances needed for initialization
val visibleScreenTracker = VisibleScreenTracker()
val config = OtelRumConfig().apply {
// Set global attributes
setGlobalAttributes(
Attributes.builder()
.put("vendor", "RUM")
.put("1.0", "v1")
.build()
)
}
// Build OpenTelemetryRum instance
val openTelemetryRumBuilder = OpenTelemetryRum.builder(application, config).apply {
mergeResource(createResource())
setCurrentNetworkProvider(CurrentNetworkProvider.createAndStart(application))
addTracerProviderCustomizer { tracerProviderBuilder: SdkTracerProviderBuilder, app: Application? ->
val otlpExporter = OtlpGrpcSpanExporter.builder()
.setEndpoint("https://ga-otlp.lumigo-tracer-edge.golumigo.com") // Set your collector endpoint here
.addHeader("Authorization", "token in here") // Set your authorization token here
.build()
val batchSpanProcessor = BatchSpanProcessor.builder(otlpExporter).build()
tracerProviderBuilder.addSpanProcessor(batchSpanProcessor)
}
addInstrumentation { instrumentedApplication ->
// Install CrashReporter
CrashReporter.builder()
.addAttributesExtractor(
RuntimeDetailsExtractor.create(
instrumentedApplication
.application
.applicationContext
)
)
.build()
.installOn(instrumentedApplication)
}
// Install lifecycle instrumentations
installLifecycleInstrumentations(this, visibleScreenTracker)
}
openTelemetryRum = openTelemetryRumBuilder.build().apply {
}
}
/**
* Install lifecycle instrumentations for OpenTelemetryRumBuilder.
*
* @param otelRumBuilder The OpenTelemetryRumBuilder instance.
* @param visibleScreenTracker The VisibleScreenTracker instance.
*/
private fun installLifecycleInstrumentations(
otelRumBuilder: OpenTelemetryRumBuilder,
visibleScreenTracker: VisibleScreenTracker
) {
otelRumBuilder.addInstrumentation { instrumentedApp ->
val tracerCustomizer = Function<Tracer, Tracer?> { tracer ->
Tracer { spanName ->
val component = if (spanName == RumConstants.APP_START_SPAN_NAME) "appstart" else "ui"
tracer.spanBuilder(spanName)
.setAttribute("COMPONENT_KEY", component)
}
}
val instrumentation = AndroidLifecycleInstrumentation.builder()
.setVisibleScreenTracker(visibleScreenTracker)
.setStartupTimer(AppStartupTimer())
.setTracerCustomizer(tracerCustomizer)
.setScreenNameExtractor(ScreenNameExtractor.DEFAULT)
.build()
// Install lifecycle instrumentations
instrumentation.installOn(instrumentedApp)
}
}
/**
* Get the initialized OpenTelemetryRum instance.
*
* @return The OpenTelemetryRum instance.
*/
fun getOpenTelemetryRum(): OpenTelemetryRum? = openTelemetryRum
/**
* Get the OpenTelemetry instance from the initialized OpenTelemetryRum.
*
* @return The OpenTelemetry instance.
*/
fun getOpenTelemetry(): OpenTelemetry? = openTelemetryRum?.openTelemetry
/**
* Get the Tracer instance from the initialized OpenTelemetry.
*
* @return The Tracer instance.
*/
fun getTracer(): Tracer? = getOpenTelemetry()?.getTracer("RumInitializer")
/**
* Create a Resource for OpenTelemetry with application name and environment.
*
* @return The Resource instance.
*/
private fun createResource(): Resource {
val applicationName = Objects.requireNonNull<String>("TEST Example")
return Resource.getDefault().toBuilder()
.put("APP_NAME_KEY", "com.example.oteltest")
.put("DEPLOYMENT_ENVIRONMENT", "app demo")
.build()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment