Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: database logger [WPB-14608] #3227

Merged
merged 7 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ class ChangeProfilingUseCase(
private val userStorage: UserStorage,
) {
/**
* Changes the profiling of the database (cipher_profile) if the profile is specified and the database is encrypted
* @param enabled true to enable profiling, false to disable
* Change profiling state.
*/
operator fun invoke(enabled: Boolean) {
userStorage.database.changeProfiling(enabled)
suspend operator fun invoke(enabled: Boolean) {
userStorage.database.debugExtension.changeProfiling(enabled)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class DebugScope internal constructor(
private val legalHoldHandler: LegalHoldHandler,
private val notificationTokenRepository: NotificationTokenRepository,
private val scope: CoroutineScope,
userStorage: UserStorage,
private val userStorage: UserStorage,
logger: KaliumLogger,
internal val dispatcher: KaliumDispatcher = KaliumDispatcherImpl,
) {
Expand Down Expand Up @@ -227,5 +227,7 @@ class DebugScope internal constructor(
notificationTokenRepository,
)

val changeProfiling: ChangeProfilingUseCase = ChangeProfilingUseCase(userStorage)
val changeProfiling: ChangeProfilingUseCase get() = ChangeProfilingUseCase(userStorage)

val observeDatabaseLoggerState get() = ObserveDatabaseLoggerStateUseCase(userStorage)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.logic.feature.debug

import com.wire.kalium.logic.di.UserStorage
import kotlinx.coroutines.flow.Flow

/**
* Use case to observe the state of the database logger.
*/
class ObserveDatabaseLoggerStateUseCase(
private val userStorage: UserStorage,
) {
suspend operator fun invoke(): Flow<Boolean> = userStorage.database.debugExtension.observeIsProfilingEnabled()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.persistence.db

internal actual fun platformDatabaseLogger(): String = "logcat"
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ actual fun userDatabaseBuilder(
dispatcher = dispatcher,
platformDatabaseData = platformDatabaseData,
isEncrypted = isEncryptionEnabled,
cipherProfile = "logcat",
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.persistence.db

internal actual fun platformDatabaseLogger(): String = "os_log"
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.persistence.db

import app.cash.sqldelight.db.QueryResult
import app.cash.sqldelight.db.SqlDriver
import com.wire.kalium.persistence.dao.MetadataDAO
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

class DebugExtension(
private val sqlDriver: SqlDriver,
private val isEncrypted: Boolean,
private val metaDataDao: MetadataDAO,
) {

suspend fun observeIsProfilingEnabled(): Flow<Boolean> =
metaDataDao.valueByKeyFlow(KEY_CIPHER_PROFILE)
.map { state ->
state?.let { DBProfile.fromString(it) }.let {
it is DBProfile.ON
}
}

/**
* Changes the profiling of the database (cipher_profile) if the profile is specified and the database is encrypted
* @param enabled true to enable profiling, false to disable
*/
suspend fun changeProfiling(enabled: Boolean): Long? =
if (isEncrypted) {
val state = if (enabled) DBProfile.ON.Device else DBProfile.Off
sqlDriver.executeQuery(
identifier = null,
sql = """PRAGMA cipher_profile= '${state.logTarget}';""",
mapper = { cursor ->
cursor.next()
cursor.getLong(0).let { QueryResult.Value<Long?>(it) }
},
parameters = 0,
).value.also {
updateMetadata(state)
}

} else {
error("Cannot change profiling on unencrypted database")
}

private suspend fun updateMetadata(state: DBProfile) {
metaDataDao.insertValue(
value = state.logTarget,
key = KEY_CIPHER_PROFILE
)
}

private companion object {
const val KEY_CIPHER_PROFILE = "cipher_profile"
}
}

sealed interface DBProfile {
val logTarget: String

data object Off : DBProfile {
override val logTarget: String = "off"

override fun toString(): String {
return "off"
}
}

sealed interface ON : DBProfile {
data object Device : ON {
override val logTarget: String = "logcat"
MohamadJaara marked this conversation as resolved.
Show resolved Hide resolved

override fun toString(): String {
return platformDatabaseLogger()
}
}

data class CustomFile(override val logTarget: String) : ON {
override fun toString(): String {
return logTarget
}
}
}

companion object {
fun fromString(value: String): DBProfile = when (value) {
"off" -> Off
platformDatabaseLogger() -> ON.Device
else -> ON.CustomFile(value)
}
}
}

internal expect fun platformDatabaseLogger(): String
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ class UserDatabaseBuilder internal constructor(
private val platformDatabaseData: PlatformDatabaseData,
private val isEncrypted: Boolean,
private val queriesContext: CoroutineContext = KaliumDispatcherImpl.io,
private val cipherProfile: String? = null,
) {

internal val database: UserDatabase = UserDatabase(
Expand Down Expand Up @@ -314,30 +313,18 @@ class UserDatabaseBuilder internal constructor(
queriesContext
)

val debugExtension: DebugExtension
get() = DebugExtension(
sqlDriver = sqlDriver,
metaDataDao = metadataDAO,
isEncrypted = isEncrypted
)

/**
* @return the absolute path of the DB file or null if the DB file does not exist
*/
fun dbFileLocation(): String? = getDatabaseAbsoluteFileLocation(platformDatabaseData, userId)

/**
* Changes the profiling of the database (cipher_profile) if the profile is specified and the database is encrypted
* @param enabled true to enable profiling, false to disable
*/
fun changeProfiling(enabled: Boolean) {
if (isEncrypted && cipherProfile != null) {
val cipherProfileValue = if (enabled) cipherProfile else "off"
sqlDriver.executeQuery(
identifier = null,
sql = "PRAGMA cipher_profile='$cipherProfileValue'",
mapper = {
it.next()
it.getLong(0).let { QueryResult.Value<Long?>(it) }
},
parameters = 0,
)
}
}

/**
* drops DB connection and delete the DB file
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.persistence.db

internal actual fun platformDatabaseLogger(): String {
TODO("Not yet implemented")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.persistence.db

internal actual fun platformDatabaseLogger(): String {
TODO("Not yet implemented")
}
Loading