분류 전체보기 230

로그 파일 Grafana+Promtail+loki 이용해서 실시간 모니터링 적용하기

Grafana+Promtail+loki 를 사용한 이유로그 수집을 하기 위한 기술을 뽑으자면 ELK(Elasticsearch, Logstash, Kibana)를 떠올릴 수 있다.하지만 서버 스펙의 한계(Ec2 프리티어)로, 비교적 가볍게 실행할 수 있는 PromTail, Loki, Grafana를 도입하게 되었다. 모니터링 서버는 다음과 같다. 모니터링 서버에는 Grafana, Loki를 도커로 띄우고, 운영 서버에는 Promtail과 스프링 부트가 도커로 돌아가게 된다. 모니터링 서버를 분리한 이유는 Promtail, Grafana, Loki 같은 로그/메트릭 수집 도구는 많은 I/O와 네트워크 트래픽을 발생시키기 때문에 분리하였다. (모니터링 서버)에 Grafana, Loki 도커로 실행하기docke..

N+1 문제 해결하기 (@EntityGraph 사용)

@EntityGraph란?연관관계가 지연 로딩으로 되어있을 경우 fetch 조인을 사용하여 여러 번의 쿼리를 한 번에 해결할 수 있습니다.@EntityGraph는 Data JPA에서 fetch 조인을 어노테이션으로 사용할 수 있도록 만들어 준 기능입니다.  N+1 발생 이유기본적으로 @OneToMany, @ManyToMany 관계는 Lazy Loading으로 되어 있는 경우JPA에서 @OneToMany와 @ManyToOne 관계 등을 지연 로딩(Lazy)으로 설정한 경우,  연관관계에서 종속된 엔티티는 쿼리 실행 시 select 되지 않고 proxy 객체를 만들어 엔티티가 적용시킵니다. 그 후 해당 proxy 객체를 호출할 때마다 그때 그때 select 쿼리가 실행됩니다. EnttiyGraph 를 사용한..

Jacoco를 이용한 테스트 커버리지 측정후, 보완하기

왜 적용했는가?현재 테스팅을 통해 컨트롤러, 서비스, 도메인, 레포지토리 단에서 코드를 짜고 있다.내 테스트 코드가 얼마나 실제 도메인을 커버를 하고 있는지, 좋은 테스트를 짜고 있는지 궁금하여 Jacoco를 도입하였다. Jacoco란?JaCoCo는 단위 테스트 또는 통합 테스트를 실행하면서 어떤 코드가 실행되었는지 분석하고 커버리지 리포트를 생성해준다. 이를 통해 테스트가 충분히 작성되었는지 확인하고, 테스트 누락된 부분을 보완할 수 있다. Build.gradleplugins { id 'jacoco'}jacoco { toolVersion = "0.8.8" reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir')}test { finali..

스프링 인터셉터(Spring Interceptor)로 API로그 DB에 저장하기

왜 적용했는가?기존 AOP를 통해 모든 API 호출에 대한 로깅을 진행하였다.그런데 PR 리뷰를 받던 중, 다음과 같은 피드백을 받게 되었다.1. 맞지 않는 URL로 요청을 보내는 경우2. Http Method를 이상하게 보내는 경우아예 Pointcut으로 지정한 컨트롤러 메서드를 타지 않기 때문에 로깅이 전혀 불가능하다.또한 치명적인 문제는, 컨트롤러에서 @Valid 어노테이션 조건을 걸어놓은 경우 AOP가 작동하지 않는다. (Valid 여부가 컨트롤러 호출보다 먼저 실행)따라서 본 프로젝트에는 AOP에서 Interceptor로 로깅 요청을 변경하였다. Interceptor로 변경하기프로젝트의 log 도메인이다. LoggingInterceptor와, RequestBodyWrappingFilter로 구분..

인터셉터에서 RequestBody를 Read 하지 못하는 이유 및 해결방법

들어가기 앞서Filter는 ServletRequest를 통해 사용자가 보낸 Http요청에 대한 requestBody 값을 읽어 들일 수 있다. Interceptor에서 또한, ServletRequest를 상속한 HttpServletRequest를 갖는데, 왜 requestBody를 읽을 수 없을까? [Filter]public interface Filter { default void init(FilterConfig filterConfig) throws ServletException { } void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; ..

Spring REST Docs와 Swagger-UI 결합하기

https://helloworld.kurly.com/blog/spring-rest-docs-guide/ 내가 만든 API를 널리 알리기 - Spring REST Docs 가이드편'추석맞이 선물하기 재개발'에 차출되어 API 문서화를 위해 도입한 Spring REST Docs 를 소개합니다.helloworld.kurly.com 들어가기 앞서위 글을 보고, 프로젝트에 RestDocs와 Swagger-UI를 적용해본 이유와 과정을 작성해보고자 합니다.Swagger의 단점기존에 사용하던 스웨거는 정말 편리하지만, 운영코드에 침투적이라는 큰 단점이 있다.RestDocs를 적용함으로써, 컨트롤러 단에서 테스트 코드를 작성해야 하므로, 'Spring RestDocs'를 적용해보았습니다. @GetMapping @..