Java 如何将堆栈跟踪发送到 log4j?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4347797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to send a stacktrace to log4j?
提问by SyntaxT3rr0r
Say you catch an exception and get the following on the standard output (like, say, the console) if you do a e.printStackTrace():
如果您执行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)
Now I want to send this instead to a logger like, say, log4j to get the following:
现在我想把它发送到一个记录器,比如 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)
How can I do this?
我怎样才能做到这一点?
try {
...
} catch (Exception e) {
final String s;
... // <-- What goes here?
log.error( s );
}
采纳答案by skaffman
You pass the exception directly to the logger, e.g.
您将异常直接传递给记录器,例如
try {
...
} catch (Exception e) {
log.error( "failed!", e );
}
It's up to log4j to render the stack trace.
由 log4j 来呈现堆栈跟踪。
回答by ktsujister
You can also get stack trace as string via ExceptionUtils.getStackTrace
.
您还可以通过ExceptionUtils.getStackTrace
.
See: ExceptionUtils.java
I use it only for log.debug
, to keep log.error
simple.
我仅将它用于log.debug
, 以保持log.error
简单。
回答by user2281804
Create this class
:
创建这个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);
}
};
}
}
Call this in your code
在您的代码中调用它
StdOutErrLog.tieSystemOutAndErrToLog();
回答by Kanagavelu Sugumar
This answer may be not related to the question asked but related to title of the question.
这个答案可能与提出的问题无关,但与问题的标题有关。
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());
}
}
OR
或者
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();
}
OR
或者
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for(StackTraceElement stackTrace: stackTraceElements){
logger.debug(stackTrace.getClassName()+ " "+ stackTrace.getMethodName()+" "+stackTrace.getLineNumber());
}
回答by iberbeu
Just because it happened to me and can be useful. If you do this
只是因为它发生在我身上并且可能有用。如果你这样做
try {
...
} catch (Exception e) {
log.error( "failed! {}", e );
}
you will get the header of the exception and not the whole stacktrace. Because the logger will think that you are passing a String.
Do it without {}
as skaffman said
您将获得异常的标头,而不是整个堆栈跟踪。因为记录器会认为你在传递一个字符串。不要{}
像斯卡夫曼所说的那样做
回答by borjab
If you want to log a stacktrace without involving an exception just do this:
如果您想在不涉及异常的情况下记录堆栈跟踪,请执行以下操作:
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);
回答by Michael Gantman
The answer from skaffman is definitely the correct answer. All logger methods such as error()
, warn()
, info()
, debug()
take Throwable as a second parameter:
来自 skaffman 的答案绝对是正确的答案。所有记录器方法,例如error()
, warn()
, info()
,都debug()
将 Throwable 作为第二个参数:
try {
...
} catch (Exception e) {
logger.error("error: ", e);
}
However, you can extract stacktrace as a String as well. Sometimes it could be useful if you wish to take advantage of formatting feature using "{}" placeholder - see method void info(String var1, Object... var2);
In this case say you have a stacktrace as String, then you can actually do something like this:
但是,您也可以将堆栈跟踪提取为字符串。有时,如果您希望使用“{}”占位符来利用格式化功能,这可能会很有用 - 请参阅方法void info(String var1, Object... var2);
在这种情况下,假设您有一个堆栈跟踪作为字符串,那么您实际上可以执行以下操作:
try {
...
} catch (Exception e) {
String stacktrace = TextUtils.getStacktrace(e);
logger.error("error occurred for usename {} and group {}, details: {}",username, group, stacktrace);
}
This will print parametrized message and the stacktrace at the end the same way it does for method: logger.error("error: ", e);
这将在最后以与方法相同的方式打印参数化消息和堆栈跟踪: logger.error("error: ", e);
I actually wrote an open source library that has a Utility for extraction of a stacktrace as a String with an option to smartly filter out some noise out of stacktrace. I.e. if you specify the package prefix that you are interested in your extracted stacktrace would be filtered out of some irrelevant parts and leave you with very consized info. Here is the link to the article that explains what utilities the library has and where to get it (both as maven artifacts and git sources) and how to use it as well. Open Source Java library with stack trace filtering, Silent String parsing Unicode converter and Version comparisonSee the paragraph "Stacktrace noise filter"
我实际上编写了一个开源库,它有一个实用程序,用于将堆栈跟踪提取为字符串,并带有一个选项,可以巧妙地从堆栈跟踪中过滤掉一些噪音。即,如果您指定您对提取的堆栈跟踪感兴趣的包前缀,则会从一些不相关的部分中过滤掉,并为您留下非常大的信息。这是文章的链接,该链接解释了该库具有哪些实用程序以及从何处获取它(作为 maven 工件和 git 源)以及如何使用它。具有堆栈跟踪过滤、Silent String 解析 Unicode 转换器和版本比较的开源 Java 库参见“堆栈跟踪噪声过滤器”段落
回答by src3369
this would be good log4j error/exception logging - readable by splunk/other logging/monitoring s/w. everything is form of key-value pair.
log4j would get the stack trace from Exception obj e
这将是很好的 log4j 错误/异常日志记录 - splunk/其他日志记录/监控软件可读。一切都是键值对的形式。log4j 将从 Exception obj 获取堆栈跟踪e
try {
---
---
} catch (Exception e) {
log.error("api_name={} method={} _message=\"error description.\" msg={}",
new Object[]{"api_name", "method_name", e.getMessage(), e});
}
回答by Rajdeep Acharyya Chowdhury
Try this:
catch (Throwable t) {
logger.error("any message" + t);
StackTraceElement[] s = t.getStackTrace();
for(StackTraceElement e : s){
logger.error("\tat " + e);
}
}
回答by Md. Sajedul Karim
You can use bellow code:
您可以使用以下代码:
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);
}
}
Here you can just call : LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);
在这里你可以打电话: LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);
It will print stackTrace into your log.
它会将 stackTrace 打印到您的日志中。