kotlin重定向log4j2的输出到jline3
1. 实现思路
遇到同时要用log4j2 和jline3 的情况, 如果把log4j2 直接重定向到System.out会中断jline3的输入栏,必须要找方法用lineReader.printAbove() 才可以避免
解决方法就是通过自定义Appender , 实现这个只需要在写一个Appender 类然后在log4j2.xml 里指明就好了
2. Console类
首先先实现Jline3, 这个不是本文重点,就大概写下要提供什么 要提供lineReader 主要是用到里面的printAbove 方法(输出就不会打断下面的输入栏)
object Console{
private val terminal: Terminal =
internal val lineReader: LineReader by lazy {
LineReaderBuilder.builder().terminal(terminal).completer(NullCompleter()).build()
}
}
3. Appender类
模板来着于Remko Popma的stackoverflow回答
package tech.eritquearcus.xxx.xxx.xxx
import org.apache.logging.log4j.core.AbstractLifeCycle
import org.apache.logging.log4j.core.Filter
import org.apache.logging.log4j.core.Layout
import org.apache.logging.log4j.core.LogEvent
import org.apache.logging.log4j.core.appender.AbstractAppender
import org.apache.logging.log4j.core.config.plugins.Plugin
import org.apache.logging.log4j.core.config.plugins.PluginAttribute
import org.apache.logging.log4j.core.config.plugins.PluginElement
import org.apache.logging.log4j.core.config.plugins.PluginFactory
import org.fusesource.jansi.Ansi
import java.io.Serializable
@Plugin(name = "Jline3Appender", category = "Core", elementType = "appender", printObject = true)
class Jline3AppenderImpl protected constructor(
name: String, filter: Filter?,
layout: Layout<Serializable>, ignoreExceptions: Boolean
) : AbstractAppender(name, filter, layout, ignoreExceptions, null) {
override fun append(event: LogEvent) {
Console.lineReader.printAbove(String(layout.toByteArray(event)) + Ansi().reset().toString())
}
companion object {
@PluginFactory
@JvmStatic
fun createAppender(
@PluginAttribute("name") name: String?,
@PluginElement("Layout") layout: Layout<Serializable>,
@PluginElement("Filter") filter: Filter?
): Jline3AppenderImpl? {
if (name == null) {
AbstractLifeCycle.LOGGER.error("No name provided for MyCustomAppenderImpl")
return null
}
return Jline3AppenderImpl(name, filter, layout, true)
}
}
}
4. log4j2.xml
这个文件要放在src/main/resource 下
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" packages="tech.eritquearcus.xxx.xxx.xxx">
<Appenders>
<Jline3Appender name="jline">
<PatternLayout
pattern="%highlight{%d{YYYY.MM.dd HH:mm:ss} [%-5level] %logger{36} - %message}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=green}\n"
disableAnsi="false"/>
</Jline3Appender>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="jline"/>
</Root>
</Loggers>
</Configuration>
主要就
- 在
Configuration 写你的appender类所在的package Jline3Appender 这个是你的Appender类上面的@plugin 注释里的name 属性Jline3Appender 后面的name可以随便写,在下面的Loggers 里的AppenderRef 的ref 写一样的就行PatternLayout 里的 disableAnsi="false" 是显示颜色PatternLayout 里其他详细配置看其他的文章,这里就不写了
end
|