MiraiConsoleLoggerController

This commit is contained in:
Karlatemp 2020-10-24 19:34:16 +08:00
parent 4564531f8b
commit 96017ae862
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
11 changed files with 316 additions and 17 deletions

View File

@ -18,13 +18,13 @@ import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
import net.mamoe.mirai.console.command.ConsoleCommandSender
import net.mamoe.mirai.console.data.PluginDataStorage
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
import net.mamoe.mirai.console.logging.MiraiConsoleLoggerController
import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
import net.mamoe.mirai.console.plugin.loader.PluginLoader
import net.mamoe.mirai.console.util.ConsoleInput
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.MiraiLogger
import java.nio.file.Path
import java.util.*
import java.util.concurrent.locks.ReentrantLock
@ -161,13 +161,7 @@ public interface MiraiConsoleImplementation : CoroutineScope {
*/
public fun createLoginSolver(requesterBot: Long, configuration: BotConfiguration): LoginSolver
/**
* 创建一个 [MiraiLogger].
*
* **注意**: [MiraiConsole] 会将 [net.mamoe.mirai.utils.DefaultLogger] 设置为 `MiraiConsole::createLogger`.
* 因此不要在 [createLogger] 中调用 [net.mamoe.mirai.utils.DefaultLogger]
*/
public fun createLogger(identity: String?): MiraiLogger
public val loggerController: MiraiConsoleLoggerController
public companion object {
internal lateinit var instance: MiraiConsoleImplementation

View File

@ -31,12 +31,17 @@ import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
import net.mamoe.mirai.console.internal.command.CommandManagerImpl
import net.mamoe.mirai.console.internal.data.builtins.AutoLoginConfig
import net.mamoe.mirai.console.internal.data.builtins.ConsoleDataScope
import net.mamoe.mirai.console.internal.data.builtins.LoggerConfig
import net.mamoe.mirai.console.internal.data.castOrNull
import net.mamoe.mirai.console.internal.extension.BuiltInSingletonExtensionSelector
import net.mamoe.mirai.console.internal.extension.GlobalComponentStorage
import net.mamoe.mirai.console.internal.permission.BuiltInPermissionService
import net.mamoe.mirai.console.internal.plugin.PluginManagerImpl
import net.mamoe.mirai.console.internal.util.autoHexToBytes
import net.mamoe.mirai.console.logging.MiraiConsoleLoggerController
import net.mamoe.mirai.console.logging.MiraiConsoleLoggerControllerForFrontend
import net.mamoe.mirai.console.logging.MiraiConsoleLoggerUnused
import net.mamoe.mirai.console.logging.MiraiDelegateLogger
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.grantPermission
import net.mamoe.mirai.console.permission.RootPermission
@ -82,6 +87,7 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
override val dataStorageForBuiltIns: PluginDataStorage by instance::dataStorageForBuiltIns
override val configStorageForBuiltIns: PluginDataStorage by instance::configStorageForBuiltIns
override val consoleInput: ConsoleInput by instance::consoleInput
override val loggerController: MiraiConsoleLoggerController by instance::loggerController
override fun createLoginSolver(requesterBot: Long, configuration: BotConfiguration): LoginSolver =
instance.createLoginSolver(requesterBot, configuration)
@ -90,10 +96,22 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
DefaultLogger = this::createLogger
}
override fun createLogger(identity: String?): MiraiLogger = instance.createLogger(identity)
override fun createLogger(identity: String?): MiraiLogger {
val controller = loggerController
val logger = MiraiConsoleLoggerUnused(controller, identity)
val delegate = MiraiDelegateLogger(logger)
logger.delegateLogger = delegate
return delegate
}
@Suppress("RemoveRedundantBackticks")
internal fun doStart() {
phase `setup logger controller`@{
if (loggerController is MiraiConsoleLoggerControllerForFrontend) {
ConsoleDataScope.addAndReloadConfig(LoggerConfig)
}
}
phase `greeting`@{
val buildDateFormatted =
buildDate.atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
@ -102,7 +120,6 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
mainLogger.info { "Backend: version $version, built on $buildDateFormatted." }
mainLogger.info { frontEndDescription.render() }
}
phase `check coroutineContext`@{
if (coroutineContext[Job] == null) {
throw MalformedMiraiConsoleImplementationError("The coroutineContext given to MiraiConsole must have a Job in it.")

View File

@ -0,0 +1,50 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*
*/
package net.mamoe.mirai.console.internal.data.builtins
import net.mamoe.mirai.console.data.AutoSavePluginConfig
import net.mamoe.mirai.console.data.value
import net.mamoe.mirai.utils.SimpleLogger
import java.util.*
internal object LoggerConfig : AutoSavePluginConfig("Logger") {
val defaultPriority by value(LogPriority.INFO)
val loggers: Map<String, LogPriority> by value(
mapOf("example.logger" to LogPriority.NONE)
)
enum class LogPriority {
ALL(null),
VERBOSE,
DEBUG,
INFO,
WARNING,
ERROR,
NONE(null);
var mapped: SimpleLogger.LogPriority? = null
// resolve <clinit> NullPointerException
private object Holder {
@JvmField
val mapping = EnumMap<SimpleLogger.LogPriority, LogPriority>(SimpleLogger.LogPriority::class.java)
}
companion object {
fun by(priority: SimpleLogger.LogPriority): LogPriority = Holder.mapping[priority]!!
}
constructor(void: Nothing?)
constructor() {
mapped = SimpleLogger.LogPriority.valueOf(name)
Holder.mapping[mapped] = this
}
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*
*/
package net.mamoe.mirai.console.logging
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.MiraiLoggerPlatformBase
import net.mamoe.mirai.utils.SimpleLogger
internal class MiraiConsoleLogger(
private val controller: MiraiConsoleLoggerController,
val logger: MiraiLogger
) : MiraiLoggerPlatformBase() {
override val identity: String? get() = logger.identity
override val isEnabled: Boolean get() = logger.isEnabled
override fun info0(message: String?, e: Throwable?) {
if (controller.shouldLog(identity, SimpleLogger.LogPriority.INFO))
logger.info(message, e)
}
override fun warning0(message: String?, e: Throwable?) {
if (controller.shouldLog(identity, SimpleLogger.LogPriority.WARNING))
logger.warning(message, e)
}
override fun debug0(message: String?, e: Throwable?) {
if (controller.shouldLog(identity, SimpleLogger.LogPriority.DEBUG))
logger.debug(message, e)
}
override fun error0(message: String?, e: Throwable?) {
if (controller.shouldLog(identity, SimpleLogger.LogPriority.ERROR))
logger.error(message, e)
}
override fun verbose0(message: String?, e: Throwable?) {
if (controller.shouldLog(identity, SimpleLogger.LogPriority.VERBOSE))
logger.verbose(message, e)
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*
*/
package net.mamoe.mirai.console.logging
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.SimpleLogger
import java.util.concurrent.atomic.AtomicReference
@ConsoleExperimentalApi
@ConsoleFrontEndImplementation
public interface MiraiConsoleLoggerController {
public fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean
public val cacheLoggers: Boolean
public fun newLoggerImpl(identity: String?): MiraiLogger
public fun allocateLoggerRegistration(identity: String?): AtomicReference<Any>
}

View File

@ -0,0 +1,39 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*
*/
package net.mamoe.mirai.console.logging
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.internal.data.builtins.ConsoleDataScope
import net.mamoe.mirai.console.internal.data.builtins.LoggerConfig
import net.mamoe.mirai.console.util.ConsoleInternalApi
import net.mamoe.mirai.utils.SimpleLogger
@ConsoleFrontEndImplementation
@ConsoleInternalApi
public abstract class MiraiConsoleLoggerControllerForFrontend : MiraiConsoleLoggerControllerPlatformBase() {
private fun shouldLog(
priority: LoggerConfig.LogPriority,
settings: LoggerConfig.LogPriority
): Boolean = settings <= priority
private fun shouldLog(identity: String?, priority: LoggerConfig.LogPriority): Boolean {
return if (identity == null) {
shouldLog(priority, LoggerConfig.defaultPriority)
} else {
shouldLog(priority, LoggerConfig.loggers[identity] ?: LoggerConfig.defaultPriority)
}
}
override fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean =
shouldLog(identity, LoggerConfig.LogPriority.by(priority))
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*
*/
package net.mamoe.mirai.console.logging
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
import net.mamoe.mirai.utils.SimpleLogger
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicReference
@Suppress("MemberVisibilityCanBePrivate")
@ConsoleExperimentalApi
@ConsoleFrontEndImplementation
public abstract class MiraiConsoleLoggerControllerPlatformBase : MiraiConsoleLoggerController {
override fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean = true
override val cacheLoggers: Boolean
get() = true
protected val registrations: ConcurrentHashMap<Any, AtomicReference<Any>> = ConcurrentHashMap()
protected object NilIdentityPlaceholder
override fun allocateLoggerRegistration(identity: String?): AtomicReference<Any> =
registrations.computeIfAbsent(identity ?: NilIdentityPlaceholder) { AtomicReference() }
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*
*/
package net.mamoe.mirai.console.logging
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.MiraiLoggerPlatformBase
internal class MiraiConsoleLoggerUnused(
val controller: MiraiConsoleLoggerController,
override val identity: String?
) : MiraiLoggerPlatformBase() {
internal object InitializeLock
internal lateinit var delegateLogger: MiraiDelegateLogger
private val logger: MiraiLogger by lazy {
val logger = if (controller.cacheLoggers) {
val reference = controller.allocateLoggerRegistration(identity)
if (reference.compareAndSet(null, InitializeLock)) {
val logger = MiraiConsoleLogger(controller, controller.newLoggerImpl(identity))
reference.set(logger)
logger
} else {
// initialized/initializing
val logger: MiraiLogger
while (true) {
val status = reference.get()
if (status is MiraiLogger) {
logger = status
break
}
}
logger
}
} else {
MiraiConsoleLogger(controller, controller.newLoggerImpl(identity))
}
delegateLogger.logger = logger
logger
}
override val isEnabled: Boolean
get() = super.isEnabled
override fun debug0(message: String?, e: Throwable?) = logger.debug(message, e)
override fun error0(message: String?, e: Throwable?) = logger.error(message, e)
override fun info0(message: String?, e: Throwable?) = logger.info(message, e)
override fun verbose0(message: String?, e: Throwable?) = logger.verbose(message, e)
override fun warning0(message: String?, e: Throwable?) = logger.warning(message, e)
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2019-2020 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
*
*/
package net.mamoe.mirai.console.logging
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.MiraiLoggerPlatformBase
internal class MiraiDelegateLogger(var logger: MiraiLogger) : MiraiLoggerPlatformBase() {
override val identity: String? get() = logger.identity
override val isEnabled: Boolean get() = logger.isEnabled
override fun debug0(message: String?, e: Throwable?) = logger.debug(message, e)
override fun error0(message: String?, e: Throwable?) = logger.error(message, e)
override fun info0(message: String?, e: Throwable?) = logger.info(message, e)
override fun verbose0(message: String?, e: Throwable?) = logger.verbose(message, e)
override fun warning0(message: String?, e: Throwable?) = logger.warning(message, e)
}

View File

@ -14,6 +14,8 @@ import net.mamoe.mirai.console.MiraiConsoleImplementation.Companion.start
import net.mamoe.mirai.console.command.CommandManager
import net.mamoe.mirai.console.data.MemoryPluginDataStorage
import net.mamoe.mirai.console.data.PluginDataStorage
import net.mamoe.mirai.console.logging.MiraiConsoleLoggerController
import net.mamoe.mirai.console.logging.MiraiConsoleLoggerControllerPlatformBase
import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
import net.mamoe.mirai.console.plugin.loader.PluginLoader
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
@ -21,10 +23,7 @@ import net.mamoe.mirai.console.util.ConsoleInput
import net.mamoe.mirai.console.util.ConsoleInternalApi
import net.mamoe.mirai.console.util.SemVersion
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.LoginSolver
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.PlatformLogger
import net.mamoe.mirai.utils.*
import java.nio.file.Path
import kotlin.coroutines.Continuation
import kotlin.coroutines.CoroutineContext
@ -73,8 +72,9 @@ fun initTestEnvironment() {
override fun createLoginSolver(requesterBot: Long, configuration: BotConfiguration): LoginSolver =
LoginSolver.Default
override fun createLogger(identity: String?): MiraiLogger {
return PlatformLogger(identity)
override val loggerController: MiraiConsoleLoggerController = object:MiraiConsoleLoggerControllerPlatformBase(){
override fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean = true
override fun newLoggerImpl(identity: String?): MiraiLogger = PlatformLogger(identity)
}
override val coroutineContext: CoroutineContext = SupervisorJob() + CoroutineExceptionHandler { _, throwable ->

View File

@ -33,6 +33,8 @@ import net.mamoe.mirai.console.MiraiConsoleFrontEndDescription
import net.mamoe.mirai.console.MiraiConsoleImplementation
import net.mamoe.mirai.console.data.MultiFilePluginDataStorage
import net.mamoe.mirai.console.data.PluginDataStorage
import net.mamoe.mirai.console.logging.MiraiConsoleLoggerController
import net.mamoe.mirai.console.logging.MiraiConsoleLoggerControllerForFrontend
import net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader
import net.mamoe.mirai.console.plugin.loader.PluginLoader
import net.mamoe.mirai.console.terminal.ConsoleInputImpl.requestInput
@ -81,7 +83,9 @@ class MiraiConsoleImplementationTerminal
return DefaultLoginSolver(input = { requestInput("LOGIN> ") })
}
override fun createLogger(identity: String?): MiraiLogger = LoggerCreator(identity)
override val loggerController: MiraiConsoleLoggerController = object : MiraiConsoleLoggerControllerForFrontend() {
override fun newLoggerImpl(identity: String?): MiraiLogger = LoggerCreator(identity)
}
init {
with(rootPath.toFile()) {
@ -151,6 +155,7 @@ val terminal: Terminal = run {
private object ConsoleFrontEndDescImpl : MiraiConsoleFrontEndDescription {
override val name: String get() = "Terminal"
override val vendor: String get() = "Mamoe Technologies"
// net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants.version
// is console's version not frontend's version
override val version: SemVersion = SemVersion(net.mamoe.mirai.console.internal.MiraiConsoleBuildConstants.versionConst)