복붙노트

[SPRING] 스프링 부트 2.0에서`@Endpoint (id = "health")`를 만드는 방법은?

SPRING

스프링 부트 2.0에서`@Endpoint (id = "health")`를 만드는 방법은?

스프링 부트 2.0.0.M5에서 건강 액추에이터를 사용자 정의하는 새로운 방법을 시도했습니다. 여기에 설명되어 있습니다 : https://spring.io/blog/2017/08/22/introducing-actuator-endpoints-in-spring- boot-2-0 :

@Endpoint(id = "health")
public class HealthEndpoint {
    @ReadOperation
    public Health health() {
        return new Health.Builder()
            .up()
            .withDetail("MyStatus", "is happy")
            .build();
    }
}

그러나 localhost : port / application / health에 HTTP GET을 실행해도 표준 기본 건강 정보를 얻습니다. 내 코드는 완전히 무시됩니다.

HealthIndicator 구현을 통해 건강 정보를 사용자 지정하는 "전통적인 방법"을 사용하면 예상대로 작동하고 건강 정보는 주어진 세부 정보로 장식됩니다.

@Component
public class MyHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        return new Health.Builder()
            .up()
            .withDetail("MyStatus 1.1", "is happy")
            .withDetail("MyStatus 1.2", "is also happy")
            .build();
    }
}

QUESTION : @ Endpoint (id = "health") 솔루션을 만들기 위해 더 이상 구성하거나 구현해야하는 것은 무엇입니까?

내 의도는 사용자 정의 액츄에이터를 만들지 않고 기존 건강 액추에이터를 사용자 정의하는 것입니다. 문서를 바탕으로 HealthIndicator를 구현 한 것과 같은 결과를 얻을 것으로 기대합니다. 나는 그 가정에서 틀린가?

Maven 설정 pom.xml은 다음을 포함합니다 :

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.M5</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

Spring 부트 설정 application.properties는 다음을 포함합니다 :

endpoints.health.enabled=true
endpoints.autoconfig.enabled=true
endpoints.autoconfig.web.enabled=true

해결법

  1. ==============================

    1.Spring Boot 2.0에서 커스텀 액추에이터 엔드 포인트를 생성하는 데 필요한 변경 사항은 다음과 같습니다.

    Spring Boot 2.0에서 커스텀 액추에이터 엔드 포인트를 생성하는 데 필요한 변경 사항은 다음과 같습니다.

    사용자 정의 정보를 포함하는 도메인.

    @Data
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    public class MyHealth {
    
        private Map<String, Object> details;
    
        @JsonAnyGetter
        public Map<String, Object> getDetails() {
            return this.details;
        }
    }
    

    myhealth 종점 선언,

    @Endpoint(id = "myhealth")
    public class MyHealthEndpoint {
    
        @ReadOperation
        public MyHealth health() {
            Map<String, Object> details = new LinkedHashMap<>();
            details.put("MyStatus", "is happy");
            MyHealth health = new MyHealth();
            health.setDetails(details);
    
            return health;
        }
    }
    

    myhealth 엔드 포인트 확장,

    @WebEndpointExtension(endpoint = MyHealthEndpoint.class)
    public class MyHealthWebEndpointExtension {
    
        private final MyHealthEndpoint delegate;
    
        public MyHealthWebEndpointExtension(MyHealthEndpoint delegate) {
            this.delegate = delegate;
        }
    
        @ReadOperation
        public WebEndpointResponse<MyHealth> getHealth() {
            MyHealth health = delegate.health();
            return new WebEndpointResponse<>(health, 200);
        }
    }
    

    두 개의 새로 생성 된 액추에이터 클래스를 Bean으로 노출시키는 구성,

    @Configuration
    public class ActuatorConfiguration {
    
        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnEnabledEndpoint
        public MyHealthEndpoint myHealthEndpoint() {
            return new MyHealthEndpoint();
        }
    
        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnEnabledEndpoint
        @ConditionalOnBean({MyHealthEndpoint.class})
        public MyHealthWebEndpointExtension myHealthWebEndpointExtension(
                MyHealthEndpoint delegate) {
            return new MyHealthWebEndpointExtension(delegate);
        }
    }
    

    application.yml에 대한 변경 사항,

    endpoints:
      myhealth:
        enabled: true
    

    애플리케이션을 시작하면 http : // : / application / myhealth에서 새로 액츄에이터 엔드 포인트에 액세스 할 수 있어야합니다.

    아래에 표시된 것과 비슷한 응답을 기대해야합니다.

    {
      "MyStatus": "is happy"
    }
    

    완전한 작업 예제는 여기에서 찾을 수 있습니다.

  2. ==============================

    2.자신 만의 @WebEndpoint를 제공하십시오.

    자신 만의 @WebEndpoint를 제공하십시오.

    @Component
    @WebEndpoint(id = "acmehealth")
    public class AcmeHealthEndpoint {
    
        @ReadOperation
        public String hello() {
          return "hello health";
        }
    }
    

    application.properties를 통해 :

    management.endpoints.web.exposure.include=acmehealth
    management.endpoints.web.path-mapping.health=internal/health
    management.endpoints.web.path-mapping.acmehealth=/health
    

    이 기능은 사용자 정의 HealthIndicator처럼 기존 / 건강 정보를 추가하는 것이 아니라 건강 정보를 완전히 무시합니다. @ Endpoint (id = "health")와 "내 의도는 사용자 정의 액추에이터를 만들지 않고 기존 건강 액추에이터를 사용자 정의하는 것입니다"라는 질문은 원하는 것입니다. 그러나 AcmeHealthEndpoint에서 기존 HealthEndpoint를 사용하고 두 가지를 모두 수행 할 수 있습니다.

    @Component
    @WebEndpoint(id = "prettyhealth")
    public class PrettyHealthEndpoint {
    
        private final HealthEndpoint healthEndpoint;
        private final ObjectMapper objectMapper;
    
        @Autowired
        public PrettyHealthEndpoint(HealthEndpoint healthEndpoint, ObjectMapper objectMapper) {
            this.healthEndpoint = healthEndpoint;
            this.objectMapper = objectMapper;
        }
    
        @ReadOperation(produces = "application/json")
        public String getHealthJson() throws JsonProcessingException {
            Health health = healthEndpoint.health();
            ObjectWriter writer = objectMapper.writerWithDefaultPrettyPrinter();
            return writer.writeValueAsString(health);
        }
    
        @ReadOperation
        public String prettyHealth() throws JsonProcessingException {
            return "<html><body><pre>" + getHealthJson() + "</pre></body></html>";
        }
    }
    
  3. from https://stackoverflow.com/questions/46796899/how-to-make-the-endpointid-health-working-in-spring-boot-2-0 by cc-by-sa and MIT license