kotlin重定向log4j2的输出到jline3

Posted Eritque arcus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kotlin重定向log4j2的输出到jline3相关的知识,希望对你有一定的参考价值。

kotlin重定向log4j2的输出到jline3

1. 实现思路

遇到同时要用log4j2jline3的情况, 如果把log4j2直接重定向到System.out会中断jline3的输入栏,必须要找方法用lineReader.printAbove()才可以避免

解决方法就是通过自定义Appender, 实现这个只需要在写一个Appender类然后在log4j2.xml里指明就好了

2. Console类

首先先实现Jline3, 这个不是本文重点,就大概写下要提供什么
要提供lineReader主要是用到里面的printAbove方法(输出就不会打断下面的输入栏)

object Console
	private val terminal: Terminal = /*complie code*/
	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, 不然可能会报错Serializable是kotlin.io internal object
import java.io.Serializable

// 类名可以改,不用和name一样, name也可以改, 大概照抄下就行, 主要是append方法
@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类在上面提供了, Ansi是色彩相关
        Console.lineReader.printAbove(String(layout.toByteArray(event)) + Ansi().reset().toString())
    

    companion object 
		// 一定要这2个注释,不然可能会报错找不到Factory method
        @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%dYYYY.MM.dd HH:mm:ss [%-5level] %logger36 - %messageFATAL=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里的AppenderRefref写一样的就行
  • PatternLayout 里的 disableAnsi="false"是显示颜色
  • PatternLayout里其他详细配置看其他的文章,这里就不写了
end

以上是关于kotlin重定向log4j2的输出到jline3的主要内容,如果未能解决你的问题,请参考以下文章

kotlin重定向log4j2的输出到jline3

kotlin重定向log4j2的输出到jline3

将 feign 和 Ribbon 日志重定向到 log4j2

如何将所有日志从hibernate和spring重定向到log4j2?

怎样去掉提示:nohup:重定向标准错误到标准输出

重定向标准错误到标准输出 是啥意思