From 55b5b69c9e782600c6d04e843788b79621e333ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Santos?= Date: Thu, 14 Nov 2024 07:23:29 +0000 Subject: [PATCH] Fix logging performance issues (#272) --- composeApp/build.gradle.kts | 1 + .../commonMain/kotlin/org/ooni/probe/App.kt | 1 + .../org/ooni/probe/domain/GetStorageUsed.kt | 18 +++++++++------ .../org/ooni/probe/domain/RunNetTest.kt | 22 +------------------ .../ooni/probe/shared/monitoring/AppLogger.kt | 18 ++++++++++++--- .../ooni/probe/ui/settings/about/InfoLinks.kt | 7 ------ 6 files changed, 29 insertions(+), 38 deletions(-) diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 200d7050..d31ccf07 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -128,6 +128,7 @@ kotlin { optIn("kotlinx.cinterop.BetaInteropApi") optIn("kotlinx.cinterop.ExperimentalForeignApi") optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") + optIn("kotlinx.coroutines.FlowPreview") optIn("org.jetbrains.compose.resources.ExperimentalResourceApi") optIn("androidx.compose.foundation.ExperimentalFoundationApi") optIn("androidx.compose.material3.ExperimentalMaterial3Api") diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt index a0df1626..884d4273 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt @@ -87,6 +87,7 @@ fun App( Logger.addLogWriter(dependencies.crashMonitoring.logWriter) Logger.addLogWriter(dependencies.appLogger.logWriter) logAppStart(dependencies.platformInfo) + dependencies.appLogger.writeLogsToFile() } LaunchedEffect(Unit) { if (dependencies.flavorConfig.isCrashReportingEnabled) { diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetStorageUsed.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetStorageUsed.kt index f07604c4..63f34b57 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetStorageUsed.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetStorageUsed.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.update import kotlinx.coroutines.withContext +import okio.FileNotFoundException import okio.FileSystem import okio.Path.Companion.toPath import kotlin.coroutines.CoroutineContext @@ -24,13 +25,16 @@ class GetStorageUsed( suspend fun update(): Long { return withContext(backgroundContext) { - val usedStorage = - ( - fileSystem.listRecursively(baseFileDir.toPath()).toList() + fileSystem.listRecursively( - cacheDir.toPath(), - ) - ).filter { fileSystem.metadata(it).isRegularFile } - .sumOf { (fileSystem.metadata(it).size ?: 0) } + val allFiles = listOf(baseFileDir, cacheDir) + .flatMap { fileSystem.listRecursively(baseFileDir.toPath()) } + val usedStorage = allFiles.sumOf { + val metadata = try { + fileSystem.metadata(it) + } catch (e: FileNotFoundException) { + return@sumOf 0L + } + if (metadata.isRegularFile) metadata.size ?: 0 else 0 + } storageUsed.update { usedStorage } return@withContext usedStorage } diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/RunNetTest.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/RunNetTest.kt index aa74c225..cdb0c7bc 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/RunNetTest.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/domain/RunNetTest.kt @@ -127,8 +127,6 @@ class RunNetTest( if (it !is TestRunState.Running) return@setCurrentTestState it it.copy(log = event.message) } - - writeToLogFile(event.message + "\n") } is TaskEvent.Progress -> { @@ -139,8 +137,6 @@ class RunNetTest( log = event.message, ) } - - writeToLogFile(event.message + "\n") } is TaskEvent.Measurement -> { @@ -259,9 +255,7 @@ class RunNetTest( Logger.w("BugJsonDump", Failure(event.value)) } - is TaskEvent.TaskTerminated -> { - deleteLogFile() - } + is TaskEvent.TaskTerminated -> Unit } } @@ -287,20 +281,6 @@ class RunNetTest( storeMeasurement(updatedMeasurement) } - private suspend fun writeToLogFile(text: String) { - writeFile( - path = getLogFilePath(), - contents = text, - append = true, - ) - } - - private suspend fun deleteLogFile() { - deleteFiles(getLogFilePath()) - } - - private fun getLogFilePath() = MeasurementModel.logFilePath(spec.resultId, spec.netTest.test) - private suspend fun writeToReportFile( measurement: MeasurementModel, text: String, diff --git a/composeApp/src/commonMain/kotlin/org/ooni/probe/shared/monitoring/AppLogger.kt b/composeApp/src/commonMain/kotlin/org/ooni/probe/shared/monitoring/AppLogger.kt index 21123bb5..93e06d8f 100644 --- a/composeApp/src/commonMain/kotlin/org/ooni/probe/shared/monitoring/AppLogger.kt +++ b/composeApp/src/commonMain/kotlin/org/ooni/probe/shared/monitoring/AppLogger.kt @@ -5,6 +5,8 @@ import co.touchlab.kermit.Severity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.update @@ -18,6 +20,7 @@ import org.ooni.probe.data.disk.WriteFile import org.ooni.probe.shared.now import org.ooni.probe.ui.shared.logFormat import kotlin.coroutines.CoroutineContext +import kotlin.time.Duration.Companion.seconds class AppLogger( private val readFile: ReadFile, @@ -53,6 +56,17 @@ class AppLogger( fun getLogFilePath() = FILE_PATH + // Persist the log into the log file after a certain period without changes + suspend fun writeLogsToFile() { + withContext(backgroundContext) { + log + .debounce(5.seconds) + .collectLatest { lines -> + writeFile(FILE_PATH, lines.joinToString("\n"), append = false) + } + } + } + val logWriter = object : LogWriter() { override fun isLoggable( tag: String, @@ -69,9 +83,7 @@ class AppLogger( val logMessage = "${LocalDateTime.now().logFormat()} : ${severity.name.uppercase()} : $message" log.update { lines -> - val newLines = (lines + logMessage).takeLast(MAX_LINES) - writeFile(FILE_PATH, newLines.joinToString("\n"), append = false) - newLines + (lines + logMessage).takeLast(MAX_LINES) } } } diff --git a/composeApp/src/dwMain/kotlin/org/ooni/probe/ui/settings/about/InfoLinks.kt b/composeApp/src/dwMain/kotlin/org/ooni/probe/ui/settings/about/InfoLinks.kt index ed9f997c..d80786cc 100644 --- a/composeApp/src/dwMain/kotlin/org/ooni/probe/ui/settings/about/InfoLinks.kt +++ b/composeApp/src/dwMain/kotlin/org/ooni/probe/ui/settings/about/InfoLinks.kt @@ -1,19 +1,12 @@ package org.ooni.probe.ui.settings.about import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import ooniprobe.composeapp.generated.resources.Res import ooniprobe.composeapp.generated.resources.logo_probe -import ooniprobe.composeapp.generated.resources.onboarding import org.jetbrains.compose.resources.painterResource import org.ooni.probe.ui.shared.isHeightCompact