【发布时间】:2020-08-14 16:25:31
【问题描述】:
我有一个带有 MainService 的 Spring Boot 项目,它使用几个帮助方法和其他“微服务”来创建一个 FinalObject,最终使用 Hibernate/JPA 进行持久化。方法和服务可能会记录多条消息,我希望这些消息与记录事件发生时正在创建的对象相关联。
问题在于辅助方法和微服务无权访问finalObject 实例,因此即使记录了所有内容,也只会将捕获的异常保存为finalObject 属性——而不是警告消息或其他日志:
class FinalObject {
private int value;
private int price;
private List<String> logs;
...
}
class MainService {
@Autowired ValueService valueService; // + other services
void createFinalObject() { // Main method
FinalObject o1 = new FinalObject();
try {
o1.setValue(valueService.getValue("some argument"));
}
catch (Exception e) {
log.error(e.toString()); // Logging using Log4j2
o1.addLog(e.toString()); // If there's an exception, I can easily log it to a o1 attribute.
}
o1.setPrice(calculatePrice(o1.getValue()));
...
}
int calculatePrice(int value) { // Helper method
if (value > getMarketPrice())
log.info("This is very valuable!"); // I need a way to associate this with o1!
...
return price;
}
}
// ValueService.java
int getValue(String arg) {
if (arg.matches("\\d$"))
log.warn("arg ends with a number"); // Must also be saved to o1!
...
return value;
}
解决方案 1:到处传递o1:
int calculatePrice(int value, FinalObject o1) {
if (value > getMarketPrice()) {
o1.addLog("This is very valuable!"); // Now I have access to o1 here
log.info("This is very valuable!");
}
...
解决方案 2:将 o1 的 logs 属性作为可修改列表传递:
o1.setPrice(calculatePrice(o1.getValue(), o1.getLogs()));
...
int calculatePrice(int value, List<String> finalObjectLogs) {
if (value > getMarketPrice()) {
finalObjectLogs.add("This is very valuable!"); // Directly modify o1's logs attribute
log.info("This is very valuable!");
}
...
解决方案 3:添加 log4j2 数据库附加程序
一个更优雅的解决方案可能是向 log4j2 添加一个数据库附加程序。一个挑战是如何将这些日志与o1 关联起来。 FinalObject id 仅在createFinalObject() 的最后生成,当它保存到数据库时,所以在执行日志语句时我没有 id。
问题:
我怎样才能比我上面提到的方式更优雅地做到这一点?
或者:
如果解决方案 3 看起来不错,我该如何实施?
【问题讨论】:
标签: java spring-boot hibernate jpa logging