From 4ba02420edd480173aa704c4905c5ddaa78c8a89 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Fri, 16 Aug 2024 14:39:36 +0800 Subject: [PATCH] Feat(Logger): Support persistent logging --- app/build.gradle.kts | 1 + .../oxygen/toolbox/OxygenApplication.kt | 8 ++ .../fatweb/oxygen/toolbox/di/NetworkModule.kt | 8 +- .../oxygen/toolbox/util/OxygenLogger.kt | 81 +++++++++++++++++++ gradle/libs.versions.toml | 2 + 5 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 app/src/main/kotlin/top/fatweb/oxygen/toolbox/util/OxygenLogger.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c2d67d0..8d0e142 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -184,4 +184,5 @@ dependencies { ksp(libs.room.compiler) implementation(libs.room.runtime) implementation(libs.room.ktx) + implementation(libs.timber) } \ No newline at end of file diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/OxygenApplication.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/OxygenApplication.kt index c5a3acd..0e15135 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/OxygenApplication.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/OxygenApplication.kt @@ -2,11 +2,19 @@ package top.fatweb.oxygen.toolbox import android.app.Application import dagger.hilt.android.HiltAndroidApp +import timber.log.Timber import top.fatweb.oxygen.toolbox.repository.userdata.UserDataRepository +import top.fatweb.oxygen.toolbox.util.OxygenLogTree import javax.inject.Inject @HiltAndroidApp class OxygenApplication : Application() { @Inject lateinit var userDataRepository: UserDataRepository + + override fun onCreate() { + super.onCreate() + + Timber.plant(if (BuildConfig.DEBUG) Timber.DebugTree() else OxygenLogTree(this)) + } } \ No newline at end of file diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/di/NetworkModule.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/di/NetworkModule.kt index 9368989..0ea038a 100644 --- a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/di/NetworkModule.kt +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/di/NetworkModule.kt @@ -11,6 +11,7 @@ import okhttp3.logging.HttpLoggingInterceptor import top.fatweb.oxygen.toolbox.BuildConfig import top.fatweb.oxygen.toolbox.data.network.OxygenNetworkDataSource import top.fatweb.oxygen.toolbox.network.retrofit.RetrofitOxygenNetwork +import top.fatweb.oxygen.toolbox.util.HttpLogger import javax.inject.Singleton @Module @@ -27,11 +28,10 @@ internal object NetworkModule { fun okHttpCallFactory(): Call.Factory = OkHttpClient.Builder() .addInterceptor( - HttpLoggingInterceptor() + HttpLoggingInterceptor(HttpLogger()) .apply { - if (BuildConfig.DEBUG) { - level = HttpLoggingInterceptor.Level.BODY - } + level = + if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.BASIC } ) .build() diff --git a/app/src/main/kotlin/top/fatweb/oxygen/toolbox/util/OxygenLogger.kt b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/util/OxygenLogger.kt new file mode 100644 index 0000000..e620386 --- /dev/null +++ b/app/src/main/kotlin/top/fatweb/oxygen/toolbox/util/OxygenLogger.kt @@ -0,0 +1,81 @@ +package top.fatweb.oxygen.toolbox.util + +import android.annotation.SuppressLint +import android.content.Context +import android.util.Log +import androidx.annotation.IntDef +import okhttp3.logging.HttpLoggingInterceptor +import timber.log.Timber +import java.io.File +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +class HttpLogger : HttpLoggingInterceptor.Logger { + override fun log(message: String) { + Timber.i(message) + } +} + +class OxygenLogTree( + context: Context +) : Timber.DebugTree() { + @IntDef(Log.ASSERT, Log.ERROR, Log.WARN, Log.INFO, Log.DEBUG, Log.VERBOSE) + @Retention( + AnnotationRetention.SOURCE + ) + annotation class Level + + private val fileNamePrefix = "oxygen_toolbox" + private val fileNamePostfix = ".log" + private val maxFileSize: Long = 10 * 1024 * 1024 + private val dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + private val logDir = File(context.cacheDir, "logs") + private val logFile = File(logDir, "$fileNamePrefix$fileNamePostfix") + + @SuppressLint("LogNotTimber") + override fun log(@Level priority: Int, tag: String?, message: String, t: Throwable?) { + checkFile() + try { + if (logFile.length() >= maxFileSize) { + rotateLogFile() + } + logFile.appendText(format(priority, tag, message, t)) + } catch (e: Exception) { + Log.e("OxygenLogTree", "Error writing log message to file", e) + } + } + + private fun checkFile() { + try { + if (!logDir.exists()) { + logDir.mkdirs() + } + logFile.createNewFile() + } catch (_: Exception) {} + } + + private fun format(@Level priority: Int, tag: String?, message: String, t: Throwable?) = "${ + LocalDateTime.now() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")) + }\t$tag\t${ + when (priority) { + Log.ASSERT -> "Assert: " + Log.DEBUG -> "Debug: " + Log.ERROR -> "Error: " + Log.INFO -> "Info: " + Log.VERBOSE -> "Verbose: " + Log.WARN -> "Warn: " + else -> "Unknown: " + } + } $message${t?.run { " ${toString()}" } ?: ""}\n" + + private fun rotateLogFile() { + logFile.renameTo( + File( + logFile.parent, + "$fileNamePrefix${LocalDateTime.now().format(dateFormat)}$fileNamePostfix" + ) + ) + logFile.createNewFile() + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6270cf2..8ec220e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,6 +32,7 @@ okhttp = "4.12.0" androidsvg = "1.4" webviewCompose = "0.33.6" room = "2.6.1" +timber = "5.0.1" [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } @@ -100,3 +101,4 @@ compose-webview = { group = "io.github.kevinnzou", name = "compose-webview", ver room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" } room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" } room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" } +timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" }