如何在 java logback 中打印自定义堆栈跟踪?

how to print custom stacktrace in java logback?

当前logback.xml

<appender name="FILEOUT3" class="ch.qos.logback.core.FileAppender">
    <file>D:/${byDay}.log</file>
    <append>true</append>
    <encoder>
        <Pattern>%d{HH:mm:ss} %-5level %msg%replace(%xException){"\n", ">> "}%nopex%n</Pattern>
    </encoder>
</appender>

当前结果:

play.api.Configuration$$anon: Configuration error[Cannot connect to database [default]]
>> at play.api.Configuration$.play$api$Configuration$$configError(Configuration.scala:92) ~[play_2.10-2.2.0.jar:2.2.0]
>> at play.api.Configuration.reportError(Configuration.scala:570) ~[play_2.10-2.2.0.jar:2.2.0]
>> at play.api.db.BoneCPPlugin$$anonfun$onStart.apply(DB.scala:252) ~[play-jdbc_2.10-2.2.0.jar:2.2.0]

我想要结果:

[12:43:16.454] play.api.Configuration$$anon: Configuration error[Cannot connect to database [default]]
[12:43:16.454]    at play.api.Configuration$.play$api$Configuration$$configError(Configuration.scala:92) ~[play_2.10-2.2.0.jar:2.2.0]
[12:43:16.454]    at play.api.Configuration.reportError(Configuration.scala:570) ~[play_2.10-2.2.0.jar:2.2.0]
[12:43:16.454]    at play.api.db.BoneCPPlugin$$anonfun$onStart.apply(DB.scala:252) ~[play-jdbc_2.10-2.2.0.jar:2.2.0]
:
:
more 40 lines
:
[12:43:16.454]    at play.api.db.BoneCPPlugin$$anonfun$onStart.apply(DB.scala:252) ~[play-jdbc_2.10-2.2.0.jar:2.2.0]

重要!
同时打印

我想知道。
如何更改logback.xml?

您不能通过仅更改 logback.xml 来做到这一点,因为由 %replace 调用的 ReplacingCompositeConverter 仅使用静态字符串作为替换(没有日期或 PatternLayout 的任何其他转换词)。

为了达到你的目标,你应该创建自定义转换器(如果你要使用我的,请注意它应该放在 ch.qos.logback.core.pattern 包中)

package ch.qos.logback.core.pattern;

import ch.qos.logback.classic.PatternLayout;

import ch.qos.logback.core.pattern.parser.Node;
import ch.qos.logback.core.pattern.parser.Parser;
import ch.qos.logback.core.spi.ScanException;

public class ReplacingAndParsingCompositeConverter<E> extends ReplacingCompositeConverter<E> {

    @Override
    protected String transform(E event, String in) {
        if (!started) {
            return in;
        }

        String parsedReplacement;

        try {
            Parser<E> p = new Parser<E>(replacement);
            p.setContext(getContext());
            Node t = p.parse();
            Converter<E> c = p.compile(t, PatternLayout.defaultConverterMap);
            ConverterUtil.setContextForConverters(getContext(), c);
            ConverterUtil.startConverters(c);
            StringBuilder buf = new StringBuilder();
            while (c != null) {
                c.write(buf, event);
                c = c.getNext();
            }
            parsedReplacement = buf.toString();
        } catch (ScanException e) {
            e.printStackTrace();
            parsedReplacement = replacement;
        }
        return pattern.matcher(in).replaceAll(parsedReplacement);
    }
}

那么您应该在 logback.xml 中使用 声明此转换器并使用它代替旧的 %replace。

<configuration ...>
    <conversionRule conversionWord="replaceAndParse" converterClass="ch.qos.logback.core.pattern.ReplacingAndParsingCompositeConverter" />

    <appender name="FILEOUT3" class="ch.qos.logback.core.FileAppender">
        <file>D:/${byDay}.log</file>
        <append>true</append>
        <encoder>
            <Pattern>[%d{HH:mm:ss.SSS}] %-5level %msg%replaceAndParse(%xException){"(\r?\n)", "[%d{HH:mm:ss.SSS}]"}%nopex%n</Pattern>
        </encoder>
    </appender>
    ....
</configuration>