Feat(Logger): Support persistent logging

This commit is contained in:
2024-08-16 14:39:36 +08:00
parent 3a6fb2a6f0
commit 4ba02420ed
5 changed files with 96 additions and 4 deletions

View File

@@ -184,4 +184,5 @@ dependencies {
ksp(libs.room.compiler) ksp(libs.room.compiler)
implementation(libs.room.runtime) implementation(libs.room.runtime)
implementation(libs.room.ktx) implementation(libs.room.ktx)
implementation(libs.timber)
} }

View File

@@ -2,11 +2,19 @@ package top.fatweb.oxygen.toolbox
import android.app.Application import android.app.Application
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import timber.log.Timber
import top.fatweb.oxygen.toolbox.repository.userdata.UserDataRepository import top.fatweb.oxygen.toolbox.repository.userdata.UserDataRepository
import top.fatweb.oxygen.toolbox.util.OxygenLogTree
import javax.inject.Inject import javax.inject.Inject
@HiltAndroidApp @HiltAndroidApp
class OxygenApplication : Application() { class OxygenApplication : Application() {
@Inject @Inject
lateinit var userDataRepository: UserDataRepository lateinit var userDataRepository: UserDataRepository
override fun onCreate() {
super.onCreate()
Timber.plant(if (BuildConfig.DEBUG) Timber.DebugTree() else OxygenLogTree(this))
}
} }

View File

@@ -11,6 +11,7 @@ import okhttp3.logging.HttpLoggingInterceptor
import top.fatweb.oxygen.toolbox.BuildConfig import top.fatweb.oxygen.toolbox.BuildConfig
import top.fatweb.oxygen.toolbox.data.network.OxygenNetworkDataSource import top.fatweb.oxygen.toolbox.data.network.OxygenNetworkDataSource
import top.fatweb.oxygen.toolbox.network.retrofit.RetrofitOxygenNetwork import top.fatweb.oxygen.toolbox.network.retrofit.RetrofitOxygenNetwork
import top.fatweb.oxygen.toolbox.util.HttpLogger
import javax.inject.Singleton import javax.inject.Singleton
@Module @Module
@@ -27,11 +28,10 @@ internal object NetworkModule {
fun okHttpCallFactory(): Call.Factory = fun okHttpCallFactory(): Call.Factory =
OkHttpClient.Builder() OkHttpClient.Builder()
.addInterceptor( .addInterceptor(
HttpLoggingInterceptor() HttpLoggingInterceptor(HttpLogger())
.apply { .apply {
if (BuildConfig.DEBUG) { level =
level = HttpLoggingInterceptor.Level.BODY if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.BASIC
}
} }
) )
.build() .build()

View File

@@ -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()
}
}

View File

@@ -32,6 +32,7 @@ okhttp = "4.12.0"
androidsvg = "1.4" androidsvg = "1.4"
webviewCompose = "0.33.6" webviewCompose = "0.33.6"
room = "2.6.1" room = "2.6.1"
timber = "5.0.1"
[plugins] [plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" } 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-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
room-runtime = { group = "androidx.room", name = "room-runtime", 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" } room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" }