日志工具利用try-with-resources语法在close重载中实现自动计时,错误使用导致日志丢失
精简代码如下:
import cn.hutool.json.JSONUtil;
public class LogHelper implements AutoCloseable {
public LogHelper(ActionLog actionLog) {
actionLog.startTime = System.currentTimeMillis();
this.actionLog = actionLog;
}
private ActionLog actionLog;
@Override
public void close() throws Exception {
System.out.println("close执行");
actionLog.endTime = System.currentTimeMillis();
actionLog.spendTime = (actionLog.endTime - actionLog.startTime) / 1000;
actionLog.write();
}
static class ActionLog {
public String message;
public Long startTime;
public Long endTime;
public Long spendTime;
public Throwable throwable;
public void write() {
System.out.println(JSONUtil.toJsonStr(this));
}
}
//测试异常日志打印
public static void main(String[] args) {
ActionLog actionLog = new ActionLog();
try(LogHelper logHelper = new LogHelper(actionLog)) {
actionLog.message = "log message";
int a = 1 / 0;
} catch (Throwable throwable) {
//close先于catch执行导致异常日志缺失
System.out.println("catch执行");
actionLog.throwable = throwable;
}
}
}
发生异常时执行结果:
close执行
{"message":"log message","startTime":1711450365630,"endTime":1711450365630,"spendTime":0}
catch执行
可以看到,try-with-resources语句中出现异常时,close语句会先于catch语句执行,导致日志提前打印,丢失了异常信息。