ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링 부트 모니터링(2.1) - Health 엔드포인트 탐구
    Web/환경설정 관련 2024. 5. 14. 16:02

     

    • Health 엔드포인트에 접근하면, 애플리케이션과 애플리케이션에서 사용되는 여러 컴포넌트의 상태를 전반적으로 파악할 수 있다. 
    • 스프링 부트는 애플리케이션 컴포넌트별로 다양한 HealthIndicator를 제공하는데, 이 중 DiskSpaceHealthIndicator와 PingHealthIndicator와 같은 일부 구현체는 항상 기본으로 제공한다. 

    1. 좀 더 자세한 정보보기 

     

    • Health 엔드포인트로 애플리케이션에 대한 좀 더 자세한 정보를 수집해보자 
    management.endpoint.health.show-details=always
    
    #총 3가지 값을 지정할 수 있다.
    # always = 상태 상세 정보를 항상 표시 
    # naver = 기본 값이며, 상세 정보를 표시하지 않는다.
    # when-authorized = 애플리케이션이 인증되고, 
    # application.properties파일에 management.endpoint.health.roles로 지정된 역할을 가지고 접근할 때만 볼 수 있다.

    • 스프링 부트는 클래스패스에 있는 의존 관계에 따라 조건적으로 HealthIndicaotor를 활성화한다. 
    • 예를 들어 관계형 데이터 베이스를 사용한다면 스프링 부트는 자동 구성을 통해 DataSourceHealthIndicator를 추가한다.
    • status필드는 애플리케이션 상태 정보를 집약해서 표시하는데, 다음과 같이 기본적으로 네 가지 값을 표시한다.
      • DOWN - 컴포넌트를 정상적으로 사용할 수 없는 상태 
      • OUT-OF-SERVICE - 컴포넌트가 일시적으로 동작하지 않는 상태 
      • UP - 컴포넌트가 의도한 대로 동작하는 상태 
      • UNKNOWN - 컴포넌트 상태를 알 수 없는 상태 
    @Component
    public class CustomHealthIndicator implements HealthIndicator {
        @Override
        public Health health() {
            return Health.status("FATAL").build();
        }
    }

    • HealthIndicator에 health()메서드를 통해 커스텀으로 상태를 추가할 수도 있다. 
    managment.endpoint.health.status.ordr=FATAL,DOWN
    • 상태의 우선순위도 지정할 수 있다. 
    • 애플리케이션의 상태는 엔드포인트의 HTTP 상태 코드에도 영향을 미친다.
    • 스프링 부트는 애플리케이션 상태가 DOWN이나 OUT-OF-SERVICE면 기본적으로 503을 반환하고,
    • UP이나 UNKOWN이면 200일 반환한다. 
    • status와 특정 반환 값을 매핑하고 싶으면, 다음 두가지 방식으로 처리할 수 있다.
    @Component
    public class CustomHealthCodeStatusMapper implements HttpCodeStatusMapper{
    
    	public int getStatusCode(Status status) {
    		if(status == Status.DOWN) {
    			return HttpStatus.INTERNAL_SERVER_ERROR.value();
    		}
    		
    		else if(status == Status.OUT_OF_SERVICE) {
    			return HttpStatus.INTERNAL_SERVER_ERROR.value();
    		}
    		return HttpStatus.OK.value();
    	}
    
    }
    management.endpoint.health.status.http-mapping.down=500

     

    2. 커스텀 스프링 부트 HealthIndicator 작성 

     

    • 기본으로 제공하는 HealthIndicator를 사용할 수도 있지만, 원한다면 적절하게 Custom도 가능하다.
    • 애플리케이션과 연동되는 다른 REST API 시스템의 상태를 보여주는 커스텀 HealthIndicator를 만들어보자 
    package com.example.manyConfig.config.aucuator;
    
    import org.springframework.boot.actuate.health.Health;
    import org.springframework.boot.actuate.health.HealthIndicator;
    import org.springframework.core.ParameterizedTypeReference;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Component;
    import org.springframework.web.reactive.function.client.WebClient;
    import org.springframework.web.reactive.function.client.WebClientRequestException;
    import java.util.Map;
    
    @Component
    public class AppRustHealthIndicator implements HealthIndicator {
    
        @Override
        public Health health() {
            try {
                //abstractClass - 익명 구현
                ParameterizedTypeReference<ResponseEntity<Map<String,String>>> ref =
                        new ParameterizedTypeReference<ResponseEntity<Map<String, String>>>() {};
                WebClient webClient = WebClient.builder().baseUrl("http://dog.ce/api/image").build();
    
               ResponseEntity<Map<String,String>> result = webClient.get().exchange().block().bodyToMono(ref).block();
    
               if(result.getStatusCode().is2xxSuccessful() && result.getBody() != null){
                   return Health.up().withDetails(result.getBody()).build();
               }else{
                   return Health.down().withDetail("status",result.getStatusCode()).build();
               }
    
            }catch (WebClientRequestException ex){
                return Health.down().withException(ex).build();
            }
    
        }
    }
    •  ParameterizedTypeReference<ResponseEntity<Map<String,String>>> 추상 클래스를 익명으로 구현했다.
    • 해당 클래스는 보통RestTemplate와 함께 사용되며, RestAPI로 읽어온 정보를 어떤 Type의 Object로 변환할 지 지정하는데 사용된다. 
      • RestTemplate보다는 WebFlux의 WebClient를 권장한다. 따라서 해당 코드도 WebClient로 작성했지만, 타입변환을 위해 ParameterizedTypeReference는 남겨두었다.
      • ParameterizedTypeReference와 WebClient는 추후 다른 글에서 더 자세히 다룰 예정이다! 
    • 무튼 지정한 url로 요청을 보내고, 해당 결과를 ResponseEntity로 받아와서 검사한다.
      • 요청에 대한 응답을 잘 받았다면, status를 up으로, 아니라면 down하도록 설정해 두었다.

     

    • 해당 URL은 존재하지 않기 때문에 위와 같이 DOWN을 받을 것을 확인할 수 있다. 
    • AppRustHealthIndicator로 이름을 지정하니, components로 appRust가 들어가 있다.

    • HealthIndicator를 통해 위와 같이 애플리케이션의 다양한 상태를 체크해서 모니터링하도록 쉽게 커스텀할 수 있다.
    • DB연결 정보라던지, 특정 API의 동작을 추적한다던지, 하고싶은 것을 적으면 될 것 같다!

     

    참고자료:

    https://velog.io/@dailylifecoding/Java-Using-ParameterizedTypeReferenceType-At-Runtime-Using-Spring-Parameterized

    https://tecoble.techcourse.co.kr/post/2021-07-25-resttemplate-webclient/

    https://www.yes24.com/Product/Goods/122002340

Designed by Tistory.