Skip to content

Commit

Permalink
Send logs to datadog
Browse files Browse the repository at this point in the history
  • Loading branch information
ForceTower committed Nov 7, 2024
1 parent 65b76fe commit edfb29b
Show file tree
Hide file tree
Showing 18 changed files with 228 additions and 21 deletions.
1 change: 1 addition & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
UNES_KEYSTORE_PASSWORD: ${{ secrets.UNES_KEYSTORE_PASSWORD }}
UNES_KEYSTORE_PRIVATE_KEY_PASSWORD: ${{ secrets.UNES_KEYSTORE_PRIVATE_KEY_PASSWORD }}
UNES_MAPS_KEY: ${{ secrets.UNES_MAPS_KEY }}
UNES_DATADOG_CLIENT_KEY: ${{ secrets.UNES_DATADOG_CLIENT_KEY }}

- name: Upload Check Results
uses: actions/upload-artifact@v2
Expand Down
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ android {
buildConfigField("String", "SIECOMP_DAY5_START", "\"2019-10-22T08:00:00-03:00\"")
buildConfigField("String", "SIECOMP_DAY5_END", "\"2019-10-22T17:30:00-03:00\"")
buildConfigField("String", "UEFS_DEFAULT_PROXY", "\"10.65.16.2:3128\"")
buildConfigField("String", "DATADOG_PUBLIC_KEY", "\"${System.getenv("UNES_DATADOG_CLIENT_KEY")}\"")

ndk {
abiFilters += listOf("arm64-v8a", "armeabi", "armeabi-v7a", "mips", "mips64", "x86", "x86_64")
Expand Down Expand Up @@ -231,6 +232,7 @@ dependencies {
debugImplementation(libs.chucker)
releaseImplementation(libs.chucker.no.op)
implementation(libs.timber)
implementation(libs.datadog)
implementation(libs.play.services.games.v2)
implementation(libs.play.services.auth)
implementation(libs.play.services.location)
Expand Down
1 change: 0 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
-assumenosideeffects class timber.log.Timber {
public static *** v(...);
public static *** d(...);
public static *** i(...);
}

-if class androidx.credentials.CredentialManager
Expand Down
37 changes: 35 additions & 2 deletions app/src/main/java/com/forcetower/uefs/UApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,25 @@ package com.forcetower.uefs
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import com.datadog.android.Datadog
import com.datadog.android.DatadogSite
import com.datadog.android.log.Logger
import com.datadog.android.log.Logs
import com.datadog.android.log.LogsConfiguration
import com.datadog.android.privacy.TrackingConsent
import com.forcetower.sagres.SagresNavigator
import com.forcetower.uefs.core.constants.Constants
import com.forcetower.uefs.core.storage.cookies.CachedCookiePersistor
import com.forcetower.uefs.core.storage.cookies.PrefsCookiePersistor
import com.forcetower.uefs.core.work.sync.SyncMainWorker
import com.forcetower.uefs.domain.usecase.device.GetDeviceInfoUseCase
import com.forcetower.uefs.feature.themeswitcher.ThemePreferencesManager
import com.forcetower.uefs.impl.AndroidBase64Encoder
import com.forcetower.uefs.impl.CrashlyticsTree
import com.forcetower.uefs.impl.DatadogTree
import com.forcetower.uefs.impl.SharedPrefsCachePersistence
import com.forcetower.uefs.service.NotificationHelper
import com.google.android.gms.games.PlayGamesSdk
Expand All @@ -41,12 +50,15 @@ import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject
import okhttp3.OkHttpClient
import timber.log.Timber
import java.util.UUID
import kotlin.uuid.Uuid

@HiltAndroidApp
class UApplication : Application(), Configuration.Provider {
@Inject lateinit var preferences: SharedPreferences

@Inject lateinit var datadogTree: DatadogTree
@Inject lateinit var workerFactory: HiltWorkerFactory
@Inject lateinit var deviceInfoUseCase: GetDeviceInfoUseCase

var disciplineToolbarDevClickCount = 0
var messageToolbarDevClickCount = 0
Expand All @@ -56,13 +68,34 @@ class UApplication : Application(), Configuration.Provider {
SplitCompat.install(this)
}

private fun initializeDatadog() {
if (BuildConfig.DEBUG) return
val configuration = com.datadog.android.core.configuration.Configuration.Builder(
clientToken = BuildConfig.DATADOG_PUBLIC_KEY,
env = "production",
).apply {
setCrashReportsEnabled(false)
useSite(DatadogSite.US1)
}.build()
Datadog.initialize(this, configuration, TrackingConsent.GRANTED)


val logsConfig = LogsConfiguration.Builder().build()
Logs.enable(logsConfig)
}

override fun onCreate() {
initializeDatadog()
super.onCreate()
Logs.addAttribute("machineId", deviceInfoUseCase.machineIdDirect())

if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
} else {
Timber.plant(CrashlyticsTree())
Timber.plant(datadogTree)
}
super.onCreate()


if (preferences.getBoolean("google_play_games_enabled_v2", false)) {
PlayGamesSdk.initialize(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStoreFile
import androidx.preference.PreferenceManager
import androidx.room.Room
import com.datadog.android.log.Logger
import com.forcetower.uefs.core.storage.apidatabase.APIDatabase
import com.forcetower.uefs.core.storage.database.M50TO51
import com.forcetower.uefs.core.storage.database.M51TO52
Expand Down Expand Up @@ -92,6 +93,15 @@ object AppModule {
}
}

@Provides
@Singleton
@Named("settings")
fun provideSettings(context: Context): DataStore<Preferences> {
return PreferenceDataStoreFactory.create {
context.preferencesDataStoreFile("settings")
}
}

@Provides
@Singleton
fun provideThemeSwitcherResourceProvider() = ThemeSwitcherResourceProvider()
Expand All @@ -117,6 +127,19 @@ object AppModule {
return agents.random()
}

@Provides
@Singleton
fun datadogLogs(): Logger {
return Logger.Builder()
.setNetworkInfoEnabled(true)
.setLogcatLogsEnabled(false)
.setRemoteSampleRate(100f)
.setBundleWithTraceEnabled(true)
.setService("Android")
.setName("Android")
.build()
}

@Provides
@Reusable
@Named("unesUserAgent")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,17 @@ object NetworkModule {
.cookieJar(cookieJar)
.callTimeout(2, TimeUnit.MINUTES)
.addInterceptor(interceptor)
.addInterceptor(
HttpLoggingInterceptor {
Timber.tag("ok-http").d(it)
}.apply {
level = if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Level.BASIC
} else {
HttpLoggingInterceptor.Level.NONE
}
.apply {
if (!BuildConfig.DEBUG) {
addInterceptor(
HttpLoggingInterceptor {
Timber.tag("ok-http").d(it)
}.apply {
level = HttpLoggingInterceptor.Level.BASIC
}
)
}
)
}
.addInterceptor(chuckerInterceptor)
.build()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class EdgeAccountRepository @Inject constructor(
fun getAccount() = database.edgeServiceAccount.me()

suspend fun fetchAccountIfNeeded() {
val token = database.edgeAccessToken.require() ?: return
Timber.d("Has edge token $token")
database.edgeAccessToken.require() ?: return
Timber.d("Has edge token")

val me = service.me().data
val value = EdgeServiceAccount(
Expand All @@ -32,8 +32,8 @@ class EdgeAccountRepository @Inject constructor(
}

suspend fun startSession() {
val token = database.edgeAccessToken.require() ?: return
Timber.d("Has edge token $token")
database.edgeAccessToken.require() ?: return
Timber.d("Has edge token")
val access = database.accessDao().getAccessDirectSuspend() ?: return
Timber.d("No credentials")
runCatching {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.forcetower.uefs.domain.usecase.device

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import dagger.Reusable
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import java.security.MessageDigest
import java.util.UUID
import javax.inject.Inject
import javax.inject.Named

@Reusable
class GetDeviceInfoUseCase @Inject constructor(
@Named("settings") private val settings: DataStore<Preferences>
) {
private val deviceId = stringPreferencesKey("device_id")

@Inject
fun generateMachineId(): String {
return runBlocking {
settings.data.first()[deviceId] ?: run {
val generated = UUID.randomUUID().toString()
settings.edit { it[deviceId] = generated }
generated
}
}
}

fun machineIdDirect(): String {
return runBlocking {
settings.data.first()[deviceId]?.let { str ->
val bytes = MessageDigest.getInstance("MD5").digest(str.toByteArray(Charsets.UTF_8))
bytes.joinToString(separator = "") { byte -> "%02x".format(byte) }
} ?: UNINITIALIZED
}
}

fun machineId(): Flow<String> {
return settings.data.map {
it[deviceId]?.let { str ->
val bytes = MessageDigest.getInstance("MD5").digest(str.toByteArray(Charsets.UTF_8))
bytes.joinToString(separator = "") { byte -> "%02x".format(byte) }
} ?: UNINITIALIZED
}
}

private companion object {
const val UNINITIALIZED = "unavailable"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import androidx.navigation.ui.NavigationUI
import com.datadog.android.log.Logs
import com.forcetower.core.lifecycle.EventObserver
import com.forcetower.sagres.SagresNavigator
import com.forcetower.sagres.database.model.SagresCredential
Expand Down Expand Up @@ -297,6 +298,10 @@ class HomeActivity : UGameActivity() {
private fun onAccessUpdate(access: Access?) {
if (access == null) {
Timber.d("Access Invalidated")
Logs.removeAttribute("username")
Logs.removeAttribute("institution")
Logs.removeAttribute("accessValid")

val intent = Intent(this, LoginActivity::class.java)
intent.addFlags(FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP)
Expand All @@ -309,6 +314,9 @@ class HomeActivity : UGameActivity() {
analytics.setUserId(access.username)
analytics.setUserProperty("institution", SagresNavigator.instance.getSelectedInstitution())
analytics.setUserProperty("access_valid", "${access.valid}")
Logs.addAttribute("username", access.username)
Logs.addAttribute("institution", SagresNavigator.instance.getSelectedInstitution())
Logs.addAttribute("accessValid", access.valid)
SagresNavigator.instance.putCredentials(SagresCredential(access.username, access.password, SagresNavigator.instance.getSelectedInstitution()))

if (!access.valid) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.forcetower.uefs.feature.home

import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Bundle
Expand All @@ -41,6 +42,7 @@ import com.canhub.cropper.CropImageView
import com.forcetower.core.utils.ColorUtils
import com.forcetower.uefs.BuildConfig
import com.forcetower.uefs.R
import com.forcetower.uefs.core.constants.Constants
import com.forcetower.uefs.core.model.unes.Course
import com.forcetower.uefs.core.model.unes.EdgeServiceAccount
import com.forcetower.uefs.core.util.isStudentFromUEFS
Expand Down Expand Up @@ -171,8 +173,7 @@ class HomeBottomFragment : UFragment() {
true
}
R.id.bug_report -> {
val fragment = SendFeedbackFragment()
fragment.show(childFragmentManager, "feedback_modal")
sendEmail()
true
}
R.id.campus_map -> {
Expand All @@ -186,6 +187,15 @@ class HomeBottomFragment : UFragment() {
}
}

private fun sendEmail() {
val text = "\n\nVersion: ${BuildConfig.VERSION_NAME}\nCode: ${BuildConfig.VERSION_CODE}\nDevice ID: ${viewModel.requireDeviceId()}"
val intent = Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", Constants.DEVELOPER_EMAIL, null)).apply {
putExtra(Intent.EXTRA_SUBJECT, "[UNES] App Feedback")
putExtra(Intent.EXTRA_TEXT, text)
}
startActivity(Intent.createChooser(intent, getString(R.string.send_email)))
}

private fun onImagePicked(uri: Uri) {
viewModel.setSelectedImage(uri)
Glide.with(requireContext())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import com.forcetower.uefs.core.storage.resource.Status
import com.forcetower.uefs.core.task.FetchMissingSemestersUseCase
import com.forcetower.uefs.core.work.image.UploadImageToStorage
import com.forcetower.uefs.domain.usecase.auth.EdgeAnonymousLoginUseCase
import com.forcetower.uefs.domain.usecase.device.GetDeviceInfoUseCase
import com.forcetower.uefs.easter.darktheme.DarkThemeRepository
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.InstallStatus
Expand All @@ -78,7 +79,8 @@ class HomeViewModel @Inject constructor(
@Named("flagSnowpiercerEnabled")
private val snowpiercerEnabled: Boolean,
private val anonymousLoginUseCase: EdgeAnonymousLoginUseCase,
private val edgeSyncRepository: EdgeSyncRepository
private val edgeSyncRepository: EdgeSyncRepository,
private val deviceInfoUseCase: GetDeviceInfoUseCase
) : AndroidViewModel(application) {
private var selectImageUri: Uri? = null

Expand Down Expand Up @@ -231,4 +233,8 @@ class HomeViewModel @Inject constructor(
fetchMissingSemesters(Unit)
}
}

fun requireDeviceId(): String {
return deviceInfoUseCase.machineIdDirect()
}
}
Loading

0 comments on commit edfb29b

Please sign in to comment.