kotlin重定向log4j2的输出到jline3
2024-02-09 17:10:53 #Kotlin 1. 实现思路
遇到同时要用log4j2
和jline3
的情况, 如果把log4j2
直接重定向到System.out会中断jline3的输入栏,必须要找方法用lineReader.printAbove()
才可以避免
解决方法就是通过自定义Appender
, 实现这个只需要在写一个Appender
类然后在log4j2.xml
里指明就好了
2. Console类
首先先实现Jline3, 这个不是本文重点,就大概写下要提供什么
要提供lineReader
主要是用到里面的printAbove
方法(输出就不会打断下面的输入栏)
1 2 3 4 5 6
| object Console{ private val terminal: Terminal = internal val lineReader: LineReader by lazy { LineReaderBuilder.builder().terminal(terminal).completer(NullCompleter()).build() } }
|
3. Appender类
模板来着于Remko Popma的stackoverflow回答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| 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
下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?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