欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

解决 logback 不能输出 e.printStackTrace 日志的问题

最编程 2024-03-08 22:05:45
...
【开源中国 APP 全新上线】“动弹” 回归、集成大模型对话、畅读技术报告

背景

老代码中有一些使用e.printStackTrace(),System.err和System.out来打印日志,在logback的日志文件中没有输出,导致产生异常找不到原因。

解决方案

  1. 替换掉不合理的日志打印方式,通过slf4j处理

  2. e.printStackTrace()换成log.error("产生异常的参数",e)

    其实,上面说的都说废话。。。如果替换起来容易的话,谁还会看到这个文章?

下面开始说重点了,我们的临时替代方案,把System.out和System.err的日志通过log来输出,不就完美解决了吗。核心方法,通过System.setOut(PrintStream) 来改变原来的print动作。

@Configuration
public class LogSystemProxy {

    private final static Logger log = LoggerFactory.getLogger("proxy.system.log");

    @PostConstruct
    public void initProxy(){
        log.debug("LogSystemProxy init .....");
        System.setOut(getLoggerProxy(StdType.OUT));
        System.setErr(getLoggerProxy(StdType.ERR));
    }


    private enum StdType{
        OUT(System.out, log::info),
        ERR(System.err, log::error),
        ;
        PrintStream stream;
        Consumer<String> consumer;
        StdType(PrintStream stream,Consumer<String> consumer){
            this.stream = stream;
            this.consumer = consumer;
        }
    }

    private PrintStream getLoggerProxy(StdType stdType){
        return new PrintStream(stdType.stream){
            @Override
            public void print(String s) {
                stdType.stream.print(s);
                stdType.consumer.accept(s);
            }
        };
    }
}

如果日志配置文件中日志有root是通过ConsoleAppender输出的话,记得要做排除

 <logger name="proxy.system.log" additivity="false">
   <appender-ref ref="fileAppender" />
 </logger>