Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
051175c
Translate strings.xml in bn_IN [Manual Sync]
transifex-integration[bot] Mar 10, 2025
76fc22c
Translate strings.xml in bn_BD [Manual Sync]
transifex-integration[bot] Mar 10, 2025
0d57702
Fix misspelling in the spanish strings
msasikanth Mar 11, 2025
3f98238
Merge pull request #5361 from simpledotorg/translations_48fc69a51be7c…
msasikanth Mar 11, 2025
6ba248c
Translate strings.xml in ti [Manual Sync]
transifex-integration[bot] Mar 10, 2025
665406e
Merge pull request #5362 from simpledotorg/translations_48fc69a51be7c…
msasikanth Mar 11, 2025
8cecb05
Merge pull request #5363 from simpledotorg/translations_48fc69a51be7c…
msasikanth Mar 11, 2025
0121f80
Translate strings.xml in so [Manual Sync]
transifex-integration[bot] Mar 10, 2025
7a86aa6
Translate strings.xml in so [Manual Sync]
transifex-integration[bot] Mar 10, 2025
6f84f4c
Merge pull request #5364 from simpledotorg/translations_48fc69a51be7c…
msasikanth Mar 11, 2025
509926f
Updates for file app/src/main/res/values/strings.xml in si_LK [Manual…
transifex-integration[bot] Mar 11, 2025
f6212e2
Updates for file app/src/main/res/values/strings.xml in hi_IN [Manual…
transifex-integration[bot] Mar 11, 2025
3241d7e
Updates for file app/src/main/res/values/strings.xml in am_ET [Manual…
transifex-integration[bot] Mar 11, 2025
086b581
Updates for file app/src/main/res/values/strings.xml in ta_IN [Manual…
transifex-integration[bot] Mar 11, 2025
1c4b68b
Updates for file app/src/main/res/values/strings.xml in om [Manual Sy…
transifex-integration[bot] Mar 11, 2025
da63f08
Updates for file app/src/main/res/values/strings.xml in kn_IN [Manual…
transifex-integration[bot] Mar 11, 2025
c7164c7
Updates for file app/src/main/res/values/strings.xml in te_IN [Manual…
transifex-integration[bot] Mar 11, 2025
46e2136
Updates for file app/src/main/res/values/strings.xml in sid [Manual S…
transifex-integration[bot] Mar 11, 2025
fcb329d
Fix invalid escape characters in strings #5378
msasikanth Mar 11, 2025
7e128a1
Push Room database metrics to Sentry (#5276)
msasikanth Mar 24, 2025
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 .github/workflows/benchmark_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ jobs:
script: |
adb root
./gradlew --no-configuration-cache -PmanifestEndpoint=https://api-sandbox.simple.org/api/ installQaDebug installQaDebugAndroidTest lockClocks
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
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
adb uninstall org.simple.clinic.qa.debug
adb uninstall org.simple.clinic.qa.debug.test
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
- Bump AGP to v8.8.2
- Calculate lab-based CVD risk score
- Update copy of statin nudge to support lab-based nudge
- Report SQL performance metrics to Sentry

### Fixes

Expand Down
24 changes: 7 additions & 17 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
@file:Suppress("UnstableApiUsage")

import com.android.build.gradle.internal.tasks.databinding.DataBindingGenBaseClassesTask
import io.sentry.android.gradle.extensions.InstrumentationFeature
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
import org.simple.rmg.RoomMetadataGenerator
import java.util.EnumSet

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.sentry)
alias(libs.plugins.datadog)
alias(libs.plugins.ksp)
alias(libs.plugins.kotlin.compose.compiler)
alias(libs.plugins.google.services)
Expand All @@ -33,7 +34,8 @@ sentry {
// We are using our own instrumentation tooling for Room queries
// Look at [ADR 013: SQL Performance Profiling (v2)]
tracingInstrumentation {
enabled.set(false)
enabled = true
features.set(EnumSet.allOf(InstrumentationFeature::class.java) - InstrumentationFeature.DATABASE)
}
}

Expand Down Expand Up @@ -87,22 +89,12 @@ android {
val manifestEndpoint: String by project
val disableScreenshot: String by project
val allowRootedDevice: String by project
val datadogServiceName: String by project
val datadogApplicationId: String by project
val datadogClientToken: String by project
val datadogEnvironment: String by project

addManifestPlaceholders(mapOf(
"sentryDsn" to sentryDsn,
"sentryEnvironment" to sentryEnvironment
))

buildConfigField("String", "SENTRY_DSN", "\"$sentryDsn\"")
buildConfigField("String", "SENTRY_ENVIRONMENT", "\"$sentryEnvironment\"")
buildConfigField("String", "MANIFEST_ENDPOINT", "\"$manifestEndpoint\"")
buildConfigField("boolean", "DISABLE_SCREENSHOT", disableScreenshot)
buildConfigField("boolean", "ALLOW_ROOTED_DEVICE", allowRootedDevice)
buildConfigField("String", "DATADOG_SERVICE_NAME", "\"$datadogServiceName\"")
buildConfigField("String", "DATADOG_APPLICATION_ID", "\"$datadogApplicationId\"")
buildConfigField("String", "DATADOG_CLIENT_TOKEN", "\"$datadogClientToken\"")
buildConfigField("String", "DATADOG_ENVIRONMENT", "\"$datadogEnvironment\"")

ksp {
arg("room.schemaLocation", "$projectDir/schemas")
Expand Down Expand Up @@ -482,8 +474,6 @@ dependencies {

runtimeOnly(libs.jackson.core)

implementation(libs.datadog.sdk)

androidTestImplementation(libs.apache.commons.math)
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

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

</instrumentation>
</manifest>
66 changes: 19 additions & 47 deletions app/src/androidTest/java/org/simple/clinic/TestClinicApp.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
package org.simple.clinic

import android.app.Application
import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import com.datadog.android.Datadog
import com.datadog.android.core.configuration.Configuration
import com.datadog.android.core.configuration.Credentials
import com.datadog.android.core.configuration.UploadFrequency
import com.datadog.android.privacy.TrackingConsent
import com.datadog.android.rum.GlobalRum
import com.datadog.android.rum.RumMonitor
import com.datadog.android.rum.tracking.ViewTrackingStrategy
import com.datadog.android.tracing.AndroidTracer
import com.tspoon.traceur.Traceur
import io.opentracing.util.GlobalTracer
import io.sentry.SentryLevel
import io.sentry.SentryOptions
import io.sentry.android.core.SentryAndroid
import org.simple.clinic.TestClinicApp.Companion.appComponent
import org.simple.clinic.benchmark.BackupBenchmarkDatabase
import org.simple.clinic.di.DaggerTestAppComponent
Expand Down Expand Up @@ -100,9 +92,8 @@ class TestClinicApp : Application() {
dataSync.syncTheWorld()
backupBenchmarkDatabase.backup()

setupDatadog(
clientToken = instrumentationArgs.getString("dd_client_token")!!,
applicationId = instrumentationArgs.getString("dd_application_id")!!
setupSentry(
dsn = instrumentationArgs.getString("sentry_dsn")!!,
)
}
}
Expand Down Expand Up @@ -155,39 +146,20 @@ class TestClinicApp : Application() {
.build()
}

private fun setupDatadog(
clientToken: String,
applicationId: String
) {
val datadogConfig = Configuration
.Builder(
logsEnabled = true,
tracesEnabled = true,
crashReportsEnabled = false,
rumEnabled = false
)
.useViewTrackingStrategy(NoopViewTrackingStrategy())
.setUploadFrequency(UploadFrequency.FREQUENT)
.build()
val credentials = Credentials(
clientToken = clientToken,
envName = "test",
variant = BuildConfig.FLAVOR,
rumApplicationId = applicationId,
serviceName = "simple-android-perf-regression"
)
Datadog.initialize(this, credentials, datadogConfig, TrackingConsent.GRANTED)
GlobalRum.registerIfAbsent(RumMonitor.Builder().build())
GlobalTracer.registerIfAbsent(AndroidTracer.Builder().setPartialFlushThreshold(5).build())
}

private class NoopViewTrackingStrategy : ViewTrackingStrategy {
override fun register(context: Context) {
// No need to track views in tests
}

override fun unregister(context: Context?) {
// No need to track views in tests
private fun setupSentry(dsn: String) {
SentryAndroid.init(this) { options ->
options.dsn = dsn
options.environment = "test"
options.sampleRate = 0.0
options.tracesSampleRate = 1.0

options.beforeSend = SentryOptions.BeforeSendCallback { event, _ ->
if (event.level != SentryLevel.DEBUG) {
event
} else {
null
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package org.simple.clinic.benchmark

import android.util.Log
import io.opentracing.util.GlobalTracer
import io.sentry.Sentry
import io.sentry.SentryLongDate
import io.sentry.SpanStatus
import io.sentry.TransactionOptions
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
import org.simple.clinic.TestClinicApp
import java.util.concurrent.TimeUnit.MICROSECONDS
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeUnit.MILLISECONDS
import javax.inject.Inject

Expand Down Expand Up @@ -65,19 +68,22 @@ class BenchmarkTestRule(

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

val tracer = GlobalTracer.get()
val adjustedStartTime = millisToMicros(System.currentTimeMillis() - medianTimeTaken)
val span = tracer
.buildSpan("test.method")
.withTag("class", testClass)
.withTag("method", testMethod)
.withStartTimestamp(adjustedStartTime)
.start()
val adjustedStartTime = millisToNanos(System.currentTimeMillis() - medianTimeTaken)

span.finish(adjustedStartTime + millisToMicros(medianTimeTaken))
val span = Sentry.startTransaction(
/* name = */ "test.method",
/* operation = */ "$testClass/$testMethod",
/* transactionOptions = */ TransactionOptions().apply {
startTimestamp = SentryLongDate(adjustedStartTime)
}
)

span.finish(
SpanStatus.OK,
SentryLongDate(adjustedStartTime + millisToNanos(medianTimeTaken)))
}

private fun millisToMicros(millis: Long) = MICROSECONDS.convert(millis, MILLISECONDS)
private fun millisToNanos(millis: Long) = TimeUnit.NANOSECONDS.convert(millis, MILLISECONDS)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@ package org.simple.clinic.benchmark
import android.os.Bundle
import android.util.Log
import androidx.test.internal.runner.listener.InstrumentationRunListener
import io.opentracing.util.GlobalTracer
import org.junit.runner.Result
import org.simple.clinic.TestClinicApp
import java.io.PrintStream
import java.time.Duration

class WaitForDatadogToUpload : InstrumentationRunListener() {
class WaitForSentryToUpload : InstrumentationRunListener() {

override fun instrumentationRunFinished(streamResult: PrintStream?, resultBundle: Bundle?, junitResults: Result?) {
// We don't have a way to force Datadog to upload all its traces, so we'll wait for a few seconds
// for DD to upload, and then we'll finish it.
// We don't have a way to force Sentry to upload all its traces, so we'll wait for a few seconds
// for Sentry to upload, and then we'll finish it.
if (TestClinicApp.isInBenchmarkMode) {
Log.i("PerfRegression", "Wait for Datadog upload")
Log.i("PerfRegression", "Wait for Sentry upload")
Thread.sleep(Duration.ofMinutes(1).toMillis())
GlobalTracer.get().close()
}
}
}
4 changes: 0 additions & 4 deletions app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
tools:ignore="GoogleAppIndexingWarning"
tools:replace="android:name,android:icon">

<meta-data
android:name="io.sentry.auto-init"
android:value="false" />

<receiver android:name=".DebugNotificationActionReceiver" />

<receiver
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.simple.clinic.di.network

import com.datadog.android.DatadogInterceptor
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
import dagger.Module
import dagger.Provides
import io.sentry.okhttp.SentryOkHttpInterceptor
import okhttp3.Interceptor
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level.BODY
Expand All @@ -25,7 +25,7 @@ class HttpInterceptorsModule {
}

return listOf(
DatadogInterceptor(),
SentryOkHttpInterceptor(),
loggedInInterceptor,
appInfoHttpInterceptor,
loggingInterceptor,
Expand Down
12 changes: 2 additions & 10 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,8 @@
android:value="barcode" />

<meta-data
android:name="io.sentry.dsn"
android:value="${sentryDsn}" />

<meta-data
android:name="io.sentry.environment"
android:value="${sentryEnvironment}" />

<meta-data
android:name="io.sentry.sample-rate"
android:value="0.75" />
android:name="io.sentry.auto-init"
android:value="false" />

<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
Expand Down
Loading
Loading