在SpringBoot中,我们可以统一异常处理,例如使用 @ControllerAdvice 和  @ExceptionHandler
但是这种方式,如果在异常中,我们需要把异常记录到日志当中,会产生一个问题,就是日志中记录的Category 全部变成了 Advice 的类名。
例如:
- @Controller
- public class HomeController {
-     @GetMapping("/")
-     public String home(Model model) {
-         if (model.getAttribute("name").toString().isEmpty()) throw new RuntimeException("Oops!");
-         model.addAttribute("name", "Good boy, now: " + Util.now());
-         return "home";
-     }
- }
- package tacos.advisor;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.web.bind.annotation.ControllerAdvice;
- import org.springframework.web.bind.annotation.ExceptionHandler;
- @ControllerAdvice
- public class GlobalExceptionHandler {
-     @ExceptionHandler(Exception.class)
-     public Object handleException(Throwable exception) {
-         log.error("fail: {}", exception);
-         return null;
-     }
- }
统一前的日志:
23:02:04.197 [ERROR] [tacos.controller.HomeController ] fail: {} 
统一后变成了
23:02:04.197 [ERROR] [tacos.controller.GlobalExceptionHandler ] fail: {} 
如何让统一后也继续用异常发生时所在的类名类作为日志类名输出日志呢?
解决方法:
- @ControllerAdvice
- public class GlobalExceptionHandler {
-     @ExceptionHandler(Exception.class)
-     public Object handleException(Throwable exception) {
-         Logger log = LoggerFactory.getLogger(exception.getStackTrace()[0].getClassName());
-         log.error("fail: {}", exception);
-         return null;
-     }
- }
这样日志就和原来一样了。