问题描述
写
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位.
问题描述
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.