Skip to content

Commit 7e128a1

Browse files
authored
1 parent fcb329d commit 7e128a1

File tree

21 files changed

+113
-221
lines changed

21 files changed

+113
-221
lines changed

.github/workflows/benchmark_suite.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ jobs:
4141
script: |
4242
adb root
4343
./gradlew --no-configuration-cache -PmanifestEndpoint=https://api-sandbox.simple.org/api/ installQaDebug installQaDebugAndroidTest lockClocks
44-
adb shell am instrument -w -e filter org.simple.clinic.benchmark.SelectBenchmarkTests -e benchmark_app_performance true -e dd_client_token ${{ secrets.DD_PERF_CLIENT_TOKEN }} -e dd_application_id ${{ secrets.DD_PERF_APPLICATION_ID }} org.simple.clinic.qa.debug.test/org.simple.clinic.AndroidTestJUnitRunner
44+
adb shell am instrument -w -e filter org.simple.clinic.benchmark.SelectBenchmarkTests -e benchmark_app_performance true -e sentry_dsn ${{ secrets.SENTRY_DSN }} org.simple.clinic.qa.debug.test/org.simple.clinic.AndroidTestJUnitRunner
4545
adb uninstall org.simple.clinic.qa.debug
4646
adb uninstall org.simple.clinic.qa.debug.test

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
- Bump AGP to v8.8.2
6868
- Calculate lab-based CVD risk score
6969
- Update copy of statin nudge to support lab-based nudge
70+
- Report SQL performance metrics to Sentry
7071

7172
### Fixes
7273

app/build.gradle.kts

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
@file:Suppress("UnstableApiUsage")
22

33
import com.android.build.gradle.internal.tasks.databinding.DataBindingGenBaseClassesTask
4+
import io.sentry.android.gradle.extensions.InstrumentationFeature
45
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
56
import org.gradle.api.tasks.testing.logging.TestLogEvent
67
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
78
import org.simple.rmg.RoomMetadataGenerator
9+
import java.util.EnumSet
810

911
plugins {
1012
alias(libs.plugins.android.application)
1113
alias(libs.plugins.kotlin.android)
1214
alias(libs.plugins.kotlin.parcelize)
1315
alias(libs.plugins.sentry)
14-
alias(libs.plugins.datadog)
1516
alias(libs.plugins.ksp)
1617
alias(libs.plugins.kotlin.compose.compiler)
1718
alias(libs.plugins.google.services)
@@ -33,7 +34,8 @@ sentry {
3334
// We are using our own instrumentation tooling for Room queries
3435
// Look at [ADR 013: SQL Performance Profiling (v2)]
3536
tracingInstrumentation {
36-
enabled.set(false)
37+
enabled = true
38+
features.set(EnumSet.allOf(InstrumentationFeature::class.java) - InstrumentationFeature.DATABASE)
3739
}
3840
}
3941

@@ -87,22 +89,12 @@ android {
8789
val manifestEndpoint: String by project
8890
val disableScreenshot: String by project
8991
val allowRootedDevice: String by project
90-
val datadogServiceName: String by project
91-
val datadogApplicationId: String by project
92-
val datadogClientToken: String by project
93-
val datadogEnvironment: String by project
94-
95-
addManifestPlaceholders(mapOf(
96-
"sentryDsn" to sentryDsn,
97-
"sentryEnvironment" to sentryEnvironment
98-
))
92+
93+
buildConfigField("String", "SENTRY_DSN", "\"$sentryDsn\"")
94+
buildConfigField("String", "SENTRY_ENVIRONMENT", "\"$sentryEnvironment\"")
9995
buildConfigField("String", "MANIFEST_ENDPOINT", "\"$manifestEndpoint\"")
10096
buildConfigField("boolean", "DISABLE_SCREENSHOT", disableScreenshot)
10197
buildConfigField("boolean", "ALLOW_ROOTED_DEVICE", allowRootedDevice)
102-
buildConfigField("String", "DATADOG_SERVICE_NAME", "\"$datadogServiceName\"")
103-
buildConfigField("String", "DATADOG_APPLICATION_ID", "\"$datadogApplicationId\"")
104-
buildConfigField("String", "DATADOG_CLIENT_TOKEN", "\"$datadogClientToken\"")
105-
buildConfigField("String", "DATADOG_ENVIRONMENT", "\"$datadogEnvironment\"")
10698

10799
ksp {
108100
arg("room.schemaLocation", "$projectDir/schemas")
@@ -482,8 +474,6 @@ dependencies {
482474

483475
runtimeOnly(libs.jackson.core)
484476

485-
implementation(libs.datadog.sdk)
486-
487477
androidTestImplementation(libs.apache.commons.math)
488478
}
489479

app/src/androidTest/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<meta-data
88
android:name="listener"
9-
android:value="org.simple.clinic.benchmark.WaitForDatadogToUpload" />
9+
android:value="org.simple.clinic.benchmark.WaitForSentryToUpload" />
1010

1111
</instrumentation>
1212
</manifest>

app/src/androidTest/java/org/simple/clinic/TestClinicApp.kt

Lines changed: 19 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
package org.simple.clinic
22

33
import android.app.Application
4-
import android.content.Context
54
import androidx.test.platform.app.InstrumentationRegistry
6-
import com.datadog.android.Datadog
7-
import com.datadog.android.core.configuration.Configuration
8-
import com.datadog.android.core.configuration.Credentials
9-
import com.datadog.android.core.configuration.UploadFrequency
10-
import com.datadog.android.privacy.TrackingConsent
11-
import com.datadog.android.rum.GlobalRum
12-
import com.datadog.android.rum.RumMonitor
13-
import com.datadog.android.rum.tracking.ViewTrackingStrategy
14-
import com.datadog.android.tracing.AndroidTracer
155
import com.tspoon.traceur.Traceur
16-
import io.opentracing.util.GlobalTracer
6+
import io.sentry.SentryLevel
7+
import io.sentry.SentryOptions
8+
import io.sentry.android.core.SentryAndroid
179
import org.simple.clinic.TestClinicApp.Companion.appComponent
1810
import org.simple.clinic.benchmark.BackupBenchmarkDatabase
1911
import org.simple.clinic.di.DaggerTestAppComponent
@@ -100,9 +92,8 @@ class TestClinicApp : Application() {
10092
dataSync.syncTheWorld()
10193
backupBenchmarkDatabase.backup()
10294

103-
setupDatadog(
104-
clientToken = instrumentationArgs.getString("dd_client_token")!!,
105-
applicationId = instrumentationArgs.getString("dd_application_id")!!
95+
setupSentry(
96+
dsn = instrumentationArgs.getString("sentry_dsn")!!,
10697
)
10798
}
10899
}
@@ -155,39 +146,20 @@ class TestClinicApp : Application() {
155146
.build()
156147
}
157148

158-
private fun setupDatadog(
159-
clientToken: String,
160-
applicationId: String
161-
) {
162-
val datadogConfig = Configuration
163-
.Builder(
164-
logsEnabled = true,
165-
tracesEnabled = true,
166-
crashReportsEnabled = false,
167-
rumEnabled = false
168-
)
169-
.useViewTrackingStrategy(NoopViewTrackingStrategy())
170-
.setUploadFrequency(UploadFrequency.FREQUENT)
171-
.build()
172-
val credentials = Credentials(
173-
clientToken = clientToken,
174-
envName = "test",
175-
variant = BuildConfig.FLAVOR,
176-
rumApplicationId = applicationId,
177-
serviceName = "simple-android-perf-regression"
178-
)
179-
Datadog.initialize(this, credentials, datadogConfig, TrackingConsent.GRANTED)
180-
GlobalRum.registerIfAbsent(RumMonitor.Builder().build())
181-
GlobalTracer.registerIfAbsent(AndroidTracer.Builder().setPartialFlushThreshold(5).build())
182-
}
183-
184-
private class NoopViewTrackingStrategy : ViewTrackingStrategy {
185-
override fun register(context: Context) {
186-
// No need to track views in tests
187-
}
188-
189-
override fun unregister(context: Context?) {
190-
// No need to track views in tests
149+
private fun setupSentry(dsn: String) {
150+
SentryAndroid.init(this) { options ->
151+
options.dsn = dsn
152+
options.environment = "test"
153+
options.sampleRate = 0.0
154+
options.tracesSampleRate = 1.0
155+
156+
options.beforeSend = SentryOptions.BeforeSendCallback { event, _ ->
157+
if (event.level != SentryLevel.DEBUG) {
158+
event
159+
} else {
160+
null
161+
}
162+
}
191163
}
192164
}
193165
}

app/src/androidTest/java/org/simple/clinic/benchmark/BenchmarkTestRule.kt

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package org.simple.clinic.benchmark
22

33
import android.util.Log
4-
import io.opentracing.util.GlobalTracer
4+
import io.sentry.Sentry
5+
import io.sentry.SentryLongDate
6+
import io.sentry.SpanStatus
7+
import io.sentry.TransactionOptions
58
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics
69
import org.junit.rules.TestRule
710
import org.junit.runner.Description
811
import org.junit.runners.model.Statement
912
import org.simple.clinic.TestClinicApp
10-
import java.util.concurrent.TimeUnit.MICROSECONDS
13+
import java.util.concurrent.TimeUnit
1114
import java.util.concurrent.TimeUnit.MILLISECONDS
1215
import javax.inject.Inject
1316

@@ -65,19 +68,22 @@ class BenchmarkTestRule(
6568

6669
Log.i("PerfRegression", "Median benchmark for $testClass#$testMethod: ${medianTimeTaken}ms")
6770

68-
val tracer = GlobalTracer.get()
69-
val adjustedStartTime = millisToMicros(System.currentTimeMillis() - medianTimeTaken)
70-
val span = tracer
71-
.buildSpan("test.method")
72-
.withTag("class", testClass)
73-
.withTag("method", testMethod)
74-
.withStartTimestamp(adjustedStartTime)
75-
.start()
71+
val adjustedStartTime = millisToNanos(System.currentTimeMillis() - medianTimeTaken)
7672

77-
span.finish(adjustedStartTime + millisToMicros(medianTimeTaken))
73+
val span = Sentry.startTransaction(
74+
/* name = */ "test.method",
75+
/* operation = */ "$testClass/$testMethod",
76+
/* transactionOptions = */ TransactionOptions().apply {
77+
startTimestamp = SentryLongDate(adjustedStartTime)
78+
}
79+
)
80+
81+
span.finish(
82+
SpanStatus.OK,
83+
SentryLongDate(adjustedStartTime + millisToNanos(medianTimeTaken)))
7884
}
7985

80-
private fun millisToMicros(millis: Long) = MICROSECONDS.convert(millis, MILLISECONDS)
86+
private fun millisToNanos(millis: Long) = TimeUnit.NANOSECONDS.convert(millis, MILLISECONDS)
8187
}
8288
}
8389
}

app/src/androidTest/java/org/simple/clinic/benchmark/WaitForDatadogToUpload.kt renamed to app/src/androidTest/java/org/simple/clinic/benchmark/WaitForSentryToUpload.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,19 @@ package org.simple.clinic.benchmark
33
import android.os.Bundle
44
import android.util.Log
55
import androidx.test.internal.runner.listener.InstrumentationRunListener
6-
import io.opentracing.util.GlobalTracer
76
import org.junit.runner.Result
87
import org.simple.clinic.TestClinicApp
98
import java.io.PrintStream
109
import java.time.Duration
1110

12-
class WaitForDatadogToUpload : InstrumentationRunListener() {
11+
class WaitForSentryToUpload : InstrumentationRunListener() {
1312

1413
override fun instrumentationRunFinished(streamResult: PrintStream?, resultBundle: Bundle?, junitResults: Result?) {
15-
// We don't have a way to force Datadog to upload all its traces, so we'll wait for a few seconds
16-
// for DD to upload, and then we'll finish it.
14+
// We don't have a way to force Sentry to upload all its traces, so we'll wait for a few seconds
15+
// for Sentry to upload, and then we'll finish it.
1716
if (TestClinicApp.isInBenchmarkMode) {
18-
Log.i("PerfRegression", "Wait for Datadog upload")
17+
Log.i("PerfRegression", "Wait for Sentry upload")
1918
Thread.sleep(Duration.ofMinutes(1).toMillis())
20-
GlobalTracer.get().close()
2119
}
2220
}
2321
}

app/src/debug/AndroidManifest.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88
tools:ignore="GoogleAppIndexingWarning"
99
tools:replace="android:name,android:icon">
1010

11-
<meta-data
12-
android:name="io.sentry.auto-init"
13-
android:value="false" />
14-
1511
<receiver android:name=".DebugNotificationActionReceiver" />
1612

1713
<receiver

app/src/debug/java/org/simple/clinic/di/network/HttpInterceptorsModule.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package org.simple.clinic.di.network
22

3-
import com.datadog.android.DatadogInterceptor
43
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor
54
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
65
import dagger.Module
76
import dagger.Provides
7+
import io.sentry.okhttp.SentryOkHttpInterceptor
88
import okhttp3.Interceptor
99
import okhttp3.logging.HttpLoggingInterceptor
1010
import okhttp3.logging.HttpLoggingInterceptor.Level.BODY
@@ -25,7 +25,7 @@ class HttpInterceptorsModule {
2525
}
2626

2727
return listOf(
28-
DatadogInterceptor(),
28+
SentryOkHttpInterceptor(),
2929
loggedInInterceptor,
3030
appInfoHttpInterceptor,
3131
loggingInterceptor,

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,8 @@
6666
android:value="barcode" />
6767

6868
<meta-data
69-
android:name="io.sentry.dsn"
70-
android:value="${sentryDsn}" />
71-
72-
<meta-data
73-
android:name="io.sentry.environment"
74-
android:value="${sentryEnvironment}" />
75-
76-
<meta-data
77-
android:name="io.sentry.sample-rate"
78-
android:value="0.75" />
69+
android:name="io.sentry.auto-init"
70+
android:value="false" />
7971

8072
<service
8173
android:name="androidx.work.impl.foreground.SystemForegroundService"

0 commit comments

Comments
 (0)