有没有可能在log4j中给堆栈跟踪的每一行都加上前缀?[英] Is it possible to prefix every line of a stacktrace in log4j?

本文是小编为大家收集整理的关于有没有可能在log4j中给堆栈跟踪的每一行都加上前缀?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

logger.error("message", exception);

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
...

我的转换模式是

log4j.appender.syslog.layout.ConversionPattern=myPrefix: [%p] [%t] [%c] [%x] - %m%n

因此,可以将每行带有myprefix的前缀 as:

    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
    ...

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

预先感谢.

推荐答案

子类,例如:

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;
    }

}

添加到您的log4j.properties:

log4j.throwableRenderer=whatever.package.LogThrowableRenderer

这使用现有的DefaultThrowableRenderer在添加前缀之前以熟悉的方式渲染堆栈,因此它将包括Throwable类,消息和原因.

其他推荐答案

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

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

html" rel="noflowlollow norefoll .org/log4j/1.2/apidocs/org/apache/log4j/spi/thfortablerenderer.html

然后,编辑您的log4j配置:

log4j.throwablerenderer = 您的custom-class-name

ThrowableRenderer返回String s的数组.这是您的代码:

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();

另一个想法是将Throwable打印到PrintWriter中,该Throwable包裹一些写入内存的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();

其他推荐答案

使用log4j2,您可以通过将separator指定为newline,然后是您的前缀:

,可以在stackTraces的每条新行中添加一个前缀:

%xThrowable{separator(\nmyPrefix)}%n

您可以类似地将前缀添加到每个多行消息的每条新行:

%replace{%m}{[\r\n]+}{\nmyPrefix}

例如,在每个多行日志和stacktrace行中添加空格前缀:

appender.rolling.layout.pattern = %d [%t] %-5p %c %L - %replace{%m}{[\r\n]+}{\n }%xThrowable{separator(\n )}%n

请注意,您要在%xThrowable之后放置%xThrowable位.

本文地址:https://www.itbaoku.cn/post/1574988.html

问题描述

when you write

logger.error("message", exception);

log4j produces the message and the complete stack trace :

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
...

my conversion pattern is

log4j.appender.syslog.layout.ConversionPattern=myPrefix: [%p] [%t] [%c] [%x] - %m%n

So, is it possible to prefix every line with myPrefix, as :

    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
    ...

When I grep my logs on myPrefix, i don't see the stack trace. We have many different prefixes (one per module)

Thanks in advance.

推荐答案

Subclass ThrowableRenderer, for example:

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;
    }

}

Add to your log4j.properties:

log4j.throwableRenderer=whatever.package.LogThrowableRenderer

This uses the existing DefaultThrowableRenderer to render the stacktrace in the familiar way before adding the prefix, so it will include the Throwable class, message, and cause.

其他推荐答案

Refer to Alex's answer as it's a cleaner one.

You can write your own implementation of org.apache.log4j.spi.ThrowableRenderer:

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

Then, edit your log4j configuration:

log4j.throwableRenderer=your-custom-class-name

The ThrowableRenderer returns an array of Strings. Here's your code:

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();

Another idea would be to print the Throwable into a PrintWriter that is wrapping some Writer that writes into memory, and then re-iterate over strings delimited by line.separator, adding each line to a list:

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();

其他推荐答案

With log4j2 you can add a prefix to each new line of your stacktraces by specifying the separator as a newline followed by your prefix:

%xThrowable{separator(\nmyPrefix)}%n

You can similarly add prefixes to each new line of each multi-line message:

%replace{%m}{[\r\n]+}{\nmyPrefix}

For example, to add a whitespace prefix to each multi-line log and stacktrace line:

appender.rolling.layout.pattern = %d [%t] %-5p %c %L - %replace{%m}{[\r\n]+}{\n }%xThrowable{separator(\n )}%n

Note that you want place the %xThrowable bit after your %m.