Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 560910c7 authored by Rafael Tonholo's avatar Rafael Tonholo
Browse files

fix(logging): all logs logged with AndroidConsoleLogSink as tag

parent 421c8c07
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -11,7 +11,9 @@ private class AndroidConsoleLogSink(
) : ConsoleLogSink {

    override fun log(event: LogEvent) {
        val timber = event.tag?.let { Timber.tag(it) } ?: Timber
        val timber = event.tag
            ?.let { Timber.tag(it) }
            ?: Timber.tag(event.composeTag(ignoredClasses = IGNORE_CLASSES) ?: this::class.java.name)

        when (event.level) {
            LogLevel.VERBOSE -> timber.v(event.throwable, event.message)
@@ -21,4 +23,15 @@ private class AndroidConsoleLogSink(
            LogLevel.ERROR -> timber.e(event.throwable, event.message)
        }
    }

    companion object {
        private val IGNORE_CLASSES = setOf(
            Timber::class.java.name,
            Timber.Forest::class.java.name,
            Timber.Tree::class.java.name,
            Timber.DebugTree::class.java.name,
            AndroidConsoleLogSink::class.java.name,
            // Add other classes to ignore if needed
        )
    }
}
+67 −0
Original line number Diff line number Diff line
package net.thunderbird.core.logging.console

import net.thunderbird.core.logging.DefaultLogger
import net.thunderbird.core.logging.LogEvent
import net.thunderbird.core.logging.Logger

/**
 * Composes a tag for the given [LogEvent].
 *
 * If the event has a tag, it is used; otherwise, a tag is extracted from the stack trace.
 * The tag is processed using the [processTag] method before being returned.
 *
 * @receiver The [LogEvent] to compose a tag for.
 * @param ignoredClasses The set of Class full name to be ignored.
 * @param processTag Processes a tag before it is used for logging.
 * @return The composed tag, or null if no tag could be determined.
 */
internal fun LogEvent.composeTag(
    ignoredClasses: Set<String>,
    processTag: (String) -> String? = { it },
): String? {
    // If a tag is provided, use it; otherwise, extract it from the stack trace
    val rawTag = tag ?: extractTagFromStackTrace(ignoredClasses)
    // Process the tag before returning it
    return rawTag?.let { processTag(it) }
}

/**
 * Extracts a tag from the stack trace.
 *
 * @return The extracted tag, or null if no suitable tag could be found.
 */
private fun extractTagFromStackTrace(ignoredClasses: Set<String>): String? {
    // Some classes are not available to this module, and we don't want
    // to add the dependency just for class filtering.
    val ignoredClasses = ignoredClasses + setOf(
        "net.thunderbird.core.logging.console.ComposeLogTagKt",
        "net.thunderbird.core.logging.composite.DefaultCompositeLogSink",
        "net.thunderbird.core.logging.legacy.Log",
        Logger::class.java.name,
        DefaultLogger::class.java.name,
    )

    @Suppress("ThrowingExceptionsWithoutMessageOrCause")
    val stackTrace = Throwable().stackTrace

    return stackTrace
        .firstOrNull { element ->
            ignoredClasses.none { element.className.startsWith(it) }
        }
        ?.let(::createStackElementTag)
}

/**
 * Creates a tag from a stack trace element.
 *
 * @param element The stack trace element to create a tag from.
 * @return The created tag.
 */
private fun createStackElementTag(element: StackTraceElement): String {
    var tag = element.className.substringAfterLast('.')
    val regex = "(\\$\\d+)+$".toRegex()
    if (regex.containsMatchIn(input = tag)) {
        tag = regex.replace(input = tag, replacement = "")
    }
    return tag
}
+10 −2
Original line number Diff line number Diff line
@@ -15,10 +15,18 @@ private class JvmConsoleLogSink(
    }

    private fun composeMessage(event: LogEvent): String {
        return if (event.tag != null) {
            "[${event.tag}] ${event.message}"
        val tag = event.tag ?: event.composeTag(ignoredClasses = IGNORE_CLASSES)
        return if (tag != null) {
            "[$tag] ${event.message}"
        } else {
            event.message
        }
    }

    companion object {
        private val IGNORE_CLASSES = setOf(
            JvmConsoleLogSink::class.java.name,
            // Add other classes to ignore if needed
        )
    }
}