From 9767d255d344080a7289bc76e80f6093be640f14 Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Sat, 24 Oct 2026 10:20:23 +0800 Subject: [PATCH] Add option to disable Pluto Timber console output --- pluto-plugins/plugins/logger/README.md | 5 ++++ .../pluto/plugins/logger/PlutoTimberTree.kt | 4 ++- .../plugins/logger/lib/build.gradle.kts | 2 ++ .../pluto/plugins/logger/PlutoTimberTree.kt | 21 ++++++++++++-- .../plugins/logger/internal/LogsProcessor.kt | 29 ++++++++++++++++--- .../logger/internal/LogsProcessorTest.kt | 29 +++++++++++++++++++ 6 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 pluto-plugins/plugins/logger/lib/src/test/java/com/pluto/plugins/logger/internal/LogsProcessorTest.kt diff --git a/pluto-plugins/plugins/logger/README.md b/pluto-plugins/plugins/logger/README.md index da8ac450..87768d6c 100644 --- a/pluto-plugins/plugins/logger/README.md +++ b/pluto-plugins/plugins/logger/README.md @@ -50,6 +50,11 @@ Install Pluto as a Tree for Timber: Timber.plant(PlutoTimberTree()); ``` +Console output is enabled by default. To keep these logs in Pluto without duplicating them in Logcat, disable console output when planting the tree: +```kotlin +Timber.plant(PlutoTimberTree(printToConsole = false)) +``` + But if you are connected to Logcat, PlutoLogs behave similar to Log class, with an improvement to tag the method and file name also. In Logcat, PlutoLogs will look like the following. ``` D/onClick(MainActivity.kt:40) | debug_log: button clicked diff --git a/pluto-plugins/plugins/logger/lib-no-op/src/main/java/com/pluto/plugins/logger/PlutoTimberTree.kt b/pluto-plugins/plugins/logger/lib-no-op/src/main/java/com/pluto/plugins/logger/PlutoTimberTree.kt index 49957456..8c2f4960 100644 --- a/pluto-plugins/plugins/logger/lib-no-op/src/main/java/com/pluto/plugins/logger/PlutoTimberTree.kt +++ b/pluto-plugins/plugins/logger/lib-no-op/src/main/java/com/pluto/plugins/logger/PlutoTimberTree.kt @@ -2,7 +2,9 @@ package com.pluto.plugins.logger import timber.log.Timber -class PlutoTimberTree : Timber.Tree() { +class PlutoTimberTree @JvmOverloads constructor( + @Suppress("UNUSED_PARAMETER") printToConsole: Boolean = true +) : Timber.Tree() { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {} } diff --git a/pluto-plugins/plugins/logger/lib/build.gradle.kts b/pluto-plugins/plugins/logger/lib/build.gradle.kts index a1d09d09..330a6485 100644 --- a/pluto-plugins/plugins/logger/lib/build.gradle.kts +++ b/pluto-plugins/plugins/logger/lib/build.gradle.kts @@ -104,4 +104,6 @@ dependencies { implementation(libs.room) ksp(libs.room.compiler) + + testImplementation(libs.junit) } diff --git a/pluto-plugins/plugins/logger/lib/src/main/java/com/pluto/plugins/logger/PlutoTimberTree.kt b/pluto-plugins/plugins/logger/lib/src/main/java/com/pluto/plugins/logger/PlutoTimberTree.kt index a15628ee..1abcda35 100644 --- a/pluto-plugins/plugins/logger/lib/src/main/java/com/pluto/plugins/logger/PlutoTimberTree.kt +++ b/pluto-plugins/plugins/logger/lib/src/main/java/com/pluto/plugins/logger/PlutoTimberTree.kt @@ -9,14 +9,29 @@ import com.squareup.moshi.Types import java.math.BigDecimal import timber.log.Timber -class PlutoTimberTree : Timber.Tree() { +class PlutoTimberTree @JvmOverloads constructor( + private val printToConsole: Boolean = true +) : Timber.Tree() { override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { if (priority == LOG_EVENT_PRIORITY) { val eventData = eventExtractor(message) - LogsProcessor.processEvent(tag ?: "pluto_timber", eventData.first, eventData.second, Thread.currentThread().getStackTraceElement()) + LogsProcessor.processEvent( + tag ?: "pluto_timber", + eventData.first, + eventData.second, + Thread.currentThread().getStackTraceElement(), + printToConsole = printToConsole + ) } else { - LogsProcessor.process(priority, tag ?: "pluto_timber", messageExtractor(message), t, Thread.currentThread().getStackTraceElement()) + LogsProcessor.process( + priority, + tag ?: "pluto_timber", + messageExtractor(message), + t, + Thread.currentThread().getStackTraceElement(), + printToConsole = printToConsole + ) } } diff --git a/pluto-plugins/plugins/logger/lib/src/main/java/com/pluto/plugins/logger/internal/LogsProcessor.kt b/pluto-plugins/plugins/logger/lib/src/main/java/com/pluto/plugins/logger/internal/LogsProcessor.kt index 6b5afe71..218f852d 100644 --- a/pluto-plugins/plugins/logger/lib/src/main/java/com/pluto/plugins/logger/internal/LogsProcessor.kt +++ b/pluto-plugins/plugins/logger/lib/src/main/java/com/pluto/plugins/logger/internal/LogsProcessor.kt @@ -12,18 +12,35 @@ internal class LogsProcessor private constructor() { companion object { - fun process(priority: Int, tag: String, message: String, tr: Throwable?, stackTraceElement: StackTraceElement) { + fun process( + priority: Int, + tag: String, + message: String, + tr: Throwable?, + stackTraceElement: StackTraceElement, + printToConsole: Boolean = true + ) { val stackTrace = stackTraceElement.stackTrace() LogDBHandler.persistLog(priority2Level(priority), tag, message, tr, stackTrace) - consolePrint(priority2Level(priority), tag, message, tr, stackTrace) + printToConsoleIfEnabled(printToConsole) { + consolePrint(priority2Level(priority), tag, message, tr, stackTrace) + } } - fun processEvent(tag: String, event: String, attr: HashMap?, stackTraceElement: StackTraceElement) { + fun processEvent( + tag: String, + event: String, + attr: HashMap?, + stackTraceElement: StackTraceElement, + printToConsole: Boolean = true + ) { val moshi = Moshi.Builder().build() val moshiAdapter: JsonAdapter?> = moshi.adapter(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) val stackTrace = stackTraceElement.stackTrace() LogDBHandler.persistEvent(Level.Event, tag, event, attr, stackTrace) - consolePrint(Level.Event, tag, "$event => ${moshiAdapter.toJson(attr)}", null, stackTrace) + printToConsoleIfEnabled(printToConsole) { + consolePrint(Level.Event, tag, "$event => ${moshiAdapter.toJson(attr)}", null, stackTrace) + } } @SuppressWarnings("ComplexCondition") @@ -57,6 +74,10 @@ internal class LogsProcessor private constructor() { } } + internal inline fun printToConsoleIfEnabled(enabled: Boolean, print: () -> Unit) { + if (enabled) print() + } + private fun consolePrint(level: Level, tag: String, message: String, tr: Throwable?, trace: StackTrace) { val newMessage = StringBuilder().append(message).append("\n").append("[logged from: ${trace.formattedStack()}]").toString() when (level) { diff --git a/pluto-plugins/plugins/logger/lib/src/test/java/com/pluto/plugins/logger/internal/LogsProcessorTest.kt b/pluto-plugins/plugins/logger/lib/src/test/java/com/pluto/plugins/logger/internal/LogsProcessorTest.kt new file mode 100644 index 00000000..1455a9e1 --- /dev/null +++ b/pluto-plugins/plugins/logger/lib/src/test/java/com/pluto/plugins/logger/internal/LogsProcessorTest.kt @@ -0,0 +1,29 @@ +package com.pluto.plugins.logger.internal + +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +class LogsProcessorTest { + @Test + fun doesNotPrintWhenConsoleOutputIsDisabled() { + var printed = false + + LogsProcessor.printToConsoleIfEnabled(false) { + printed = true + } + + assertFalse(printed) + } + + @Test + fun printsWhenConsoleOutputIsEnabled() { + var printed = false + + LogsProcessor.printToConsoleIfEnabled(true) { + printed = true + } + + assertTrue(printed) + } +}