파이널 프로젝트 에러 모으기 위해 Sentry.io 사용

jaegeunsong97·2023년 6월 29일
0

TIL

목록 보기
140/156
post-thumbnail

2023_6_29_TIL

上男子 되는 길

上男子 TIL

Sentry연결

에러 로그를 모두 한곳에 모아서 관리를 하기 위해서 Sentry.io를 사용했다.

  1. 의존성을 먼저 주입한다.

  1. dev.yml 과 prod.yml에다가 코드를 추가하고 local로 시험을 해보자

  2. 에러를 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()
                    );
                }
            }
        }
    }
}
  1. 확인

즉, sentry를 연결해서 에러를 모아주는 거는 할 수 있다. 하지만 이 에러를 슬랙으로 보내 팀원들과 같이 공유하는 부분을 해보려고 노력했지만, 생각보다 오래걸렸다.

알고보니까 돈을 내면되는 거였다!!!!!!!!!!!

上男子

上男子 스케줄

上男子 스케줄

상남자 스케줄

上男子 노션

상남자의 공부 노션

profile
블로그 이전 : https://medium.com/@jaegeunsong97

0개의 댓글