Redesign LoggerController

This commit is contained in:
Karlatemp 2020-10-26 23:20:10 +08:00
parent 7d36bc6f7d
commit 544e11747c
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
13 changed files with 171 additions and 72 deletions

View File

@ -26,6 +26,7 @@ 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
@ -164,11 +165,12 @@ public interface MiraiConsoleImplementation : CoroutineScope {
public fun createLoginSolver(requesterBot: Long, configuration: BotConfiguration): LoginSolver
/**
* 日志控制器
* 创建一个 [MiraiLogger].
*
* @see [LoggerControllerImpl]
* **注意**: [MiraiConsole] 会将 [net.mamoe.mirai.utils.DefaultLogger] 设置为 `MiraiConsole::createLogger`.
* 因此不要在 [createLogger] 中调用 [net.mamoe.mirai.utils.DefaultLogger]
*/
public val loggerController: LoggerController
public fun createLogger(identity: String?): MiraiLogger
public companion object {
internal lateinit var instance: MiraiConsoleImplementation

View File

@ -36,6 +36,8 @@ public open class AutoSavePluginData private constructor(
private lateinit var owner_: AutoSavePluginDataHolder
private val autoSaveIntervalMillis_: LongRange get() = owner_.autoSaveIntervalMillis
private lateinit var storage_: PluginDataStorage
private var authSaveJob: Job? = null
private var completionHandle: DisposableHandle? = null
public final override val saveName: String
get() = _saveName
@ -54,18 +56,27 @@ public open class AutoSavePluginData private constructor(
?: throw IllegalArgumentException("Cannot find a serial name for ${this::class}")
}
@ConsoleExperimentalApi
public fun destroy() {
completionHandle?.dispose()
authSaveJob?.cancel()
completionHandle = null
authSaveJob = null
}
@ConsoleExperimentalApi
override fun onInit(owner: PluginDataHolder, storage: PluginDataStorage) {
check(owner is AutoSavePluginDataHolder) { "owner must be AutoSavePluginDataHolder for AutoSavePluginData" }
if (this::storage_.isInitialized) {
check(storage == this.storage_) { "AutoSavePluginData is already initialized with one storage and cannot be reinitialized with another." }
destroy() // Destroy old jobs
}
this.storage_ = storage
this.owner_ = owner
owner_.coroutineContext[Job]?.invokeOnCompletion {
completionHandle = owner_.coroutineContext[Job]?.invokeOnCompletion {
kotlin.runCatching {
doSave()
}.onFailure { e ->
@ -80,7 +91,7 @@ public open class AutoSavePluginData private constructor(
}
if (shouldPerformAutoSaveWheneverChanged()) {
owner_.launch(CoroutineName("AutoSavePluginData.timedAutoSave: ${this::class.qualifiedNameOrTip}")) {
authSaveJob = owner_.launch(CoroutineName("AutoSavePluginData.timedAutoSave: ${this::class.qualifiedNameOrTip}")) {
while (isActive) {
try {
delay(autoSaveIntervalMillis_.last) // 定时自动保存一次, 用于 kts 序列化的对象

View File

@ -0,0 +1,35 @@
/*
* 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.extensions
import net.mamoe.mirai.console.extension.AbstractSingletonExtensionPoint
import net.mamoe.mirai.console.extension.SingletonExtension
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
import net.mamoe.mirai.console.logging.LoggerController
import net.mamoe.mirai.console.permission.PermissionService
public interface LoggerControllerProvider : SingletonExtension<LoggerController> {
public companion object ExtensionPoint :
AbstractSingletonExtensionPoint<LoggerControllerProvider, LoggerController>(LoggerControllerProvider::class, LoggerControllerImpl)
}
/**
* @see LoggerControllerProvider
*/
public class LoggerControllerProviderImpl(override val instance: LoggerController) : LoggerControllerProvider
/**
* @see LoggerControllerProvider
*/
public class LoggerControllerProviderLazy(initializer: () -> LoggerController) : LoggerControllerProvider {
override val instance: LoggerController by lazy(initializer)
}

View File

@ -25,6 +25,7 @@ import net.mamoe.mirai.console.command.BuiltInCommands
import net.mamoe.mirai.console.command.CommandManager
import net.mamoe.mirai.console.command.ConsoleCommandSender
import net.mamoe.mirai.console.data.PluginDataStorage
import net.mamoe.mirai.console.extensions.LoggerControllerProvider
import net.mamoe.mirai.console.extensions.PermissionServiceProvider
import net.mamoe.mirai.console.extensions.PostStartupExtension
import net.mamoe.mirai.console.extensions.SingletonExtensionSelector
@ -35,12 +36,13 @@ 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.logging.LoggerControllerDelegate
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
import net.mamoe.mirai.console.internal.logging.LoggerControllerTrusted
import net.mamoe.mirai.console.internal.logging.MiraiConsoleLogger
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.LoggerController
import net.mamoe.mirai.console.permission.PermissionService
import net.mamoe.mirai.console.permission.PermissionService.Companion.permit
import net.mamoe.mirai.console.permission.RootPermission
@ -86,8 +88,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: LoggerController by instance::loggerController
private val loggerController = LoggerControllerDelegate(LoggerControllerTrusted)
override fun createLoginSolver(requesterBot: Long, configuration: BotConfiguration): LoginSolver =
instance.createLoginSolver(requesterBot, configuration)
@ -98,15 +99,16 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
override fun createLogger(identity: String?): MiraiLogger {
val controller = loggerController
return MiraiConsoleLogger(controller, controller.newLogger(identity))
return MiraiConsoleLogger(controller, instance.createLogger(identity))
}
@Suppress("RemoveRedundantBackticks")
internal fun doStart() {
phase `setup logger controller`@{
if (loggerController is LoggerControllerImpl) {
ConsoleDataScope.addAndReloadConfig(LoggerConfig)
}
phase `pre setup logger controller`@{
loggerController.delegate = LoggerControllerImpl
// Relaod LoggerConfig first.
ConsoleDataScope.addAndReloadConfig(LoggerConfig)
}
phase `greeting`@{
@ -175,6 +177,14 @@ internal object MiraiConsoleImplementationBridge : CoroutineScope, MiraiConsoleI
}
}
phase `setup logger controller`@{
val selected = LoggerControllerProvider.selectedInstance
if (selected !== LoggerControllerImpl) {
ConsoleDataScope.dropConfig(LoggerConfig)
loggerController.delegate = selected
}
}
phase `load PermissionService`@{
mainLogger.verbose { "Loading PermissionService..." }

View File

@ -11,10 +11,7 @@ package net.mamoe.mirai.console.internal.data.builtins
import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.data.AutoSavePluginDataHolder
import net.mamoe.mirai.console.data.PluginConfig
import net.mamoe.mirai.console.data.PluginData
import net.mamoe.mirai.console.data.PluginDataStorage
import net.mamoe.mirai.console.data.*
import net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge
import net.mamoe.mirai.console.util.CoroutineScopeUtils.childScope
import net.mamoe.mirai.utils.minutesToMillis
@ -29,6 +26,11 @@ internal object ConsoleDataScope : CoroutineScope by MiraiConsole.childScope("Co
ConsoleBuiltInPluginConfigStorage.load(ConsoleBuiltInPluginConfigHolder, config)
}
fun dropConfig(config: PluginConfig) {
configs.remove(config)
(config as? AutoSavePluginConfig)?.destroy()
}
fun reloadAll() {
data.forEach { dt ->
ConsoleBuiltInPluginDataStorage.load(ConsoleBuiltInPluginDataHolder, dt)

View File

@ -13,8 +13,7 @@ package net.mamoe.mirai.console.internal.data.builtins
import net.mamoe.mirai.console.data.AutoSavePluginConfig
import net.mamoe.mirai.console.data.ValueDescription
import net.mamoe.mirai.console.data.value
import net.mamoe.mirai.utils.SimpleLogger
import java.util.*
import net.mamoe.mirai.console.logging.LogPriority
internal object LoggerConfig : AutoSavePluginConfig("Logger") {
@ValueDescription("""
@ -29,30 +28,4 @@ internal object LoggerConfig : AutoSavePluginConfig("Logger") {
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,21 @@
/*
* 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.logging
import net.mamoe.mirai.console.logging.LoggerController
import net.mamoe.mirai.utils.SimpleLogger
internal class LoggerControllerDelegate(
@Volatile
var delegate: LoggerController
) : LoggerController {
override fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean = delegate.shouldLog(identity, priority)
}

View File

@ -12,20 +12,21 @@ package net.mamoe.mirai.console.internal.logging
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.internal.data.builtins.LoggerConfig
import net.mamoe.mirai.console.logging.LogPriority
import net.mamoe.mirai.console.logging.LoggerController
import net.mamoe.mirai.console.util.ConsoleInternalApi
import net.mamoe.mirai.utils.SimpleLogger
@ConsoleFrontEndImplementation
@ConsoleInternalApi
public abstract class LoggerControllerImpl : LoggerController {
internal object LoggerControllerImpl : LoggerController {
private fun shouldLog(
priority: LoggerConfig.LogPriority,
settings: LoggerConfig.LogPriority
priority: LogPriority,
settings: LogPriority
): Boolean = settings <= priority
private fun shouldLog(identity: String?, priority: LoggerConfig.LogPriority): Boolean {
private fun shouldLog(identity: String?, priority: LogPriority): Boolean {
return if (identity == null) {
shouldLog(priority, LoggerConfig.defaultPriority)
} else {
@ -34,6 +35,6 @@ public abstract class LoggerControllerImpl : LoggerController {
}
override fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean =
shouldLog(identity, LoggerConfig.LogPriority.by(priority))
shouldLog(identity, LogPriority.by(priority))
}

View File

@ -0,0 +1,18 @@
/*
* 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.logging
import net.mamoe.mirai.console.logging.LoggerController
import net.mamoe.mirai.utils.SimpleLogger
internal object LoggerControllerTrusted: LoggerController {
override fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean = true
}

View File

@ -0,0 +1,44 @@
/*
* 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.SimpleLogger
import java.util.*
public enum class LogPriority {
ALL(null),
VERBOSE,
DEBUG,
INFO,
WARNING,
ERROR,
NONE(null);
private var mapped: SimpleLogger.LogPriority? = null
public companion object {
private val mapping = EnumMap<SimpleLogger.LogPriority, LogPriority>(SimpleLogger.LogPriority::class.java)
public fun by(priority: SimpleLogger.LogPriority): LogPriority = mapping[priority]!!
init {
values().forEach { priority ->
mapping[priority.mapped ?: return@forEach] = priority
}
}
}
constructor(void: Nothing?)
constructor() {
mapped = SimpleLogger.LogPriority.valueOf(name)
}
}

View File

@ -10,11 +10,8 @@
package net.mamoe.mirai.console.logging
import net.mamoe.mirai.console.ConsoleFrontEndImplementation
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.internal.logging.LoggerControllerImpl
import net.mamoe.mirai.console.util.ConsoleExperimentalApi
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.SimpleLogger
/**
@ -23,22 +20,8 @@ import net.mamoe.mirai.utils.SimpleLogger
* @see [LoggerControllerImpl]
*/
@ConsoleExperimentalApi
@ConsoleFrontEndImplementation
public interface LoggerController {
/** 是否应该记录该等级的日志 */
public fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean
/**
* 创建一个新的 [MiraiLogger]
*
* 实现细节:
* - 应当直接创建一个新的 [MiraiLogger], 且不进行任何持久性操作,
* 例如 放置到字段, 放入任意集合
* - 即不需要在此方法中把 [MiraiLogger] 放入任意缓存
*
* * **注意**: [MiraiConsole] 会将 [net.mamoe.mirai.utils.DefaultLogger] 设置为 `MiraiConsole::createLogger`.
* `MiraiConsole::createLogger` 会使用 [LoggerController.newLogger]
* 因此不要在 [newLogger] 中调用 [net.mamoe.mirai.utils.DefaultLogger]
*/
public fun newLogger(identity: String?): MiraiLogger
}

View File

@ -71,9 +71,8 @@ fun initTestEnvironment() {
override fun createLoginSolver(requesterBot: Long, configuration: BotConfiguration): LoginSolver =
LoginSolver.Default
override val loggerController: LoggerController = object : LoggerController {
override fun shouldLog(identity: String?, priority: SimpleLogger.LogPriority): Boolean = true
override fun newLogger(identity: String?): MiraiLogger = PlatformLogger(identity)
override fun createLogger(identity: String?): MiraiLogger {
return PlatformLogger(identity)
}
override val coroutineContext: CoroutineContext = SupervisorJob() + CoroutineExceptionHandler { _, throwable ->

View File

@ -83,8 +83,8 @@ class MiraiConsoleImplementationTerminal
return DefaultLoginSolver(input = { requestInput("LOGIN> ") })
}
override val loggerController: LoggerController = object : LoggerControllerImpl() {
override fun newLogger(identity: String?): MiraiLogger = LoggerCreator(identity)
override fun createLogger(identity: String?): MiraiLogger {
return LoggerCreator(identity)
}
init {