diff --git a/app/src/main/java/com/itsaky/androidide/logging/LifecycleAwareAppender.kt b/app/src/main/java/com/itsaky/androidide/logging/LifecycleAwareAppender.kt index d7e4a05e2..6b116aa86 100644 --- a/app/src/main/java/com/itsaky/androidide/logging/LifecycleAwareAppender.kt +++ b/app/src/main/java/com/itsaky/androidide/logging/LifecycleAwareAppender.kt @@ -20,10 +20,10 @@ package com.itsaky.androidide.logging import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleOwner -import ch.qos.logback.classic.encoder.PatternLayoutEncoder import ch.qos.logback.classic.spi.ILoggingEvent import ch.qos.logback.core.AppenderBase import ch.qos.logback.core.Context +import com.itsaky.androidide.logging.encoder.IDELogFormatLayout /** * An [AppenderBase] implementation to show the logs in the GUI. @@ -36,13 +36,11 @@ class LifecycleAwareAppender @JvmOverloads constructor( ) : AppenderBase(), LifecycleEventObserver { private var currentState: Lifecycle.State? = null - private val encoder = PatternLayoutEncoder() + private val logLayout = IDELogFormatLayout() init { setName("LifecycleAwareAppender") - - encoder.pattern = "%date %-5level [%thread] %logger{0}:" - encoder.isOutputPatternAsHeader = true + logLayout.isOmitMessage = true } fun attachTo(lifecycleOwner: LifecycleOwner) = attachTo(lifecycleOwner.lifecycle) @@ -66,19 +64,19 @@ class LifecycleAwareAppender @JvmOverloads constructor( } override fun start() { - this.encoder.start() + this.logLayout.start() super.start() } override fun stop() { super.stop() - this.encoder.stop() + this.logLayout.stop() this.consumer = null } override fun setContext(context: Context?) { super.setContext(context) - this.encoder.context = context + this.logLayout.context = context } override fun append(eventObject: ILoggingEvent?) { @@ -88,7 +86,7 @@ class LifecycleAwareAppender @JvmOverloads constructor( // When rendering the logs in the GUI, we need to ensure that the message does not span multiple lines // if it does, we need to prefix the message with the layout header - val prefix = encoder.layout.doLayout(eventObject) + val prefix = logLayout.doLayout(eventObject) eventObject.formattedMessage.split('\n').forEach { consumer?.invoke("$prefix $it") } diff --git a/logger/src/main/java/com/itsaky/androidide/logging/encoder/IDELogFormatEncoder.java b/logger/src/main/java/com/itsaky/androidide/logging/encoder/IDELogFormatEncoder.java index 1132d97bf..1bc6135c4 100644 --- a/logger/src/main/java/com/itsaky/androidide/logging/encoder/IDELogFormatEncoder.java +++ b/logger/src/main/java/com/itsaky/androidide/logging/encoder/IDELogFormatEncoder.java @@ -17,20 +17,13 @@ package com.itsaky.androidide.logging.encoder; -import ch.qos.logback.classic.encoder.PatternLayoutEncoder; +import ch.qos.logback.core.encoder.LayoutWrappingEncoder; /** * Encoder to format the log events in AndroidIDE. * * @author Akash Yadav */ -public class IDELogFormatEncoder extends PatternLayoutEncoder { +public class IDELogFormatEncoder extends LayoutWrappingEncoder { - private static final String LOG_PATTERN = "%date %-5level [%thread] %logger{0}: %msg%n"; - - public IDELogFormatEncoder() { - super(); - setPattern(LOG_PATTERN); - setOutputPatternAsHeader(true); - } } diff --git a/logger/src/main/java/com/itsaky/androidide/logging/encoder/IDELogFormatLayout.java b/logger/src/main/java/com/itsaky/androidide/logging/encoder/IDELogFormatLayout.java new file mode 100644 index 000000000..7b5fd49a5 --- /dev/null +++ b/logger/src/main/java/com/itsaky/androidide/logging/encoder/IDELogFormatLayout.java @@ -0,0 +1,67 @@ +/* + * This file is part of AndroidIDE. + * + * AndroidIDE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AndroidIDE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with AndroidIDE. If not, see . + */ + +package com.itsaky.androidide.logging.encoder; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +/** + * Log layout for AndroidIDE. + * + * @author Akash Yadav + */ +public class IDELogFormatLayout extends LayoutBase { + + private boolean omitMessage = false; + + public void setOmitMessage(boolean omitMessage) { + this.omitMessage = omitMessage; + } + + public boolean isOmitMessage() { + return omitMessage; + } + + @Override + public String doLayout(ILoggingEvent event) { + final SimpleDateFormat format = new SimpleDateFormat("dd-MM HH:mm:ss.SSS", Locale.ROOT); + final var date = format.format(new Date(event.getTimeStamp())); + + final var builder = new StringBuilder(); + builder.append(date); + builder.append(' '); + builder.append(String.format(Locale.ROOT, "%5s", event.getLevel().levelStr)); + builder.append(' '); + builder.append("["); + builder.append(event.getThreadName()); + builder.append("]"); + builder.append(' '); + builder.append(event.getLoggerName()); + builder.append(": "); + + if (!isOmitMessage()) { + builder.append(event.getFormattedMessage()); + builder.append(System.lineSeparator()); + } + + return builder.toString(); + } +} diff --git a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/common.kt b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/common.kt index c102c6974..a131102fc 100644 --- a/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/common.kt +++ b/subprojects/tooling-api-impl/src/test/java/com/itsaky/androidide/tooling/impl/common.kt @@ -17,11 +17,8 @@ package com.itsaky.androidide.tooling.impl -import ch.qos.logback.classic.spi.ILoggingEvent -import ch.qos.logback.core.AppenderBase import com.android.builder.model.v2.ide.LibraryType import com.google.common.truth.Truth.assertThat -import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder import com.itsaky.androidide.tooling.api.IAndroidProject import com.itsaky.androidide.tooling.api.IJavaProject import com.itsaky.androidide.tooling.api.IProject @@ -33,21 +30,6 @@ import com.itsaky.androidide.tooling.api.models.JavaModuleProjectDependency import com.itsaky.androidide.tooling.api.models.JavaProjectMetadata import com.itsaky.androidide.tooling.api.models.params.StringParameter -internal class CollectingAppender : AppenderBase() { - - private val encoder = IDELogFormatEncoder() - private val string = StringBuilder() - - override fun append(eventObject: ILoggingEvent?) { - string.append(encoder.layout.doLayout(eventObject)) - string.append(System.lineSeparator()) - } - - override fun toString(): String { - return string.toString() - } -} - internal fun performBasicProjectAssertions(project: IProject, server: IToolingApiServer) { assertThat(project).isNotNull()