为什么日志中此堆栈跟踪前面没有这一行?



Dears,

我有这样的代码:(Move.java)

public void execute(ArrayList<Move> performedMoves) {
logger.debug(Thread.currentThread().getName() + " executing: from: " + from.getX() + ", " + from.getY() + " -> "
+ to.getX() + ", " + to.getY() + " p: " + piece.getShortDebug() + "->" + piece.executed + ", "
+ piece.rollbacked + ";" + "|" + piece.getCurrentPlace().getX() + ", "
+ piece.getCurrentPlace().getY());
if (executed && !rollbacked) {
throw new RuntimeException("this shouldn't be...");
}
//(more code)
from.remove(piece); // line 111, throwing the exception
to.setPiece(piece);
piece.setCurrentPlace(to);

这是日志:

2021-03-07 11:12:57 DEBUG Move:195 - Thread-3 rollBack: from: 0, 2 -> 1, 2 p: t->true, false|0, 2
2021-03-07 11:12:57 DEBUG Move:148 - Thread-3 rollBack: from: 2, 1 -> 1, 2 p: p->true, false|1, 2
2021-03-07 11:12:57 DEBUG Move:156 - Thread-3 false, false|1, 2
2021-03-07 11:12:57 DEBUG Move:168 - Thread-3 false, false|1, 2
2021-03-07 11:12:57 DEBUG Move:195 - Thread-3 rollBack: from: 2, 1 -> 1, 2 p: p->true, false|2, 1
Exception in thread "Thread-3" org.bamboomy.c44.board.IllegalPlaceException: this piece wasn't here :-( -> 2, 0 == 2, 9=>t->true, true
at org.bamboomy.c44.board.Place.remove(Place.java:190)
at org.bamboomy.c44.board.Move.execute(Move.java:111)
at org.bamboomy.c44.board.Robot$Agent.evaluate(Robot.java:753)
at org.bamboomy.c44.board.Robot$Agent.evaluate(Robot.java:772)
at org.bamboomy.c44.board.Robot$Agent.evaluate(Robot.java:772)
at org.bamboomy.c44.board.Robot$Agent.evaluate(Robot.java:772)
at org.bamboomy.c44.board.Robot$Agent.run(Robot.java:608)
at java.base/java.lang.Thread.run(Thread.java:834)
2021-03-07 11:12:58 DEBUG Robot:374 - 0:-1.7976931348623157E308
2021-03-07 11:12:58 DEBUG Robot:374 - 1:-1.7976931348623157E308

为什么日志中的stacktrace前面有:

2021-03-07 11:12:57 DEBUG Move:195 - Thread-3 rollBack: from: 2, 1 -> 1, 2 p: p->true, false|2, 1

而不是像这样的东西

2021-03-07 11:12:57 DEBUG Move:195 - Thread-3 executing: from: 2, 1 -> 1, 2 p: p->true, false|2, 1

(抛出异常之前的日志条目)?

("回滚"调试条目是在同一类中的另一个方法中完成的)

还有:

如果对于某些同步问题,例如,该日志条目被吞噬(我想是这样的):我如何强制或刷新记录器,以便获得调试消息的输出?

这是非常有价值的信息,它将对我调试复杂问题有很大帮助。。。

感谢阅读/指点。。。

S。

编辑:我使用log4j 1.2.17

记录器的初始化方式如下:

final static Logger logger = Logger.getLogger(Move.class);

该输出通过Thread::getUnaughtException Handler直接发送到System.err。

根据OpenJDK线程组::uncaughtException

public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread ""
+ t.getName() + "" ");
e.printStackTrace(System.err);
}
}
}

当抛出未捕获的异常并转义当前线程的运行方法时,此代码将绕过日志记录框架并直接打印到System.err。

如果您希望代码包含时间戳,则必须执行以下操作之一:

  1. 实现一个Thread.UncaughtException处理程序,该处理程序将日志记录到您的日志框架中。然后在应用程序启动时将其附加到所有线程或线程的子集。请记住,在具有复杂类加载器结构的环境中,此处理程序可能会固定类加载器并导致内存泄漏。良好的代码卫生是在应用程序即将关闭时删除这些处理程序
  2. 在可运行或可调用的实现中,捕获Throwable并将其记录到日志框架中

最新更新