Skip to content

Commit dd4ee16

Browse files
Merge pull request #2625 from DataDog/aleksandr-gringauz/RUM-9508/logs-scenarios
RUM-9508: LogsCustom scenario for android benchmark app
2 parents 0e0e229 + 673b991 commit dd4ee16

33 files changed

+1373
-322
lines changed

gradle/libs.versions.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@ androidXConstraintLayout = "2.0.4"
2020
androidXCore = "1.3.1"
2121
androidXFragment = "1.2.4"
2222
androidXLeanback = "1.0.0"
23+
androidXLifecycleRuntimeCompose = "2.8.7"
2324
androidXMetrics = "1.0.0-beta02"
2425
androidXMultidex = "2.0.1"
2526
androidXNavigation = "2.7.7"
2627
androidXRecyclerView = "1.3.2"
2728
androidXWorkManager = "2.8.1" # Next version will bring coroutines
2829
googleAccompanist = "0.20.2"
2930
googleMaterial = "1.3.0"
31+
dagger = "2.56.2"
3032

3133
# DD-TRACE-OT
3234
openTracing = "0.32.0"
@@ -144,6 +146,9 @@ androidXNavigationFragment = { module = "androidx.navigation:navigation-fragment
144146
androidXNavigationRuntime = { module = "androidx.navigation:navigation-runtime", version.ref = "androidXNavigation" }
145147
androidXRecyclerView = { module = "androidx.recyclerview:recyclerview", version.ref = "androidXRecyclerView" }
146148
androidXWorkManager = { module = "androidx.work:work-runtime", version.ref = "androidXWorkManager" }
149+
androidXLifecycleCompose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidXLifecycleRuntimeCompose" }
150+
daggerLib = { module = "com.google.dagger:dagger", version.ref = "dagger" }
151+
daggerCompiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" }
147152
googleAccompanistAppCompatTheme = { module = "com.google.accompanist:accompanist-appcompat-theme", version.ref = "googleAccompanist" }
148153
googleAccompanistPager = { module = "com.google.accompanist:accompanist-pager", version.ref = "googleAccompanist" }
149154
googleAccompanistPagerIndicators = { module = "com.google.accompanist:accompanist-pager-indicators", version.ref = "googleAccompanist" }

sample/benchmark/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,17 @@ dependencies {
8787
implementation(libs.bundles.androidXNavigation)
8888
implementation(libs.androidXAppCompat)
8989
implementation(libs.androidXConstraintLayout)
90+
implementation(libs.androidXLifecycleCompose)
9091
implementation(libs.googleMaterial)
9192
implementation(libs.glideCore)
93+
implementation(libs.material3Android)
9294
implementation(libs.timber)
9395
implementation(platform(libs.androidXComposeBom))
9496
implementation(libs.bundles.androidXCompose)
9597
implementation(libs.coilCompose)
98+
implementation(libs.daggerLib)
99+
kapt(libs.daggerCompiler)
100+
implementation(libs.coroutinesCore)
96101
implementation(project(":features:dd-sdk-android-logs"))
97102
implementation(project(":features:dd-sdk-android-rum"))
98103
implementation(project(":features:dd-sdk-android-trace"))

sample/benchmark/src/main/java/com/datadog/benchmark/sample/BenchmarkApplication.kt

Lines changed: 16 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -6,102 +6,28 @@
66

77
package com.datadog.benchmark.sample
88

9-
import android.annotation.SuppressLint
109
import android.app.Application
11-
import android.util.Log
12-
import com.datadog.android.Datadog
13-
import com.datadog.android.compose.enableComposeActionTracking
14-
import com.datadog.android.core.configuration.BackPressureMitigation
15-
import com.datadog.android.core.configuration.BackPressureStrategy
16-
import com.datadog.android.core.configuration.BatchSize
17-
import com.datadog.android.core.configuration.Configuration
18-
import com.datadog.android.core.configuration.UploadFrequency
19-
import com.datadog.android.privacy.TrackingConsent
20-
import com.datadog.android.rum.Rum
21-
import com.datadog.android.rum.RumConfiguration
22-
import com.datadog.android.rum.tracking.NavigationViewTrackingStrategy
23-
import com.datadog.sample.benchmark.BuildConfig
24-
import com.datadog.sample.benchmark.R
10+
import androidx.annotation.Keep
11+
import com.datadog.android.api.SdkCore
12+
import com.datadog.benchmark.sample.di.app.BenchmarkAppComponent
13+
import com.datadog.benchmark.sample.di.app.DaggerBenchmarkAppComponent
14+
import javax.inject.Inject
2515

2616
internal class BenchmarkApplication : Application() {
2717

28-
override fun onCreate() {
29-
super.onCreate()
30-
initDatadogSdk()
31-
}
32-
33-
private fun initDatadogSdk() {
34-
Datadog.initialize(
35-
this,
36-
createDatadogConfiguration(),
37-
TrackingConsent.GRANTED
38-
)
39-
val rumConfig = createRumConfiguration()
40-
Rum.enable(rumConfig)
41-
}
42-
43-
private fun createRumConfiguration(): RumConfiguration {
44-
return RumConfiguration.Builder(BuildConfig.BENCHMARK_RUM_APPLICATION_ID)
45-
.useViewTrackingStrategy(
46-
NavigationViewTrackingStrategy(
47-
R.id.nav_host_fragment,
48-
true,
49-
BenchmarkNavigationPredicate()
50-
)
51-
)
52-
.setTelemetrySampleRate(SAMPLE_RATE_TELEMETRY)
53-
.trackUserInteractions()
54-
.trackLongTasks(THRESHOLD_LONG_TASK_INTERVAL)
55-
.trackNonFatalAnrs(true)
56-
.setViewEventMapper { event ->
57-
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
58-
event
59-
}
60-
.setActionEventMapper { event ->
61-
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
62-
event
63-
}
64-
.setResourceEventMapper { event ->
65-
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
66-
event
67-
}
68-
.setErrorEventMapper { event ->
69-
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
70-
event
71-
}
72-
.setLongTaskEventMapper { event ->
73-
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
74-
event
75-
}
76-
.enableComposeActionTracking()
77-
.build()
78-
}
79-
80-
@SuppressLint("LogNotTimber")
81-
private fun createDatadogConfiguration(): Configuration {
82-
val configBuilder = Configuration.Builder(
83-
clientToken = BuildConfig.BENCHMARK_CLIENT_TOKEN,
84-
env = BuildConfig.BUILD_TYPE
85-
)
86-
.setBatchSize(BatchSize.SMALL)
87-
.setUploadFrequency(UploadFrequency.FREQUENT)
18+
internal lateinit var benchmarkAppComponent: BenchmarkAppComponent
8819

89-
configBuilder.setBackpressureStrategy(
90-
BackPressureStrategy(
91-
CAPACITY_BACK_PRESSURE_STRATEGY,
92-
{ Log.w("BackPressure", "THRESHOLD REACHED!") },
93-
{ Log.e("BackPressure", "ITEM DROPPED $it!") },
94-
BackPressureMitigation.IGNORE_NEWEST
95-
)
96-
)
20+
@Inject
21+
@Keep
22+
internal lateinit var sdkCore: SdkCore
9723

98-
return configBuilder.build()
99-
}
24+
override fun onCreate() {
25+
super.onCreate()
10026

101-
companion object {
102-
private const val ATTR_IS_MAPPED = "is_mapped"
103-
private const val SAMPLE_RATE_TELEMETRY = 100f
104-
private const val THRESHOLD_LONG_TASK_INTERVAL = 250L
105-
private const val CAPACITY_BACK_PRESSURE_STRATEGY = 32
27+
benchmarkAppComponent = DaggerBenchmarkAppComponent.factory().create(this)
28+
benchmarkAppComponent.inject(this)
10629
}
10730
}
31+
32+
internal val Application.benchmarkAppComponent: BenchmarkAppComponent
33+
get() = (this as BenchmarkApplication).benchmarkAppComponent
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.benchmark.sample
8+
9+
import com.datadog.android.api.SdkCore
10+
import com.datadog.android.compose.enableComposeActionTracking
11+
import com.datadog.android.log.Logs
12+
import com.datadog.android.log.LogsConfiguration
13+
import com.datadog.android.rum.Rum
14+
import com.datadog.android.rum.RumConfiguration
15+
import com.datadog.android.rum.tracking.NavigationViewTrackingStrategy
16+
import com.datadog.android.sessionreplay.SessionReplay
17+
import com.datadog.android.sessionreplay.SessionReplayConfiguration
18+
import com.datadog.android.sessionreplay.SessionReplayPrivacy
19+
import com.datadog.android.sessionreplay.compose.ComposeExtensionSupport
20+
import com.datadog.android.sessionreplay.material.MaterialExtensionSupport
21+
import com.datadog.benchmark.sample.config.BenchmarkConfig
22+
import com.datadog.benchmark.sample.config.SyntheticsRun
23+
import com.datadog.benchmark.sample.config.SyntheticsScenario
24+
import com.datadog.benchmark.sample.navigation.BenchmarkNavigationPredicate
25+
import com.datadog.sample.benchmark.BuildConfig
26+
import com.datadog.sample.benchmark.R
27+
import javax.inject.Inject
28+
import javax.inject.Singleton
29+
30+
/**
31+
* The general recommendation is to initialize all the components at the Application.onCreate
32+
* to have all the observability as early as possible. However in the Benchmark app we know what features
33+
* we need only in [MainActivity.onCreate], it depends on the [SyntheticsScenario] which is derived from intent extras.
34+
*/
35+
@Singleton
36+
@Suppress("TooManyFunctions")
37+
internal class DatadogFeaturesInitializer @Inject constructor(
38+
private val sdkCore: SdkCore
39+
) {
40+
private var isInitialized = false
41+
fun initialize(config: BenchmarkConfig) {
42+
if (isInitialized) {
43+
return
44+
}
45+
isInitialized = true
46+
47+
if (needToEnableRum(config)) {
48+
enableRum()
49+
}
50+
51+
if (needToEnableLogs(config)) {
52+
enableLogs()
53+
}
54+
55+
if (needToEnableSessionReplay(config)) {
56+
enableSessionReplay()
57+
}
58+
}
59+
60+
private fun needToEnableSessionReplay(config: BenchmarkConfig): Boolean {
61+
return isInstrumentedRun(config) && isSessionReplayScenario(config)
62+
}
63+
64+
@Suppress("DEPRECATION")
65+
private fun enableSessionReplay() {
66+
val sessionReplayConfig = SessionReplayConfiguration
67+
.Builder(SAMPLE_IN_ALL_SESSIONS)
68+
.setPrivacy(SessionReplayPrivacy.ALLOW)
69+
.addExtensionSupport(MaterialExtensionSupport())
70+
.addExtensionSupport(ComposeExtensionSupport())
71+
.build()
72+
73+
SessionReplay.enable(sessionReplayConfig, sdkCore)
74+
}
75+
76+
private fun needToEnableLogs(config: BenchmarkConfig): Boolean {
77+
return isInstrumentedRun(config) && isLogsScenario(config)
78+
}
79+
80+
private fun enableLogs() {
81+
val logsConfig = LogsConfiguration.Builder().build()
82+
Logs.enable(logsConfig, sdkCore)
83+
}
84+
85+
private fun needToEnableRum(config: BenchmarkConfig): Boolean {
86+
return when (isInstrumentedRun(config)) {
87+
true -> isSessionReplayScenario(config) || isRumScenario(config)
88+
false -> isSessionReplayScenario(config)
89+
}
90+
}
91+
92+
private fun createRumConfiguration(): RumConfiguration {
93+
return RumConfiguration.Builder(BuildConfig.BENCHMARK_RUM_APPLICATION_ID)
94+
.useViewTrackingStrategy(
95+
NavigationViewTrackingStrategy(
96+
R.id.nav_host_fragment,
97+
true,
98+
BenchmarkNavigationPredicate()
99+
)
100+
)
101+
.setTelemetrySampleRate(SAMPLE_RATE_TELEMETRY)
102+
.trackUserInteractions()
103+
.trackLongTasks(THRESHOLD_LONG_TASK_INTERVAL)
104+
.trackNonFatalAnrs(true)
105+
.setViewEventMapper { event ->
106+
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
107+
event
108+
}
109+
.setActionEventMapper { event ->
110+
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
111+
event
112+
}
113+
.setResourceEventMapper { event ->
114+
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
115+
event
116+
}
117+
.setErrorEventMapper { event ->
118+
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
119+
event
120+
}
121+
.setLongTaskEventMapper { event ->
122+
event.context?.additionalProperties?.put(ATTR_IS_MAPPED, true)
123+
event
124+
}
125+
.enableComposeActionTracking()
126+
.build()
127+
}
128+
129+
private fun enableRum() {
130+
val rumConfig = createRumConfiguration()
131+
Rum.enable(rumConfig, sdkCore = sdkCore)
132+
}
133+
134+
private fun isSessionReplayScenario(config: BenchmarkConfig) = when (config.scenario) {
135+
SyntheticsScenario.SessionReplayCompose,
136+
SyntheticsScenario.Upload,
137+
SyntheticsScenario.SessionReplay -> true
138+
SyntheticsScenario.Rum,
139+
SyntheticsScenario.Trace,
140+
SyntheticsScenario.LogsCustom,
141+
SyntheticsScenario.LogsHeavyTraffic,
142+
null -> false
143+
}
144+
145+
private fun isRumScenario(config: BenchmarkConfig) = when (config.scenario) {
146+
SyntheticsScenario.Rum -> true
147+
SyntheticsScenario.SessionReplay,
148+
SyntheticsScenario.SessionReplayCompose,
149+
SyntheticsScenario.Trace,
150+
SyntheticsScenario.LogsCustom,
151+
SyntheticsScenario.LogsHeavyTraffic,
152+
SyntheticsScenario.Upload,
153+
null -> false
154+
}
155+
156+
private fun isLogsScenario(config: BenchmarkConfig) = when (config.scenario) {
157+
SyntheticsScenario.LogsCustom,
158+
SyntheticsScenario.LogsHeavyTraffic -> true
159+
SyntheticsScenario.SessionReplay,
160+
SyntheticsScenario.SessionReplayCompose,
161+
SyntheticsScenario.Rum,
162+
SyntheticsScenario.Trace,
163+
SyntheticsScenario.Upload,
164+
null -> false
165+
}
166+
167+
private fun isInstrumentedRun(config: BenchmarkConfig) = config.run == SyntheticsRun.Instrumented
168+
169+
companion object {
170+
private const val SAMPLE_IN_ALL_SESSIONS = 100f
171+
private const val ATTR_IS_MAPPED = "is_mapped"
172+
private const val SAMPLE_RATE_TELEMETRY = 100f
173+
private const val THRESHOLD_LONG_TASK_INTERVAL = 250L
174+
}
175+
}

0 commit comments

Comments
 (0)