2023_6_29_TIL
上男子 되는 길
上男子 TIL
Sentry연결
에러 로그를 모두 한곳에 모아서 관리를 하기 위해서 Sentry.io를 사용했다.
dev.yml 과 prod.yml에다가 코드를 추가하고 local로 시험을 해보자
에러를 Sentry로 보내는 코드를 짜보자
@Slf4j
@RequiredArgsConstructor
@RestControllerAdvice
public class MyExceptionAdvice {
private final ErrorLogRepository errorLogRepository;
@MyErrorLog // exception 걸리면 발동
@ExceptionHandler(Exception400.class)
public ResponseEntity<?> badRequest(Exception400 e){
return new ResponseEntity<>(e.body(), e.status());
}
@MyErrorLog
@ExceptionHandler(Exception401.class)
public ResponseEntity<?> unAuthorized(Exception401 e){
return new ResponseEntity<>(e.body(), e.status());
}
@MyErrorLog
@ExceptionHandler(Exception403.class)
public ResponseEntity<?> forbidden(Exception403 e){
return new ResponseEntity<>(e.body(), e.status());
}
@MyErrorLog
@ExceptionHandler(Exception404.class)
public ResponseEntity<?> notFound(Exception404 e){
return new ResponseEntity<>(e.body(), e.status());
}
@MyErrorLog
@ExceptionHandler(Exception500.class)
public ResponseEntity<?> serverError(Exception500 e){
errorLogRepository.save(com.phoenix.assetbe.model.errorLog.ErrorLog.builder() // db에 로그 저장
.msg(e.getMessage())
.userId(getUserId())
.build());
Sentry.captureException(e); // sentry.io로 로그 전송
return new ResponseEntity<>(e.body(), e.status());
}
@MyErrorLog
@ExceptionHandler(Exception.class)
public ResponseEntity<?> unknownServerError(Exception e){
errorLogRepository.save(com.phoenix.assetbe.model.errorLog.ErrorLog.builder() // db에 로그 저장
.msg(e.getMessage())
.userId(getUserId())
.build());
Sentry.captureException(e); // sentry.io로 로그 전송
ResponseDTO<String> responseDTO = new ResponseDTO<>(HttpStatus.INTERNAL_SERVER_ERROR, "unknownServerError", e.getMessage());
return new ResponseEntity<>(responseDTO, HttpStatus.INTERNAL_SERVER_ERROR);
}
private Long getUserId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return null;
}
Object principal = authentication.getPrincipal();
if (principal instanceof MyUserDetails) {
return ((MyUserDetails) principal).getUser().getId();
}
return null;
}
}
@Slf4j
@RequiredArgsConstructor
@Aspect
@Component
public class MyLogAdvice {
@Pointcut("@annotation(com.phoenix.assetbe.core.annotation.MyLog)")
public void myLog(){}
@Pointcut("@annotation(com.phoenix.assetbe.core.annotation.MyErrorLog)")
public void myErrorLog(){}
@AfterReturning("myLog()")
public void logAdvice(JoinPoint jp) throws Exception {
MethodSignature signature = (MethodSignature) jp.getSignature();
Method method = signature.getMethod();
log.debug("디버그 : "+method.getName()+" 성공"); //메서드 성공하면 로그 찍기
}
@Before("myErrorLog()")
public void errorLogAdvice(JoinPoint jp) throws Exception {
Object[] args = jp.getArgs();
for (Object arg : args) {
if(arg instanceof Exception){
Exception e = (Exception) arg;
log.error("에러 : "+e.getMessage()); // 에러 로그 찍기
}
}
}
}
@Aspect
@Component
public class MyValidAdvice {
@Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
public void postMapping() {
}
@Pointcut("@annotation(org.springframework.web.bind.annotation.PutMapping)")
public void putMapping() {
}
// @Valid에 대한 errors를 exception으로 던져줌.
@Before("postMapping() || putMapping()")
public void validationAdvice(JoinPoint jp) {
Object[] args = jp.getArgs();
for (Object arg : args) {
if (arg instanceof Errors) {
Errors errors = (Errors) arg;
if (errors.hasErrors()) {
throw new Exception400(
errors.getFieldErrors().get(0).getField(),
errors.getFieldErrors().get(0).getDefaultMessage()
);
}
}
}
}
}
즉, sentry를 연결해서 에러를 모아주는 거는 할 수 있다. 하지만 이 에러를 슬랙으로 보내 팀원들과 같이 공유하는 부분을 해보려고 노력했지만, 생각보다 오래걸렸다.
알고보니까 돈을 내면되는 거였다!!!!!!!!!!!
上男子
上男子 스케줄