feat: Write logs to file

This commit is contained in:
Ahmad Ansori Palembani 2024-11-22 12:57:52 +07:00
parent 5d6d25c261
commit b1766ebb94
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
5 changed files with 64 additions and 4 deletions

View file

@ -24,6 +24,7 @@ The format is simplified version of [Keep a Changelog](https://keepachangelog.co
- Tell user to restart the app when User-Agent is changed (@NGB-Was-Taken) - Tell user to restart the app when User-Agent is changed (@NGB-Was-Taken)
- Re-enable fetching licensed manga (@Animeboynz) - Re-enable fetching licensed manga (@Animeboynz)
- Bangumi search now shows the score and summary of a search result (@MajorTanya) - Bangumi search now shows the score and summary of a search result (@MajorTanya)
- Logs are now written to a file for easier debugging
### Fixes ### Fixes
- Fixed only few DoH provider is actually being used (Cloudflare, Google, AdGuard, and Quad9) - Fixed only few DoH provider is actually being used (Cloudflare, Google, AdGuard, and Quad9)
@ -32,7 +33,7 @@ The format is simplified version of [Keep a Changelog](https://keepachangelog.co
- Handle some uncaught crashes - Handle some uncaught crashes
- Fixed crashes due to GestureDetector's firstEvent is sometimes null on some devices - Fixed crashes due to GestureDetector's firstEvent is sometimes null on some devices
- Fixed download failed due to invalid XML 1.0 character - Fixed download failed due to invalid XML 1.0 character
- Fixed issues with shizuku in a multi user setup (@Redjard) - Fixed issues with shizuku in a multi-user setup (@Redjard)
### Other ### Other
- Simplify network helper code - Simplify network helper code

View file

@ -23,6 +23,8 @@ import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.multidex.MultiDex import androidx.multidex.MultiDex
import co.touchlab.kermit.Logger import co.touchlab.kermit.Logger
import co.touchlab.kermit.io.RollingFileLogWriter
import co.touchlab.kermit.io.RollingFileLogWriterConfig
import coil3.ImageLoader import coil3.ImageLoader
import coil3.PlatformContext import coil3.PlatformContext
import coil3.SingletonImageLoader import coil3.SingletonImageLoader
@ -56,10 +58,17 @@ import eu.kanade.tachiyomi.util.system.ImageUtil
import eu.kanade.tachiyomi.util.system.launchIO import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.localeContext import eu.kanade.tachiyomi.util.system.localeContext
import eu.kanade.tachiyomi.util.system.notification import eu.kanade.tachiyomi.util.system.notification
import eu.kanade.tachiyomi.util.system.setToDefault
import java.security.Security import java.security.Security
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.io.files.Path
import org.conscrypt.Conscrypt import org.conscrypt.Conscrypt
import org.koin.core.context.startKoin import org.koin.core.context.startKoin
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
@ -72,6 +81,7 @@ import yokai.core.di.preferenceModule
import yokai.core.migration.Migrator import yokai.core.migration.Migrator
import yokai.core.migration.migrations.migrations import yokai.core.migration.migrations.migrations
import yokai.domain.base.BasePreferences import yokai.domain.base.BasePreferences
import yokai.domain.storage.StorageManager
import yokai.i18n.MR import yokai.i18n.MR
import yokai.util.lang.getString import yokai.util.lang.getString
@ -80,15 +90,30 @@ open class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.F
val preferences: PreferencesHelper by injectLazy() val preferences: PreferencesHelper by injectLazy()
val basePreferences: BasePreferences by injectLazy() val basePreferences: BasePreferences by injectLazy()
val networkPreferences: NetworkPreferences by injectLazy() val networkPreferences: NetworkPreferences by injectLazy()
private val storageManager: StorageManager by injectLazy()
private val disableIncognitoReceiver = DisableIncognitoReceiver() private val disableIncognitoReceiver = DisableIncognitoReceiver()
private fun buildWritersToAdd(
logPath: Path?,
logFileName: String?,
) = buildList {
if (!BuildConfig.DEBUG) Logger.addLogWriter(CrashlyticsLogWriter())
if (logPath != null && logFileName != null) add(
RollingFileLogWriter(
config = RollingFileLogWriterConfig(
logFileName,
logFilePath = logPath,
)
)
)
}
@SuppressLint("LaunchActivityFromNotification") @SuppressLint("LaunchActivityFromNotification")
override fun onCreate() { override fun onCreate() {
super<Application>.onCreate() super<Application>.onCreate()
if (!BuildConfig.DEBUG) Logger.addLogWriter(CrashlyticsLogWriter())
// TLS 1.3 support for Android 10 and below // TLS 1.3 support for Android 10 and below
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Security.insertProviderAt(Conscrypt.newProvider(), 1) Security.insertProviderAt(Conscrypt.newProvider(), 1)
@ -108,6 +133,25 @@ open class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.F
val scope = ProcessLifecycleOwner.get().lifecycleScope val scope = ProcessLifecycleOwner.get().lifecycleScope
combine(
storageManager.changes,
// Just in case we have more things to add in the future...
) { _ ->
listOf(storageManager.getLogsDirectory())
}
.distinctUntilChanged()
.onEach {
val logPath = it[0]?.filePath?.let { path -> Path(path) }
val date = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date())
Logger.setToDefault(
buildWritersToAdd(
logPath = logPath,
logFileName = "$date-${BuildConfig.BUILD_TYPE}.log"
)
)
}
.launchIn(scope)
basePreferences.crashReport().changes() basePreferences.crashReport().changes()
.onEach { .onEach {
try { try {

View file

@ -42,6 +42,7 @@ class StorageManager(
} }
parent.createDirectory(COVERS_PATH) parent.createDirectory(COVERS_PATH)
parent.createDirectory(PAGES_PATH) parent.createDirectory(PAGES_PATH)
parent.createDirectory(LOGS_PATH)
} }
_changes.send(Unit) _changes.send(Unit)
} }
@ -76,6 +77,10 @@ class StorageManager(
fun getPagesDirectory(): UniFile? { fun getPagesDirectory(): UniFile? {
return baseDir?.createDirectory(PAGES_PATH) return baseDir?.createDirectory(PAGES_PATH)
} }
fun getLogsDirectory(): UniFile? {
return baseDir?.createDirectory(LOGS_PATH)
}
} }
private const val BACKUPS_PATH = "backup" private const val BACKUPS_PATH = "backup"
@ -84,3 +89,4 @@ private const val DOWNLOADS_PATH = "downloads"
private const val LOCAL_SOURCE_PATH = "local" private const val LOCAL_SOURCE_PATH = "local"
private const val COVERS_PATH = "covers" private const val COVERS_PATH = "covers"
private const val PAGES_PATH = "pages" private const val PAGES_PATH = "pages"
private const val LOGS_PATH = "logs"

View file

@ -1,6 +1,14 @@
package eu.kanade.tachiyomi.util.system package eu.kanade.tachiyomi.util.system
import co.touchlab.kermit.LogWriter
import co.touchlab.kermit.Logger import co.touchlab.kermit.Logger
import co.touchlab.kermit.platformLogWriter
fun Logger.w(e: Throwable) = w(e) { "Something is not right..." } fun Logger.w(e: Throwable) = w(e) { "Something is not right..." }
fun Logger.e(e: Throwable) = e(e) { "Something went wrong!" } fun Logger.e(e: Throwable) = e(e) { "Something went wrong!" }
fun Logger.setToDefault(
writersToAdd: List<LogWriter>,
) {
Logger.setLogWriters(listOf(platformLogWriter()) + writersToAdd)
Logger.setTag("Yokai")
}

View file

@ -44,6 +44,7 @@ flexible-adapter = { module = "com.github.arkon.FlexibleAdapter:flexible-adapter
image-decoder = { module = "com.github.tachiyomiorg:image-decoder", version = "41c059e540" } image-decoder = { module = "com.github.tachiyomiorg:image-decoder", version = "41c059e540" }
kermit = { module = "co.touchlab:kermit", version.ref = "kermit" } kermit = { module = "co.touchlab:kermit", version.ref = "kermit" }
kermit-io = { module = "co.touchlab:kermit-io", version.ref = "kermit" }
koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koin" } koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koin" }
koin-core = { module = "io.insert-koin:koin-core" } koin-core = { module = "io.insert-koin:koin-core" }
@ -113,7 +114,7 @@ sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }
db = [ "sqldelight-coroutines" ] db = [ "sqldelight-coroutines" ]
db-android = [ "sqldelight-android-driver", "sqldelight-android-paging" ] db-android = [ "sqldelight-android-driver", "sqldelight-android-paging" ]
coil = [ "coil3", "coil3-svg", "coil3-gif", "coil3-okhttp" ] coil = [ "coil3", "coil3-svg", "coil3-gif", "coil3-okhttp" ]
logging = [ "kermit" ] logging = [ "kermit", "kermit-io" ]
# FIXME: Uncomment once SQLDelight support KMP AndroidX SQLiteDriver # FIXME: Uncomment once SQLDelight support KMP AndroidX SQLiteDriver
#sqlite = [ "sqlite", "sqlite-ktx" ] #sqlite = [ "sqlite", "sqlite-ktx" ]
sqlite = [ "sqlite-ktx" ] sqlite = [ "sqlite-ktx" ]