-
Notifications
You must be signed in to change notification settings - Fork 58
[김준우] sprint7 #352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "part2-\uAE40\uC900\uC6B0-sprint7"
[김준우] sprint7 #352
Conversation
…준우-sprint6 [김준우] sprint6
- 예외 필드 수정 - DiscodeitException을 상속하는 주요 도메인 별 메인 예외 클래스 정의 완료 - 도메인 메인 예외 클래스를 상속하는 구체적인 예외 클래스 정의 완료 - 기존 구현한 예외를 커스텀 예외로 대체 완료
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 준우님,
통합테스트를 제외한 나머지 요구사항을 모두 잘 구현해주셨네요 💯
참고하면 좋을 코멘트 몇가지 남겨두었습니다!
질문주신 내용에 대한 답변은 아래에 따로 남겨둘게요.
실무에서 Spring Boot Actuator와 Spring Boot Admin을 어떤 용도로 가장 많이 활용하는지 궁금합니다
제가 속한 팀을 기준으로 하면 Spring Boot Actuator는 현재 사용하고 있고, Spring Boot Admin은 따로 사용하고 있지 않습니다.
Actuator는 스프링부트 서버의 메트릭을 노출하는 용도로 사용하고 있어요.
모니터링 환경 구축에는 Actuator를 포함해 프로메테우스, 그라파나라는 도구를 사용하고 있습니다!
모니터링 환경을 어떻게 구축할 것인가에 대한 이야기는 길어질 것 같으니 이정도로만 이야기하고 넘어갈게요.
password: ${DB_PASSWORD} | ||
jpa: | ||
hibernate: | ||
ddl-auto: none |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
운영환경에서 ddl-auto: none
보다 더 좋은건 validate라고 생각해요.
엔터티와 DB 테이블의 불일치를 서버를 띄울 때 바로 알 수 있어서요!
logging: | ||
level: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logging.level.root
설정도 추가되면 좋을 것 같아요.
logging: | |
level: | |
logging: | |
level: | |
root: info |
|
||
@ExceptionHandler(IllegalArgumentException.class) | ||
public ResponseEntity<String> handleException(IllegalArgumentException e) { | ||
e.printStackTrace(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.printStackTrace();
는 성능 상의 문제를 야기하기에 지양하는게 좋습니다.
@ExceptionHandler(NoSuchElementException.class) | ||
public ResponseEntity<String> handleException(NoSuchElementException e) { | ||
e.printStackTrace(); | ||
return ResponseEntity | ||
.status(HttpStatus.NOT_FOUND) | ||
.body(e.getMessage()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기선 따로 log를 안찍어도 괜찮을까요?
@@ -0,0 +1,9 @@ | |||
package com.sprint.mission.discodeit.dto.request; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
컨트롤러 Req, Res는 controller 패키지 하위에 있어도 좋을 것 같아요.
info: | ||
env: | ||
enabled: true | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
env.enabled: true
설정은 환경 변수와 프로퍼티 정보를 제공하는데요,
운영 환경에서는 이러한 정보가 보안 취약점이 될 수 있으므로, false
로 설정하는 것이 좋습니다.
@Test | ||
@DisplayName("채널 ID로 가장 마지막 메시지 시간을 조회한다.") | ||
void findLastMessageAtByChannelId() { | ||
UUID channelId = UUID.fromString("11111111-1111-1111-1111-111111111111"); | ||
|
||
Optional<Message> message = messageRepository.findById(UUID.fromString("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaa0020")); | ||
Optional<Instant> result = messageRepository.findLastMessageAtByChannelId(channelId); | ||
|
||
assertThat(result).isPresent(); | ||
assertThat(message.get().getCreatedAt()).isEqualTo(result.get()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 테스트는 when절이 2개인데요,
하나의 테스트가 여러 행동을 검증하는건 아닐까요?
기본 요구사항
프로파일 기반 설정 관리
application-dev.yaml
,application-prod.yaml
파일을 생성하세요.로그 관리
@Slf4j
어노테이션을 활용해 로깅을 쉽게 추가할 수 있도록 구성하세요.application.yaml
에 기본 로깅 레벨을 설정하세요.info
레벨로 설정합니다.debug
, 운영 환경에서는info
레벨로 설정합니다.logback-spring.xml
파일을 생성하세요.다음 예시와 같은 로그 메시지를 출력하기 위한 로깅 패턴과 출력 방식을 커스터마이징하세요.
로그 출력 예시
콘솔과 파일에 동시에 로그를 기록하도록 설정하세요.
{프로젝트 루트}/.logs
경로에 저장되도록 설정하세요.로그 파일은 일자별로 롤링되도록 구성하세요.
로그 파일은 30일간 보관하도록 구성하세요.
예외 처리 고도화
커스텀 예외를 설계하고 구현하세요.
패키지명:
com.sprint.mission.discodeit.exception[.{도메인}]
ErrorCode
Enum 클래스를 통해 예외 코드명과 메시지를 정의하세요.아래는 예시입니다. 필요하다고 판단되는 다양한 코드를 정의하세요.
예시
모든 예외의 기본이 되는
DiscodeitException
클래스를 정의하세요.클래스 다이어그램
details
는 예외 발생 상황에 대한 추가정보를 저장하기 위한 속성입니다.DiscodeitException
을 상속하는 주요 도메인 별 메인 예외 클래스를 정의하세요.UserException
,ChannelException
등도메인 메인 예외 클래스를 상속하는 구체적인 예외 클래스를 정의하세요.
UserNotFoundException
,UserAlreadyExistException
등 필요한 예외를 정의하세요.예시
기존에 구현했던 예외를 커스텀 예외로 대체하세요.
NoSuchElementException
IllegalArgumentException
ErrorResponse
를 통해 일관된 예외 응답을 정의하세요.클래스 다이어그램
int status
: HTTP 상태코드String exceptionType
: 발생한 예외의 클래스 이름앞서 정의한
ErrorResponse
와@RestControllerAdvice
를 활용해 예외를 처리하는 예외 핸들러를 구현하세요.ErrorResponse
)을 가져야 합니다.유효성 검사
@NotNull
,@NotBlank
,@Size
,@Email
등@Valid
를 사용해 요청 데이터를 검증하세요.MethodArgumentNotValidException
을 전역 예외 핸들러에서 처리하세요.Actuator
Discodeit
1.7.0
17
3.4.0
/actuator/info
/actuator/metrics
/actuator/health
/actuator/loggers
단위 테스트
Mockito
를 활용해 Repository 의존성을 모의(mock)하세요.BDDMockito
를 활용해 테스트 가독성을 높이세요.슬라이스 테스트
@DataJpaTest
를 활용해 테스트를 구현하세요.application-test.yaml
을 생성하세요.test
프로파일을 활성화 하세요.@EnableJpaAuditing
을 추가하세요.@WebMvcTest
를 활용해 테스트를 구현하세요.WebMvcTest
에서 자동으로 등록되지 않는 유형의 Bean이 필요하다면@Import
를 활용해 추가하세요.예시
주요 컨트롤러(User, Channel, Message)에 대해 최소 2개 이상(성공, 실패)의 테스트 케이스를 작성하세요.
MockMvc를 활용해 컨트롤러를 테스트하세요.
서비스 레이어를 모의(mock)하여 컨트롤러 로직만 테스트하세요.
JSON 응답을 검증하는 테스트를 포함하세요.
통합 테스트
@SpringBootTest
를 활용해 Spring 애플리케이션 컨텍스트를 로드하세요.@Transactional
을 활용해 독립적으로 실행하세요.심화 요구사항
MDC를 활용한 로깅 고도화
MDCLoggingInterceptor
com.**.discodeit.config
Discodeit-Request-ID
WebMvcConfigurer
를 통해MDCLoggingInterceptor
를 등록하세요.WebMvcConfig
com.**.discodeit.config
로그 출력 예시
Spring Boot Admin을 활용한 메트릭 가시화
Spring Boot Admin 서버를 구현할 모듈을 생성하세요.
IntelliJ 화면 참고
모듈 정보는 다음과 같습니다.
의존성
admin
모듈의 메인 클래스에@EnableAdminServer
어노테이션을 추가하고, 서버는 9090번 포트로 설정합니다.admin
서버 실행 후 [localhost:9090/applications](http://localhost:9090/applications) 에 접속해봅니다.discodeit 프로젝트에 Spring Boot Admin Client를 적용합니다.
의존성을 추가합니다.
admin 서버에 등록될 수 있도록 설정 정보를 추가합니다.
discodeit 서버를 실행하고, admin 대시보드에 discodeit 인스턴스가 추가되었는지 확인합니다.
admin 대시보드 화면을 조작해보면서 각종 메트릭 정보를 확인해보세요.
테스트 커버리지 관리
JaCoCo 플러그인을 추가하세요.
테스트 실행 후 생성된 리포트를 분석해보세요.
build/reports/jacoco
경로에서 확인할 수 있습니다.com.sprint.mission.discodeit.service.basic
패키지에 대해서 60% 이상의 코드 커버리지를 달성하세요.스크린샷
멘토에게