[英]How to send a stacktrace to log4j?
假设您执行e.printStackTrace() ,则捕获到一个异常并在标准输出(例如控制台)上获得以下内容:
java.io.FileNotFoundException: so.txt
at java.io.FileInputStream.<init>(FileInputStream.java)
at ExTest.readMyFile(ExTest.java:19)
at ExTest.main(ExTest.java:7)
现在,我想将其发送给log4j之类的记录器,以获取以下信息:
31947 [AWT-EventQueue-0] ERROR Java.io.FileNotFoundException: so.txt
32204 [AWT-EventQueue-0] ERROR at java.io.FileInputStream.<init>(FileInputStream.java)
32235 [AWT-EventQueue-0] ERROR at ExTest.readMyFile(ExTest.java:19)
32370 [AWT-EventQueue-0] ERROR at ExTest.main(ExTest.java:7)
我怎样才能做到这一点?
try {
...
} catch (Exception e) {
final String s;
... // <-- What goes here?
log.error( s );
}
您可以将异常直接传递给记录器,例如
try {
...
} catch (Exception e) {
log.error( "failed!", e );
}
取决于log4j来呈现堆栈跟踪。
如果要在不涉及异常的情况下记录堆栈跟踪,请执行以下操作:
String message = "";
for(StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
message = message + System.lineSeparator() + stackTraceElement.toString();
}
log.warn("Something weird happened. I will print the the complete stacktrace even if we have no exception just to help you find the cause" + message);
您还可以通过ExceptionUtils.getStackTrace
以字符串形式获取堆栈跟踪。
请参阅: ExceptionUtils.java
我仅将它用于log.debug
,以使log.error
简单。
该答案可能与提出的问题无关,但与问题的标题有关。
public class ThrowableTest {
public static void main(String[] args) {
Throwable createdBy = new Throwable("Created at main()");
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter(os);
createdBy.printStackTrace(pw);
try {
pw.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
logger.debug(os.toString());
}
}
要么
public static String getStackTrace (Throwable t)
{
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
t.printStackTrace(printWriter);
printWriter.close(); //surprise no IO exception here
try {
stringWriter.close();
}
catch (IOException e) {
}
return stringWriter.toString();
}
要么
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for(StackTraceElement stackTrace: stackTraceElements){
logger.debug(stackTrace.getClassName()+ " "+ stackTrace.getMethodName()+" "+stackTrace.getLineNumber());
}
只是因为它发生在我身上并且可能有用。 如果你这样做
try {
...
} catch (Exception e) {
log.error( "failed! {}", e );
}
您将获得异常的标头,而不是整个stacktrace。 因为记录器会认为您正在传递字符串。 如skaffman所说,不用{}
做
skaffman的答案绝对是正确的答案。 所有记录器方法,例如error()
, warn()
, info()
, debug()
将Throwable作为第二个参数:
try {
...
} catch (Exception e) {
logger.error("error: ", e);
}
但是,您也可以将stacktrace提取为String。 如果您希望利用占位符“ {}”来使用格式化功能,有时可能会很有用-请参见方法void info(String var1, Object... var2);
在这种情况下,假设您有一个String作为堆栈跟踪,那么您实际上可以执行以下操作:
try {
...
} catch (Exception e) {
String stacktrace = TextUtils.getStacktrace(e);
logger.error("error occurred for usename {} and group {}, details: {}",username, group, stacktrace);
}
这将在最后输出参数化的消息和stacktrace,方法与方法相同: logger.error("error: ", e);
我实际上写了一个开放源代码库,该库具有一个实用程序,可将String作为一个String提取出来,并带有一个选项,用于从stacktrace中巧妙地滤除一些噪声。 即,如果您指定了对提取的堆栈跟踪感兴趣的软件包前缀,则会从一些不相关的部分中滤除掉这些信息,并给您留下非常大的信息。 这里是文章的链接,解释了该库具有哪些实用程序以及在何处获取它(作为Maven工件和git源)以及如何使用它。 带有堆栈跟踪过滤,静默字符串解析Unicode转换器和版本比较的开源Java库,请参见“ Stacktrace噪声过滤器 ”
这将是很好的log4j错误/异常日志记录-splunk /其他日志记录/监视软件可以读取。 一切都是键值对形式。 log4j将从异常obj e
获取堆栈跟踪
try {
---
---
} catch (Exception e) {
log.error("api_name={} method={} _message=\"error description.\" msg={}",
new Object[]{"api_name", "method_name", e.getMessage(), e});
}
Try this:
catch (Throwable t) {
logger.error("any message" + t);
StackTraceElement[] s = t.getStackTrace();
for(StackTraceElement e : s){
logger.error("\tat " + e);
}
}
您可以使用以下代码:
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class LogWriterUtility {
Logger log;
public LogWriterUtility(Class<?> clazz) {
log = LogManager.getLogger(clazz);
}
public void errorWithAnalysis( Exception exception) {
String message="No Message on error";
StackTraceElement[] stackTrace = exception.getStackTrace();
if(stackTrace!=null && stackTrace.length>0) {
message="";
for (StackTraceElement e : stackTrace) {
message += "\n" + e.toString();
}
}
log.error(message);
}
}
您可以在这里致电: LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);
它将把stackTrace打印到您的日志中。
在Log4j 2中,可以使用Logger.catching()从捕获到的异常中记录堆栈跟踪 。
try {
String msg = messages[messages.length];
logger.error("An exception should have been thrown");
} catch (Exception ex) {
logger.catching(ex);
}
创建这个class
:
public class StdOutErrLog {
private static final Logger logger = Logger.getLogger(StdOutErrLog.class);
public static void tieSystemOutAndErrToLog() {
System.setOut(createLoggingProxy(System.out));
System.setErr(createLoggingProxy(System.err));
}
public static PrintStream createLoggingProxy(final PrintStream realPrintStream) {
return new PrintStream(realPrintStream) {
public void print(final String string) {
logger.info(string);
}
public void println(final String string) {
logger.info(string);
}
};
}
}
在您的代码中调用
StdOutErrLog.tieSystemOutAndErrToLog();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.