Java 仅获取 Stack Trace 的前 N 行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21706722/
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
Fetch only first N lines of a Stack Trace
提问by Mindwin
I have a Factory method that returns an object from a ID call.
我有一个从 ID 调用返回一个对象的工厂方法。
Mock code:
模拟代码:
public static Object getById(String id) {
Object o = CRUD.doRecovery(Class, id);
if(o == null) {
printLogMessage("recovery by ID returned Null: " + id);
// would really like to show only a few lines of stack trace.
}
return o;
}
How can I show only the first N lines of the stack trace (so I know the caller of the method) without dumping the whole stack trace on the log or having to rely on external libs?
如何仅显示堆栈跟踪的前 N 行(所以我知道该方法的调用者),而无需将整个堆栈跟踪转储到日志中或不得不依赖外部库?
采纳答案by mikea
I'm assuming from what you are asking, that you don't have an exception to deal with. In which case you can get the current stack trace from:
我从你的要求中假设,你没有例外处理。在这种情况下,您可以从以下位置获取当前堆栈跟踪:
StackTraceElement[] elements = Thread.currentThread().getStackTrace()
This will tell you pretty much everything you need to know about where you've come from in the code.
这将告诉你几乎所有你需要知道的关于你从哪里来的代码。
回答by Mindwin
This method displays i
lines of the stack trace, skipping the first two.
此方法显示i
堆栈跟踪的行,跳过前两行。
public static String traceCaller(Exception ex, int i) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
StringBuilder sb = new StringBuilder();
ex.printStackTrace(pw);
String ss = sw.toString();
String[] splitted = ss.split("\n");
sb.append("\n");
if(splitted.length > 2 + i) {
for(int x = 2; x < i+2; x++) {
sb.append(splitted[x].trim());
sb.append("\n");
}
return sb.toString();
}
return "Trace too Short.";
}
The first two lines are the exception name and the method that called traceCaller()
. Tweak it if you want to show these lines.
前两行是异常名称和调用的方法traceCaller()
。如果您想显示这些线条,请调整它。
Thanks go to @BrianAgnew(stackoverflow.com/a/1149712/1532705) for the StringWriter PrintWriter idea
感谢 @ BrianAgnew( stackoverflow.com/a/1149712/1532705) 提供 StringWriter PrintWriter 的想法
回答by ???v?т?
If you just want to truncate the stack trace, you can print the entire stack trace to a StringWriter then remove what you don't want:
如果您只想截断堆栈跟踪,您可以将整个堆栈跟踪打印到 StringWriter,然后删除您不想要的:
public static void main(String[] args) throws ParseException {
try {
throw new Exception("Argh!");
} catch (Exception e) {
System.err.println(shortenedStackTrace(e, 1));
}
}
public static String shortenedStackTrace(Exception e, int maxLines) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
String[] lines = writer.toString().split("\n");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Math.min(lines.length, maxLines); i++) {
sb.append(lines[i]).append("\n");
}
return sb.toString();
}
Alternatively, use e.getStackTrace()
to obtain a StackTraceElement[]
array. This gives you the caller stack (from inner to outer), but not the error message. You'll have to use e.getMessage()
to get the error message.
或者,用于e.getStackTrace()
获取StackTraceElement[]
数组。这为您提供了调用者堆栈(从内部到外部),而不是错误消息。您必须使用e.getMessage()
来获取错误消息。
Some logging frameworks can be configured to truncate stack traces automatically. E.g. see this question and answerabout log4j configuration.
一些日志框架可以配置为自动截断堆栈跟踪。例如,请参阅有关 log4j 配置的问题和答案。
If you just want to see the stack trace at any point in the code, you can get the elements from the Thread.currentThread()
object:
如果您只想查看代码中任何一点的堆栈跟踪,您可以从Thread.currentThread()
对象中获取元素:
Thread.currentThread().getStackTrace();
回答by Salah
You can use the ex.getStackTrace()
to get the stack elements, the StackTraceElement
contains one line of the full stacks, then print print what ever you want.
您可以使用ex.getStackTrace()
来获取堆栈元素,其中StackTraceElement
包含一行完整堆栈,然后打印您想要的任何内容。
StackTraceElement[] elements = ex.getStackTrace();
print(elements[0]);
回答by Alex Che
Guava could help. For example we want to see only first ten rows:
番石榴可以提供帮助。例如,我们只想查看前十行:
log.error("Error:", Joiner.on("\n").join(Iterables.limit(asList(ex.getStackTrace()), 10)));
回答by JosiahYoder-deactive except..
For an abbreviated version of e.printStackTrace():
对于 e.printStackTrace() 的缩写版本:
Exception e = ...
System.out.println(e.toString());
StackTraceElement[] elements = e.getStackTrace();
for(int i = 0; i<elements.length && i < STACK_TRACE_LIMIT; i++) {
System.out.println("\tat "+elements[i]);
}
Replace STACK_TRACE_LIMIT
with the limit you want or remove && i < STACK_TRACE_LIMIT
to reproduce the output of a simple stack trace (e.g., no nested exceptions)
替换STACK_TRACE_LIMIT
为您想要或删除的限制&& i < STACK_TRACE_LIMIT
以重现简单堆栈跟踪的输出(例如,没有嵌套异常)
The innermost method calls are at index 0, main is at index length-1.
最里面的方法调用位于索引 0,main 位于索引 length-1。
回答by winter
exemple to display the fifth first lines:
显示第五行的示例:
final int nbLinesToShow = 5;
try {
/* your code here */
} catch (final NullPointerException e) {
// catch error
final StackTraceElement[] elements = e.getStackTrace();
System.err.println(
"===================================== \n" + "[ERROR] lorem ipsum");
for (int i = 0; i < nbLinesToShow; i++) {
System.err.println(elements[i]);
}
}