From 14d9f79a9377077d9bbae1d8ac2cd2e54bd36b11 Mon Sep 17 00:00:00 2001 From: Akash Yadav Date: Thu, 16 May 2024 02:38:31 +0530 Subject: [PATCH] fix: use custom logging configurators for configuring logback --- .../itsaky/androidide/app/IDEApplication.kt | 15 +++-- .../logging/IDELoggingConfigurator.kt | 50 +++++++++++++++++ .../androidide/logging/LogcatAppender.java | 7 ++- logger/src/main/resources/logback.xml | 32 ----------- subprojects/tooling-api-impl/build.gradle.kts | 4 ++ .../logging/ToolingLoggingConfigurator.kt | 55 +++++++++++++++++++ testing/common/build.gradle.kts | 6 ++ .../logging/TestingLoggingConfgurator.kt | 46 ++++++++++++++++ 8 files changed, 176 insertions(+), 39 deletions(-) create mode 100644 app/src/main/java/com/itsaky/androidide/logging/IDELoggingConfigurator.kt delete mode 100644 logger/src/main/resources/logback.xml create mode 100644 subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/logging/ToolingLoggingConfigurator.kt create mode 100644 testing/common/src/main/java/com/itsaky/androidide/testing/common/logging/TestingLoggingConfgurator.kt diff --git a/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt b/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt index 43a7ffd23..bc6ea567f 100755 --- a/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt +++ b/app/src/main/java/com/itsaky/androidide/app/IDEApplication.kt @@ -30,6 +30,7 @@ import androidx.work.NetworkType import androidx.work.Operation import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager +import ch.qos.logback.classic.Logger import com.blankj.utilcode.util.ThrowableUtils.getFullStackTrace import com.google.android.material.color.DynamicColors import com.itsaky.androidide.BuildConfig @@ -43,6 +44,8 @@ import com.itsaky.androidide.events.EditorEventsIndex import com.itsaky.androidide.events.LspApiEventsIndex import com.itsaky.androidide.events.LspJavaEventsIndex import com.itsaky.androidide.events.ProjectsApiEventsIndex +import com.itsaky.androidide.logging.LogcatAppender +import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder import com.itsaky.androidide.preferences.internal.DevOpsPreferences import com.itsaky.androidide.preferences.internal.GeneralPreferences import com.itsaky.androidide.preferences.internal.StatPreferences @@ -50,7 +53,6 @@ import com.itsaky.androidide.resources.localization.LocaleProvider import com.itsaky.androidide.stats.AndroidIDEStats import com.itsaky.androidide.stats.StatUploadWorker import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE -import com.itsaky.androidide.tasks.executeAsync import com.itsaky.androidide.treesitter.TreeSitter import com.itsaky.androidide.ui.themes.IDETheme import com.itsaky.androidide.ui.themes.IThemeManager @@ -59,6 +61,9 @@ import com.itsaky.androidide.utils.VMUtils import com.itsaky.androidide.utils.flashError import com.termux.app.TermuxApplication import io.github.rosemoe.sora.widget.schemes.EditorColorScheme +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode @@ -80,17 +85,17 @@ class IDEApplication : TermuxApplication() { RecyclableObjectPool.DEBUG = BuildConfig.DEBUG } + @OptIn(DelicateCoroutinesApi::class) override fun onCreate() { instance = this uncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler() - Thread.setDefaultUncaughtExceptionHandler { thread, th -> handleCrash(thread, th) } + super.onCreate() if (BuildConfig.DEBUG) { StrictMode.setVmPolicy( StrictMode.VmPolicy.Builder(StrictMode.getVmPolicy()).penaltyLog().detectAll().build()) - if (DevOpsPreferences.dumpLogs) { startLogcatReader() } @@ -110,7 +115,9 @@ class IDEApplication : TermuxApplication() { EditorColorScheme.setDefault(SchemeAndroidIDE.newInstance(null)) - executeAsync { IDEColorSchemeProvider.init() } + GlobalScope.launch { + IDEColorSchemeProvider.init() + } } private fun handleCrash(thread: Thread, th: Throwable) { diff --git a/app/src/main/java/com/itsaky/androidide/logging/IDELoggingConfigurator.kt b/app/src/main/java/com/itsaky/androidide/logging/IDELoggingConfigurator.kt new file mode 100644 index 000000000..3a78e6b91 --- /dev/null +++ b/app/src/main/java/com/itsaky/androidide/logging/IDELoggingConfigurator.kt @@ -0,0 +1,50 @@ +/* + * 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 + +import ch.qos.logback.classic.Logger +import ch.qos.logback.classic.LoggerContext +import ch.qos.logback.classic.spi.Configurator +import ch.qos.logback.classic.spi.ConfiguratorRank +import ch.qos.logback.core.spi.ContextAwareBase +import com.google.auto.service.AutoService +import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder + +/** + * Default IDE logging configurator. + * + * @author Akash Yadav + */ +@ConfiguratorRank(ConfiguratorRank.CUSTOM_TOP_PRIORITY) +@AutoService(Configurator::class) +@Suppress("UNUSED") +class IDELoggingConfigurator : ContextAwareBase(), Configurator { + + override fun configure(context: LoggerContext): Configurator.ExecutionStatus { + addInfo("Setting up logging configuration") + + val appender = LogcatAppender() + appender.encoder = IDELogFormatEncoder() + appender.start() + + val rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME) + rootLogger.addAppender(appender) + + return Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY + } +} \ No newline at end of file diff --git a/logger/src/main/java/com/itsaky/androidide/logging/LogcatAppender.java b/logger/src/main/java/com/itsaky/androidide/logging/LogcatAppender.java index 267b04c7f..b37eb97ab 100644 --- a/logger/src/main/java/com/itsaky/androidide/logging/LogcatAppender.java +++ b/logger/src/main/java/com/itsaky/androidide/logging/LogcatAppender.java @@ -18,6 +18,7 @@ import ch.qos.logback.classic.Level; import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.UnsynchronizedAppenderBase; +import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder; import com.itsaky.androidide.logging.utils.LogUtils; /** @@ -38,7 +39,7 @@ import com.itsaky.androidide.logging.utils.LogUtils; */ public class LogcatAppender extends UnsynchronizedAppenderBase { - private PatternLayoutEncoder encoder = null; + private IDELogFormatEncoder encoder = null; private boolean checkLoggable = false; // AndroidIDE Changed: Appender is enabled only when running on Android. @@ -132,7 +133,7 @@ public class LogcatAppender extends UnsynchronizedAppenderBase { * * @return the pattern-layout encoder */ - public PatternLayoutEncoder getEncoder() { + public IDELogFormatEncoder getEncoder() { return this.encoder; } @@ -141,7 +142,7 @@ public class LogcatAppender extends UnsynchronizedAppenderBase { * * @param encoder the pattern-layout encoder */ - public void setEncoder(PatternLayoutEncoder encoder) { + public void setEncoder(IDELogFormatEncoder encoder) { this.encoder = encoder; } diff --git a/logger/src/main/resources/logback.xml b/logger/src/main/resources/logback.xml deleted file mode 100644 index df443c28b..000000000 --- a/logger/src/main/resources/logback.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - false - - - - - - - - - - - - \ No newline at end of file diff --git a/subprojects/tooling-api-impl/build.gradle.kts b/subprojects/tooling-api-impl/build.gradle.kts index 3030cc18a..632957a78 100644 --- a/subprojects/tooling-api-impl/build.gradle.kts +++ b/subprojects/tooling-api-impl/build.gradle.kts @@ -21,6 +21,7 @@ import com.itsaky.androidide.build.config.BuildConfig plugins { id("com.github.johnrengelman.shadow") version "8.1.1" id("java-library") + id("kotlin-kapt") id("org.jetbrains.kotlin.jvm") } @@ -57,12 +58,15 @@ project.tasks.getByName("shadowJar") { } dependencies { + kapt(libs.google.auto.service) + api(projects.subprojects.toolingApi) implementation(projects.buildInfo) implementation(projects.shared) implementation(libs.common.jkotlin) + implementation(libs.google.auto.service.annotations) implementation(libs.xml.xercesImpl) implementation(libs.xml.apis) implementation(libs.tooling.gradleApi) diff --git a/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/logging/ToolingLoggingConfigurator.kt b/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/logging/ToolingLoggingConfigurator.kt new file mode 100644 index 000000000..d94881a53 --- /dev/null +++ b/subprojects/tooling-api-impl/src/main/java/com/itsaky/androidide/tooling/impl/logging/ToolingLoggingConfigurator.kt @@ -0,0 +1,55 @@ +/* + * 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.tooling.impl.logging + +import ch.qos.logback.classic.Logger +import ch.qos.logback.classic.LoggerContext +import ch.qos.logback.classic.spi.Configurator +import ch.qos.logback.classic.spi.ConfiguratorRank +import ch.qos.logback.core.spi.ContextAwareBase +import com.google.auto.service.AutoService +import com.itsaky.androidide.logging.JvmStdErrAppender +import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder + +/** + * Default logging configurator for the Tooling API Runtime. + * + * @author Akash Yadav + */ +@ConfiguratorRank(ConfiguratorRank.CUSTOM_TOP_PRIORITY) +@AutoService(Configurator::class) +@Suppress("UNUSED") +class ToolingLoggingConfigurator : ContextAwareBase(), Configurator { + + override fun configure(context: LoggerContext): Configurator.ExecutionStatus { + addInfo("Setting up logging configuration for tooling API") + + val stdErrAppender = JvmStdErrAppender() + stdErrAppender.encoder = IDELogFormatEncoder() + stdErrAppender.start() + + val toolingApiAppender = ToolingApiAppender() + toolingApiAppender.start() + + val rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME) + rootLogger.addAppender(stdErrAppender) + rootLogger.addAppender(toolingApiAppender) + + return Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY + } +} \ No newline at end of file diff --git a/testing/common/build.gradle.kts b/testing/common/build.gradle.kts index ddfa3ea6b..7dff8466d 100644 --- a/testing/common/build.gradle.kts +++ b/testing/common/build.gradle.kts @@ -18,9 +18,15 @@ @Suppress("JavaPluginLanguageLevel") plugins { id("java-library") + id("kotlin-kapt") id("org.jetbrains.kotlin.jvm") } dependencies { + implementation(project(":subprojects:tooling-api-impl")) + kapt(libs.google.auto.service) + implementation(libs.google.auto.service.annotations) + api(libs.tests.junit) + api(projects.logger) } \ No newline at end of file diff --git a/testing/common/src/main/java/com/itsaky/androidide/testing/common/logging/TestingLoggingConfgurator.kt b/testing/common/src/main/java/com/itsaky/androidide/testing/common/logging/TestingLoggingConfgurator.kt new file mode 100644 index 000000000..ea4a0b946 --- /dev/null +++ b/testing/common/src/main/java/com/itsaky/androidide/testing/common/logging/TestingLoggingConfgurator.kt @@ -0,0 +1,46 @@ +/* + * 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.testing.common.logging + +import ch.qos.logback.classic.Logger +import ch.qos.logback.classic.LoggerContext +import ch.qos.logback.classic.spi.Configurator +import ch.qos.logback.classic.spi.ConfiguratorRank +import ch.qos.logback.core.spi.ContextAwareBase +import com.google.auto.service.AutoService +import com.itsaky.androidide.logging.JvmStdErrAppender +import com.itsaky.androidide.logging.encoder.IDELogFormatEncoder + +@ConfiguratorRank(ConfiguratorRank.CUSTOM_HIGH_PRIORITY) +@AutoService(Configurator::class) +@Suppress("UNUSED") +class ToolingLoggingConfigurator : ContextAwareBase(), Configurator { + + override fun configure(context: LoggerContext): Configurator.ExecutionStatus { + addInfo("Setting up logging configuration for test runtime") + + val stdErrAppender = JvmStdErrAppender() + stdErrAppender.encoder = IDELogFormatEncoder() + stdErrAppender.start() + + val rootLogger = context.getLogger(Logger.ROOT_LOGGER_NAME) + rootLogger.addAppender(stdErrAppender) + + return Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY + } +} \ No newline at end of file