是否可以在log4j中为堆栈跟踪的每一行添加前缀?

Jea*_*ana 6 java log4j

当你写作

logger.error("message", exception);
Run Code Online (Sandbox Code Playgroud)

log4j生成消息和完整的堆栈跟踪:

Aug  9 06:26:13 10.175.60.14 myPrefix: [error] [TP-Processor114] [my.class.Name] message : exception
at fatherOfException
at fatherof_fatherOfException
at fatherof_fatherof_fatherOfException
...
Run Code Online (Sandbox Code Playgroud)

我的转换模式是

log4j.appender.syslog.layout.ConversionPattern=myPrefix: [%p] [%t] [%c] [%x] - %m%n
Run Code Online (Sandbox Code Playgroud)

那么,是否可以使用myPrefix为每一行添加前缀,如下所示:

    Aug  9 06:26:13 10.175.60.14 myPrefix: [error] [TP-Processor114] [my.class.Name] message : exception
myPrefix    at fatherOfException
myPrefix    at fatherof_fatherOfException
myPrefix    at fatherof_fatherof_fatherOfException
    ...
Run Code Online (Sandbox Code Playgroud)

当我在myPrefix上grep我的日志时,我看不到堆栈跟踪.我们有许多不同的前缀(每个模块一个)

提前致谢.

Isa*_*aac 7

请参阅Alex的答案,因为它更干净.

您可以编写自己的实现org.apache.log4j.spi.ThrowableRenderer:

http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/spi/ThrowableRenderer.html

然后,编辑您的log4j配置:

log4j.throwableRenderer = your-custom-class-name

ThrowableRenderer返回的数组String秒.这是你的代码:

String prefix = "myPrefix"; // Or some constant

List<String> l = new LinkedList<String>();
l.add(String.format("%s %s: %s", prefix, t.getClass().getName(), t.getMessage()));

for (StackTraceElement ste: t.getStackTrace()){
    l.add(String.format("%s %s", prefix, ste.toString()));
}

return (String[]) l.toArray();
Run Code Online (Sandbox Code Playgroud)

另一个想法是打印Throwable到包含PrintWriter一些Writer写入内存的一个,然后重新迭代由分隔的字符串line.separator,将每一行添加到列表:

StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));

List<String> l = new LinkedList<String>();
for (String s: sw.toString().split(System.lineSeparator())) {
    l.add(String.format("%s %s", prefix, s));
}

return (String[]) l.toArray();
Run Code Online (Sandbox Code Playgroud)

  • 效果很好,谢谢!但我必须迁移到log4j 1.2.16才能做到这一点 (2认同)

Ale*_*uda 3

子类ThrowableRenderer,例如:

import org.apache.log4j.DefaultThrowableRenderer;
import org.apache.log4j.spi.ThrowableRenderer;

public class LogThrowableRenderer implements ThrowableRenderer {

    DefaultThrowableRenderer def = new DefaultThrowableRenderer();

    @Override
    public String[] doRender(Throwable t) {
        String[] temp = def.doRender(t);
        for (int i = 0; i < temp.length; i++) {
            temp[i] = "myPrefix "+temp[i];
        }
        return temp;
    }

}
Run Code Online (Sandbox Code Playgroud)

添加到您的log4j.properties

log4j.throwableRenderer=whatever.package.LogThrowableRenderer
Run Code Online (Sandbox Code Playgroud)

在添加前缀之前,这会使用现有的以DefaultThrowableRenderer熟悉的方式呈现堆栈跟踪,因此它将包括类Throwable、消息和原因。