Pyohwan/english-study

Spring Boot Actuator: Production-ready Features

Opened this issue · 5 comments

https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/html/production-ready-features.html#production-ready-enabling

  • Spring Boot 에는 운영 환경 모니터링을 위한 여러 가지 기능이 있음
    • HTTP 엔드포인트 or JMX 를 사용하여 애플리케이션을 관리하고 모니터링 가능 함
    • Auditing, health, metrics 수집 또한 자동으로 적용 됨

1. Enabling Production-ready Features

  • spring-boot-actuator 모듈이 모든 운영 환경 기능을 제공한다
  • 가장 쉬운 방법은 spring-boot-starter-actuator ‘Starter’ 를 추가해라

Definition of Actuator

  • 액츄에이터는 물건을 움직이거나 제어를 위한 기계 장치(제조 용어)
  • 액츄에이터는 작은 변화로 많은 움직임(motion)을 생성할 수 있다.
dependencies {
    compile("org.springframework.boot:spring-boot-starter-actuator")
}

2. Endpoints

  • 액츄에이터 엔드포인트를 사용하면 애플리케이션을 모니터링하고 상호작용 가능하다

  • Spring Boot 에는 built-in 엔드포인트가 여러개 포함되어 있고, 사용자가 직접 추가도 가능하다

    • 예를 들어, health 엔드포인트는 애플리케이션의 기본 health 정보를 제공한다
  • 개별 엔드포인트는 비활성화 가능하다

    • application context 에 엔드포인트 Bean 이 존재하는지 안하는지로 제어한다.
  • 원격 접근 할려면 JMX or HTTP 로 노출(expose) 해야 한다

    • 대개 HTTP를 쓴다
    • /actuator 과 함께 엔드포인트가 URL 에 매핑된다
      • 예를 들어, health 엔드포인트는 /actuator/health
  • 사용 가능한 technology-agnostic endpoints

ID Description
auditevents Exposes audit events information for the current application. Requires an AuditEventRepository bean.
beans Displays a complete list of all the Spring beans in your application.
caches Exposes available caches.
conditions Shows the conditions that were evaluated on configuration and auto-configuration classes and the reasons why they did or did not match.
configprops Displays a collated list of all @ConfigurationProperties.
env Exposes properties from Spring’s ConfigurableEnvironment.
flyway Shows any Flyway database migrations that have been applied. Requires one or more Flyway beans.
health Shows application health information.
httptrace Displays HTTP trace information (by default, the last 100 HTTP request-response exchanges). Requires an HttpTraceRepository bean.
info Displays arbitrary application info.
integrationgraph Shows the Spring Integration graph. Requires a dependency on spring-integration-core.
loggers Shows and modifies the configuration of loggers in the application.
liquibase Shows any Liquibase database migrations that have been applied. Requires one or more Liquibase beans.
metrics Shows ‘metrics’ information for the current application.
mappings Displays a collated list of all @RequestMapping paths.
scheduledtasks Displays the scheduled tasks in your application.
sessions Allows retrieval and deletion of user sessions from a Spring Session-backed session store. Requires a Servlet-based web application using Spring Session.
shutdown Lets the application be gracefully shutdown. Disabled by default.
threaddump Performs a thread dump.
  • 웹 애플리케이션(Spring MVC, Spring WebFlux, or Jersey)인 경우 추가되는 엔드포인트
ID Description
heapdump Returns an hprof heap dump file.
jolokia Exposes JMX beans over HTTP (when Jolokia is on the classpath, not available for WebFlux). Requires a dependency on jolokia-core.
logfile Returns the contents of the logfile (if logging.file.name or logging.file.path properties have been set). Supports the use of the HTTP Range header to retrieve part of the log file’s content.
prometheus Exposes metrics in a format that can be scraped by a Prometheus server. Requires a dependency on micrometer-registry-prometheus.
  • 엔드포인트 요청 및 응답 형식은 다음 문서 참고

2.1. Enabling Endpoints

  • 기본적으로 shutdown 을 제외한 모든 엔드포인트는 활성화
  • management.endpoint.<id>.enabled 로 컨트롤 가능
    • shutdown 엔드포인트 활성화 하기
management.endpoint.shutdown.enabled=true
  • 엔드포인트 활성화를 사전동의 없이(opt-out) 하는것보다 사전 동의를 받게끔(opt-in)으로 할려면 management.endpoints.enabled-by-defaultfalse로 해라.
    • 개별적인 엔드포인트를 enabled 해라
  • 다음 예제는 info 엔드포인트를 enabled 하고 다른 모든 엔드포인트들을 disables 한다.
management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true

diasbled 엔드포인트는 애플리케이션 컨텍스트에서 완전히 제거된다. 기술적인 변화로 expose 를 원한다면, include and exclude properties 를 대신 써라

2.2 Exposing Endpoints

  • 엔드포인트는 민감한 정보를 포함할 수 있으므로, expose 시기를 신중하게 고려해라
  • 다음은 built-in 엔드포인트의 기본 exposure 테이블이다
ID JMX Web
auditevents Yes No
beans Yes No
caches Yes No
conditions Yes No
configprops Yes No
env Yes No
flyway Yes No
health Yes Yes
heapdump N/A No
httptrace Yes No
info Yes Yes
integrationgraph Yes No
jolokia N/A No
logfile N/A No
loggers Yes No
liquibase Yes No
metrics Yes No
mappings Yes No
prometheus N/A No
scheduledtasks Yes No
sessions Yes No
shutdown Yes No
threaddump Yes No
  • expose 엔드포인트를 바꾸고 싶다면, include and exclude properties 를 써라
Property Default
management.endpoints.jmx.exposure.exclude  
management.endpoints.jmx.exposure.include *
management.endpoints.web.exposure.exclude  
management.endpoints.web.exposure.include info, health
  • include 는 expose 를 원하는 엔드포인트의 IDs 목록이다.
  • exclude 는 반대로 expose 를 원하지 않는 엔드포인트의 IDs 목록이다.
  • excludeinclude 보다 우선순위가 높다
  • 예를 들어, JMX 엔드포인트 expose 는 모두 중지하고, healthinfo 엔드포인트만 expose 하고 싶다면?
management.endpoints.jmx.exposure.include=health,info
  • * 로 모든 엔드포인트 선택 가능
    • 예를 들어, envbeans 을 제외한 모든 것을 HTTP 를 통해 expose 하고 싶다면?
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans

* 는 YAML 에서 특별한 의미가 있으므로, 따옴표를 추가 해야 함

management:
  endpoints:
    web:
      exposure:
        include: "*"

엔드포인트가 public 하게 expose 되어 있다면 엔드포인트 보안이 필요하다

엔드포인트에 대한 별도 전략이 필요하면 EndpointFilter bean 을 등록 해라

2.3. Securing HTTP Endpoints

  • 다른 민감한 URL 과 마찬가지로 HTTP 엔드포인트도 보호해야 한다
  • Spring Security 가 있다면, content-negotiation strategy 으로 기본적으로 보호된다
  • 예를 들어, 특정 role 을 가진 사용자만 HTTP 엔드포인트에 커스텀 보안을 적용하려는 경우, Spring Security 와 함께 RequestMatcher 를 제공한다
  • 일반적인 Spring Security 구성은 다음과 유사하다
@Configuration(proxyBeanMethods = false)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
                requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
        http.httpBasic();
    }
}
  • 위 코드는 EndpointRequest.toAnyEndpoint()는 모든 엔드포인트를 말하고, ENDPOINT_ADMIN role 을 가졌는지 검사
  • 방화벽 뒤에서 애플리케이션을 배포하는 경우, 인증 없이 모든 엔드포인트에 접근할 수 있다.
management.endpoints.web.exposure.include=*
  • 추가적으로 미인증 접근에 대해서 엔드포인트 접근을 허용하기 위해선
@Configuration(proxyBeanMethods = false)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
            requests.anyRequest().permitAll());
    }

}

2.4. Configuring Endpoints

  • 엔드포인트는 파라미터 없는 읽기 작업은 자동으로 캐싱한다
    • cache.time-to-live 로 응답 캐시 시간을 설정 가능
    • 다음 예제는 10초 캐싱
management.endpoint.beans.cache.time-to-live=10s

management.endpoint.<name> 는 고유하게 식별하는데 사용된다.
인증된 HTTP 요청 시, Principal 이 엔드포인트 입력에 사용되므로, 캐시 되지 않는다

2.5. Hypermedia for Actuator Web Endpoints

  • 모든 엔드포인트의 "discovery page" 링크가 추가된다.
    • 기본적으로 /actuator 에서 이용 가능
  • 커스텀 management context path 가 구성되면 "discovery page" 가 자동으로 /actuator 에서 root management context 로 이동한다.
    • context path 가 /management 이면, discovery page 는 /management 에서 이용 가능
    • context path 가 / 면 다른 매핑과의 충돌 방지를 위해 disabled 된다.

2.6. CORS Support

  • Cross-origin resource sharing (CORS) 는 W3C 스펙으로, cross-domain 요청이 승인 되는지 유연하게 지정할 수 있다
  • Spring MVC or Spring WebFlux 의 액츄에이터에서는 이러한 시나리오를 구성할 수 있는 웹 엔드포인트가 있다
  • CORS 는 기본적으로 disabled 다. management.endpoints.web.cors.allowed-origins 로 활성화 가능.
  • 다음 구성은 example.com 도메인에서 GET 및 POST 호출을 허용합니다.
management.endpoints.web.cors.allowed-origins=https://example.com
management.endpoints.web.cors.allowed-methods=GET,POST

2.7. Implementing Custom Endpoints

  • @bean@endpoint 을 함께 붙히고, @ReadOperation, @WriteOperation, or @DeleteOperation 중에 하나 있으면, JMX 나 웹 HTTP 로 expose 된다
    • @JmxEndpoint or @WebEndpoint 로 JMX or Web 으로만 expose 가능
  • @EndpointWebExtension and @EndpointJmxExtension 으로 더 확장 가능 하다.
  • web-framework-specific 기능에 접근해야 하면, Spring @controller and @RestController 엔드포인트를 구현하면 된다.

2.7.1. Receiving Input

  • 엔드포인트 조작은 파라미터를 입력받아서 한다
    • 웹으로 expose 할때, URL 쿼리 파라미터 및 JSON 본문으로 전달 함
    • JMX 로 expose 할때에는, MBean 파라미터로 조작
  • 기본적으로 파라미터가 필수로 요구되는데, @org.springframework.lang.Nullable 로 선택적으로 만들 수 있다
  • JSON 요청 바디
{
    "name": "test",
    "counter": 42
}

메소드 구조는 단순한 타입(int, String 등)만 가능. 커스텀타입으로 namecounter 프로퍼티를 사용할 수 없다.
매핑된 input 파라미터를 조작하려면 엔드포인트 구현체를 -parameters 로 컴파일 해야 한다 (Kotlin 은 -java-parameters) Gradle, Maven 에서 spring-boot-starter-parent 를 쓰고 있다면 자동으로 사용된다

Input type conversion

  • 엔드포인트의 operation 메소드로 전달된 파라미터는 필요한 경우 자동으로 필수 타입(required type)으로 바뀐다.
  • operation 메소드가 호출 전에, JMX or HTTP 요청을 통해 입력된 파라미터는 ApplicationConversionService as well as any Converter or GenericConverter beans qualified with @EndpointConverter 를 통해 필수 타입으로 바뀜

2.7.2. Custom Web Endpoints

  • @endpoint, @WebEndpoint, or @EndpointWebExtension 은 Jersey, Spring MVC, or Spring WebFlux 를 사용해서 HTTP 로 자동으로 expose 된다

Web Endpoint Request Predicates

  • web-exposed endpoint 에서 각 요청의 predicate 는 자동으로 생성 된다

Path

  • predicate 는 엔드포인트 ID 와 엔드포인트의 base path 기준으로 결정된다
    • 기본 base path 는 /actuator 이다
    • 예를 들어 ID sessions 인 경우, predicate 의 path 는 /actuator/sessions 이다
  • @Selector 와 파라미터 조합으로 커스터마이징 가능
    • 모든 path 엘리먼트를 챕켜 하려면 @Selector(Match=ALL_REMAINING)
    • 마지막 파라미터를 String[] 타입으로 넣을 수 있음

HTTP method

Operation HTTP method
@ReadOperation GET
@WriteOperation POST
@DeleteOperation DELETE

Consumes

  • @WriteOperation (HTTP POST) 를 붙히면, predicate 는 application/vnd.spring-boot.actuator.v2+json, application/json 이다.
  • 다른 모든 operations 는 empty 로 consume 한다

Produces

  • @DeleteOperation, @ReadOperation, and @WriteOperation 로 predicate 는 produces 가 판별한다
    • 사용 안하면, 자동으로 결정한다
  • operation 메소드 가 void 를 응답하면, produce 는 empty 가 된다.
  • org.springframework.core.io.Resource 를 응답하면, application/octet-stream 이다
  • 다른 모든 operations 는 application/vnd.spring-boot.actuator.v2+json, application/json 이다

Web Endpoint Response Status

  • 엔드포인트 operation 의 기본 응답 status 는 operation type (read, write, or delete) 에 따라 다르다
  • @ReadOperation 응답시, 응답 status 은 200 (OK) 이다. 응답 값이 없으면, 404 (Not Found)
  • @WriteOperation or @DeleteOperation 응답시, 200 (OK) 이다. 응답 값이 없으면, 204 (No Content)
  • 필수 파라미터 없이 호출, 필수 타입으로 변환 할수 없는 파라미터 등의 operation method 는 400 (Bad Request)

Web Endpoint Range Requests

  • Spring MVC or Spring Web Flux 에서 org.springframework.core.io.Resource 가 range 요청 지원 함

Jersy 에서는 Range 요청 안 됨

Web Endpoint Security

  • web-specific endpoint 조작은 현재 java.security.Principal 나 org.springframework.boot.actuate.endpoint.SecurityContext 로 가능하다
    • 전자는 전형적으로 @nullable 를 주입받아 인증된 사용자, 미인증 사용자가 다르게 행동한다
    • 후자는 isUserInRole(String) 메소드에서 권한 체크하는데 쓰인다

2.7.3. Servlet endpoints

  • Servlet 의 @ServletEndpoint that also implements Supplier 도 구현을 통해 엔드포인트 expose 가능
    • Servlet 엔드포인트는 서블릿 컨테이너와 깊이 연관되는걸 제공하지만, portability 을 포기한다
    • 기존의 서블릿을 expose 한다
    • 새 엔드포인트를 원하면 @endpoint and @WebEndpoint 로 헤리

2.7.4. Controller endpoints

  • @ControllerEndpoint and @RestControllerEndpoint 은 Spring MVC or Spring WebFlux 에서만 expose 되는 엔드포인트를 구현할 수 있다
    • @RequestMapping and @GetMapping 처럼 Spring MVC and Spring WebFlux 에서 쓰는 애너테이션을 쓰면 매핑되고, 엔드포인트 ID 는 path 의 prefix 로 사용 됨
    • 컨트롤러 엔드포인트는 Spring’s web frameworks와 깊이 연관되는걸 제공하지만, portability 을 포기한다
    • @endpoint and @WebEndpoint 사용 가능

2.8. Health Information

  • 실행중인 애플리케이션 health 정보 확인 가능
  • production 시스템이 다운되면 모니터링 하다가 알림 하는데 사용하기 좋다
  • health 엔드포인트로 expose 된다
    • management.endpoint.health.show-detailsmanagement.endpoint.health.show-components 로 구성 가능
Name Description
never Details are never shown.
when-authorized Details are only shown to authorized users. Authorized roles can be configured using management.endpoint.health.roles.
always Details are shown to all users.
  • 기본값은 never
  • 사용자는 하나 이상의 엔드포인트 role 이 있다면 인증되었다고 간주된다
  • 엔드포인트에 구성된 role이 없다면(default) 모든 사용자는 인증되었다고 간주된다
  • management.endpoint.health.roles 로 구성 가능

always 를 사용하여 secured 애플리케이션을 가졌다면, 인증사용자와 미인증사용자 둘다 health 엔드포인트에 접근 가능해야만 한다(must)

  • Health 정보는 HealthContributorRegistry 에서 수집 한다. (기본적으로 HealthContributor 객체)
    • 직접 작성도 가능
  • HealthContributorHealthIndicator or CompositeHealthContributor 로 될 수 있다.
    • HealthIndicatorStatus 를 포함하는 실제 health 정보를 제공
    • CompositeHealthContributor 는 다른 HealthContributors 와 혼합을 제공
  • 기본적으로 최종 health 시스템은 StatusAggregator (HealthIndicator 에서 status 를 정렬한) 에서 유래한다.
    • 정렬된 목록에서 첫번째 status 는 전체 health status 다
    • HealthIndicator 응답이 없다면 UNKNOWN status 가 사용된다

HealthContributorRegistry 는 런타임으로 health indicator 를 등록 및 해제할때 쓴다

2.8.1. Auto-configured HealthIndicators

  • 자동 구성되는 HealthIndicators
Name Description
CassandraHealthIndicator Checks that a Cassandra database is up.
CouchbaseHealthIndicator Checks that a Couchbase cluster is up.
DiskSpaceHealthIndicator Checks for low disk space.
ElasticSearchRestHealthContributorAutoConfiguration Checks that an Elasticsearch cluster is up.
HazelcastHealthIndicator Checks that a Hazelcast server is up.
InfluxDbHealthIndicator Checks that an InfluxDB server is up.
JmsHealthIndicator Checks that a JMS broker is up.
LdapHealthIndicator Checks that an LDAP server is up.
MailHealthIndicator Checks that a mail server is up.
MongoHealthIndicator Checks that a Mongo database is up.
Neo4jHealthIndicator Checks that a Neo4j database is up.
PingHealthIndicator Always responds with UP.
RabbitHealthIndicator Checks that a Rabbit server is up.
RedisHealthIndicator Checks that a Redis server is up.
SolrHealthIndicator Checks that a Solr server is up.

management.health.defaults.enabled 로 모두 diable 할 수 있음

2.8.2. Writing Custom HealthIndicators

  • HealthIndicator 인터페이스 구현해서 커스터마이징 해라
    • health() 메소드와 Health 응답 반환을 제공해라
    • Health 응답은 status 를 포함해야 하고, 선택적으로 세부 정보도 넣을 수 있다
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class MyHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        int errorCode = check(); // perform some specific health check
        if (errorCode != 0) {
            return Health.down().withDetail("Error Code", errorCode).build();
        }
        return Health.up().build();
    }

}

주어진 HealthIndicator ID 는 HealthIndicator suffix 를 뺀 bean 이다. 위의 경우 my

  • Spring Boot 는 이미 정의된 Status 타입 말고도 사용자 정의 가능함
    • StatusAggregator 를 구현하거나, management.endpoint.health.status.order 를 설정해라
  • 예를 들어, FATAL Status 를 가진 HealthIndicator 구현체가 있을때, severity 우선순위 대로 적으면 된다
management.endpoint.health.status.order=fatal,down,out-of-service,unknown,up
  • 전체 health 의 응답 HTTP status 코드를 반영한다. (ex UP 은 200, OUT_OF_SERVICE and DOWN 는 503)
    • 사용자 정의 가능함. FATAL 을 503 으로 설정
management.endpoint.health.status.http-mapping.fatal=503

더 많이 조절해야 하면, HttpCodeStatusMapper Bean 을 정의해라

  • 내장된 기본 status 매핑
Status Mapping
DOWN SERVICE_UNAVAILABLE (503)
OUT_OF_SERVICE SERVICE_UNAVAILABLE (503)
UP No mapping by default, so http status is 200
UNKNOWN No mapping by default, so http status is 200

2.8.3. Reactive Health Indicators

  • Spring WebFlux 에서 ReactiveHealthContributor 은 non-blocking 으로 health 접근 가능
    • ReactiveHealthContributorRegistry (기본적으로 HealthContributor and ReactiveHealthContributor 객체) 에서 컨텐츠 수집 함
  • reactive API 를 하지 않는 일반적인 HealthContributors 는 스케쥴러로 실행 함

ReactiveHealthContributorRegistry 로 health indicator를 실시간으로 등록, 안등록

  • ReactiveHealthIndicator 인터페이스 구현 가능. 다음은 ReactiveHealthIndicator 구현체를 보여줌
@Component
public class MyReactiveHealthIndicator implements ReactiveHealthIndicator {

    @Override
    public Mono<Health> health() {
        return doHealthCheck() //perform some specific health check that returns a Mono<Health>
            .onErrorResume(ex -> Mono.just(new Health.Builder().down(ex).build()));
    }

}

오류를 자동으로 처리하려면 AbstractReactiveHealthIndicator 를 확장해라

2.8.4. Auto-configured ReactiveHealthIndicators

  • 자동구성되는 ReactiveHealthIndicators
Name Description
CassandraReactiveHealthIndicator Checks that a Cassandra database is up.
CouchbaseReactiveHealthIndicator Checks that a Couchbase cluster is up.
MongoReactiveHealthIndicator Checks that a Mongo database is up.
RedisReactiveHealthIndicator Checks that a Redis server is up.

필요한 경우, reactive indicator 는 regular 로 대체된다. 명시적으로 처리 되지 않은 HealthIndicator 은 자동 래핑된다

2.8.5. Health Groups

  • health indicators 를 그룹핑 할 수 있다
    • Kubernetes 에 배포할때에는 “liveness” and “readiness” probes health 세트가 필요할 수 있다
  • Health indicator 그룹을 만들려면 management.endpoint.health.group.<name> 를 써라
    • include or exclude 설정 가능
management.endpoint.health.group.custom.include=db
  • localhost:8080/actuator/health/custom 에서 확인 해봐라
  • 기본 그룹은 StatusAggregator and HttpCodeStatusMapper 설정을 상속 받음
    • show-details and roles 로 재정의도 가능함
management.endpoint.health.group.custom.show-details=when-authorized
management.endpoint.health.group.custom.roles=admin
management.endpoint.health.group.custom.status.order=fatal,up
management.endpoint.health.group.custom.status.http-mapping.fatal=500

커스텀 StatusAggregator or HttpCodeStatusMapper 를 그룹으로 등록해야 하면, @Qualifier("groupname") 를 써라

2.9. Application Information

  • ApplicationContext 에 정의된 모든 InfoContributor 빈에서 수집된 다양한 정보를 expose 한다
    • 여러가지 자동구성된것도 있고, 직접 작성도 가능

2.9.1. Auto-configured InfoContributors

  • 적절하게 알아서 자동구성
Name Description
EnvironmentInfoContributor Exposes any key from the Environment under the info key.
GitInfoContributor Exposes git information if a git.properties file is available.
BuildInfoContributor Exposes build information if a META-INF/build-info.properties file is available.

management.info.defaults.enabled 로 모두 비활성 가능

2.9.2. Custom Application Information

  • info.* 으로 설정 가능
  • info 아래 모든 Environment properties 가 자동으로 expose 된다.
info.app.encoding=UTF-8
info.app.java.source=1.8
info.app.java.target=1.8

이렇게 hardcoding 말고, 빌드시 주입 가능

info.app.encoding=@project.build.sourceEncoding@
info.app.java.source=@java.version@
info.app.java.target=@java.version@

2.9.3. Git Commit Information

  • 빌드 될때 git 소스 코드 레파지터리에 대한 상태도 게시한다
  • GitProperties 빈이 사용 가능하면 git.branch, git.commit.id, and git.commit.time 가 expose 된다

git.properties 파일이 사용 가능하면 GitProperties 빈은 자동구성 됨

  • 전체 git 정보 표시를 원하면 이렇게 해라
management.info.git.mode=full

2.9.4. Build Information

  • BuildProperties 빈이 사용 가능하면, info 엔드포인트가 빌드 정보를 게시한다. META-INF/build-info.properties 파일이 classpath 에 있어야 한다

Gradle, Maven 플러그인으로 지원

2.9.5. Writing Custom InfoContributors

  • InfoContributor 인터페이스를 구현하면 커스텀 가능
import java.util.Collections;

import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;

@Component
public class ExampleInfoContributor implements InfoContributor {

    @Override
    public void contribute(Info.Builder builder) {
        builder.withDetail("example",
                Collections.singletonMap("key", "value"));
    }

}
  • 응답은?
{
    "example": {
        "key" : "value"
    }
}

3. Monitoring and Management over HTTP

  • 웹 애플리케이션을 개발하면, 스프링 부트 Actuator 는 모든 활성화된 엔드포인트를 HTTP 로 expose 한다
  • 기본 컨벤션은 엔드포인트 id 와 /actuator prefix 를 사용하는 URL path 다.
    • 예를 들어 health/actuator/health 로 expose 한다

Actuator 는 기본적으로 Spring MVC, Spring WebFlux, and Jersey 를 지원한다.

3.1. Customizing the Management Endpoint Paths

  • 때로는 커스텀 prefix 를 management 엔드포인트로 쓰는것이 유용하다.
    • 예를 들어, 애플리케이션이 다른 목적으로 actuator 를 사용중이라면, management.endpoints.web.base-path 로 management 엔드포인트 prefix 를 바꿀 수 있다.
management.endpoints.web.base-path=/manage
  • 위에서는 /actuator/{id} to /manage/{id} (for example, /manage/info). 로 바뀐다

management 포트가 다른 HTTP 포트로 구성되어 expose 안되었을 경우, management.endpoints.web.base-pathserver.servlet.context-path 와 관련된다. 만약 management.server.port 가 구성되면, management.endpoints.web.base-pathmanagement.server.servlet.context-path 와 관련된다.

  • 엔드포인트를 다른 path 로 맵 하고 싶을때는 management.endpoints.web.path-mapping 를 써라
  • 다음은 /actuator/health to /healthcheck 로 리맵하는 예제다
management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=healthcheck

3.2. Customizing the Management Server Port

  • 기본 HTTP port 로 management 엔드포인트를 expose 하는것은 cloud-based 배포에서는 현명한 선택이다
  • 그러나 자체 데이터 센터에서 애플리케이션을 실행한다면, 다른 HTTP 포트를 사용하는 것이 좋다
  • management.server.port 로 바꿀수 있다
management.server.port=8081

Cloud Foundry 에서는 8080 port 에서 HTTP 와 TCP 라우팅을 요청을 받습니다.

3.3. Configuring Management-specific SSL

  • 커스텀 포트로 구성했을때 management 서버는 management.server.ssl.* 를 이용해 SSL 로 구성할 수 있다.
  • 예를 들어, 메인 애플리케이션은 HTTPS 를 쓰지만, management 서버는 HTTP 를 쓰도록 핟다.
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:store.jks
server.ssl.key-password=secret
management.server.port=8080
management.server.ssl.enabled=false
  • 그렇지 않으면, 메인 서버와 management 서버 둘다 SSL 을 사용할 수 있다. (다른 key stores)
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:main.jks
server.ssl.key-password=secret
management.server.port=8080
management.server.ssl.enabled=true
management.server.ssl.key-store=classpath:management.jks
management.server.ssl.key-password=secret

3.4. Customizing the Management Server Address

  • management.server.address 로 management 엔드포인트가 사용 가능한 adress 를 커스텀 가능
  • internal or ops-facing(?) 네트워트만 listen 하고 싶거나 localhost 만 listen 하고 싶을때 유용하다.

메인 서버 포트와 달라야만 다른 address 에서 listen 가능하다

  • 다음 예제에서는 원격 management 연결을 허용하지 않는다
management.server.port=8081
management.server.address=127.0.0.1

3.5. Disabling HTTP Endpoints

  • HTTP 로 엔드포인트를 expose 하고 싶지 않다면, management port 를 -1 로 해라
management.server.port=-1
  • management.endpoints.web.exposure.exclude 를 써도 된다
management.endpoints.web.exposure.exclude=*

4. Monitoring and Management over JMX

  • Java Management Extensions (JMX) 은 애플리케이션을 관리하고 모니터를 하는 표준 메커니즘을 제공한다.
    • 기본적으로 이 기능은 활성화 되어 있지 않고, spring.jmx.enabled to true 해야만 켤수 있다
  • 스프링부트에서는 기본적으로 management 엔드포인트를 JMX MBeans 으로 expose 한다.

4.1. Customizing MBean Names

  • MBean 은 일반적으로 id 엔드포인트로 생성 된다.
    • 예를 들어 health 엔드포인트는 org.springframework.boot:type=Endpoint,name=Health 로 expose 된다
  • 애플리케이션에 둘 이상의 ApplicationContext 가 있다면 충돌날 수 있다.
    • MBean 이 항상 유니크 하도록 spring.jmx.unique-names property to true 하면 된다
  • JVX 도메인을 커스터마이징 하여 엔드포인트 노출 가능하다.
spring.jmx.unique-names=true
management.endpoints.jmx.domain=com.example.myapp

4.2. Disabling JMX Endpoints

  • JMX 엔드포인트를 expose 원하지 않는다면 management.endpoints.jmx.exposure.exclude property to * 로 설정 해라
management.endpoints.jmx.exposure.exclude=*

4.3. Using Jolokia for JMX over HTTP

  • Jolokia 는 JMX beans 에 접근 대체 방법을 제공하는 JMX-HTTP 브리지다.
    • org.jolokia:jolokia-core 를 추가해라
<dependency>
    <groupId>org.jolokia</groupId>
    <artifactId>jolokia-core</artifactId>
</dependency>
  • 그런다음 management.endpoints.web.exposure.include 에 jolokia or * 을 넣으면, Jolokia 엔드포인트가 expose 된다
    • management HTTP 서버에서 /actuator/jolokia 로 접근 가능

4.3.1. Customizing Jolokia

  • 전통적으로 서블릿 파라미터를 통해 세팅 가능하다
  • 스프링부트에서는 management.endpoint.jolokia.config. 로 설정 가능하다
management.endpoint.jolokia.config.debug=true

4.3.2. Disabling Jolokia

  • Jolokia 를 쓰지만 스프링부트에서 안 쓸려면
management.endpoint.jolokia.enabled=false

5. Loggers

  • Spring Boot Actuator 는 런타임시 애플리케이션 로그 레벨을 보고 설정 가능한 기능이 포함되어 있다
  • 로그 레벨
    • TRACE
    • DEBUG
    • INFO
    • WARN
    • ERROR
    • FATAL
    • OFF
    • null
  • null indicates 은 명시적인 구성이 없음을 말함

5.1. Configure a Logger

  • 주어진 로거를 구성하기 위해 resource’s URI 에 POST 해라
{
    "configuredLevel": "DEBUG"
}

로거 레벨을 "reset" 하기 위해(기본 구성을 사용하려고), configuredLevelnull 로 할 수 있다.

6. Metrics

  • Spring Boot Actuator 는 많은 모니터링 시스템과 애플리케이션 메트릭인 Micrometer를 자동구성과 의존성 관리를제공한다.

6.1. Getting started

  • 스프링부트는 혼합된 MeterRegistry 를 자동구성하고, classpath 에서 알맞은 registry 도 추가 함
    • micrometer-registry-{system} 가 있으면 됨
  • 대부분의 registries 는 공통 기능을 공유한다
    • 예를 들어, Micrometer registry 구현체가 classpath에 있어도 disable 가능하다
    • Datadog disable
management.metrics.export.datadog.enabled=false
  • 스프링부트는 명시적으로 설정하지 않는 한, 자동구성된 registries 를 글로벌 스태틱 registry 인 Metrics 에 추가한다.
    • 명시적으로 등록 안할려면?
management.metrics.use-global-registry=false
  • meters 가 registry 에 등록되기 전에(공통 태그 등) 추가로 구성하고 싶다면 MeterRegistryCustomizer 빈을 등록가능하다.
@Bean
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
    return registry -> registry.config().commonTags("region", "us-east-1");
}
  • generic type 으로, 부분적인 registry 구현체를 커스터마이징 가능
@Bean
MeterRegistryCustomizer<GraphiteMeterRegistry> graphiteMetricsNamingConvention() {
    return registry -> registry.config().namingConvention(MY_CUSTOM_CONVENTION);
}
  • 컴포넌트의 MeterRegistry 에 주입 가능하고, metrics 을 등록할 수 있다
@Component
public class SampleBean {

    private final Counter counter;

    public SampleBean(MeterRegistry registry) {
        this.counter = registry.counter("received.messages");
    }

    public void handleMessage(String message) {
        this.counter.increment();
        // handle message implementation
    }

}
  • 스프링부트는 설정과 애너테이션으로 bulit-in instrumentation (i.e. MeterBinder implementations) 을 구성한다.

6.2. Supported monitoring systems

6.2.1. AppOptics

  • 기본적으로 AppOptics registry 는 api.appoptics.com/v1/measurements 로 메트릭을 주기적으로 push 한다.
    • API token 은 필수다
management.metrics.export.appoptics.api-token=YOUR_TOKEN

6.2.5. Elastic

  • 기본적으로 메트릭은 로컬머신에서 실행중인 Elastic 으로 export 된다.
  • 사용할 Elastic 서버는 다음과 같이 사용한다.
management.metrics.export.elastic.host=https://elastic.example.com:8086

6.2.13. Prometheus

  • Prometheus 는 개별 앱 인스턴스의 메트릭을 poll 할것으로 기대한다.
  • Spring Boot 는 /actuator/prometheus 액츄에이터 엔드포인트를 제공하고, Prometheus 가 scrape(긁어) 해갈수 있다

엔드포인트는 기본적으로 사용할 수 없기 때문에, expose 시켜야 한다

  • prometheus.ymlscrape_config 을 추가한 예제이다.
scrape_configs:
  - job_name: 'spring'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['HOST:PORT']
  • ephemeral(수명이 짧은) 혹은 배치 잡에서 Prometheus Pushgateway 를 통해 Prometheus 로 메트릭을 expose 할 수 있다.
  • Prometheus Pushgateway 사용하려면 디펜던시 추가 필요
<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_pushgateway</artifactId>
</dependency>
  • classpath에 위 디펜던시가 있다면 PrometheusPushGatewayManager 를 자동구성 함
    • management.metrics.export.prometheus.pushgateway 로도 설정 가능

6.2.15. Simple

  • Micrometer 는 다른 registry가 구성되어 있지 않다면, 간단한 in-memory 로 자동구성 한다. 이를 통해 어떤 메트릭이 수집되는지 확인 가능하다
  • 사용가능한 다른 backend 가 있다면 득시 disable 된다
  • 명시적인 비활성
management.metrics.export.simple.enabled=false

6.3. Supported Metrics

  • JVM metrics, report utilization of:
    • Various memory and buffer pools
    • Statistics related to garbage collection
      *Threads utilization
    • Number of classes loaded/unloaded
  • CPU metrics
  • File descriptor metrics
  • Kafka consumer metrics
  • Log4j2 metrics: record the number of events logged to Log4j2 at each level
  • Logback metrics: record the number of events logged to Logback at each level
  • Uptime metrics: report a gauge for uptime and a fixed gauge representing the application’s absolute start time
  • Tomcat metrics (server.tomcat.mbeanregistry.enabled must be set to true for all Tomcat metrics to be registered)
  • Spring Integration metrics

6.3.1. Spring MVC Metrics

  • 자동구성으로 Spring MVC 가 처리하는 요청을 계측가능하다
    • management.metrics.web.server.request.autotime.enabledtrue 이면 모든 요청을 계측. false 이면 @Timed 붙은 것만 계측
@RestController
@Timed 
public class MyController {

    @GetMapping("/api/people")
    @Timed(extraTags = { "region", "us-east-1" }) 
    @Timed(value = "all.people", longTask = true) 
    public List<Person> listPeople() { ... }

}
  • 컨트롤러로 들어오는 모든 요청의 timings 을 활성화

  • 개별적인 엔드포인트 활성화.

  • long task 일 경우 longTask = true 붙힘

    • Long task timers 는 별도의 메트릭 이름이 필요하고, short 태스크 타이머도 쌓일 수 있음
  • 기본적으로 메트릭 이름은 http.server.requests 로 생성 됨

    • management.metrics.web.server.request.metric-name 로 커스텀 가능
  • 기본적인 Spring MVC-related 메트릭 정보는 다음의 표처럼 tag 됨

Tag Description
exception Simple class name of any exception that was thrown while handling the request.
method Request’s method (for example, GET or POST)
outcome Request’s outcome based on the status code of the response. 1xx is INFORMATIONAL, 2xx is SUCCESS, 3xx is REDIRECTION, 4xx CLIENT_ERROR, and 5xx is SERVER_ERROR
status Response’s HTTP status code (for example, 200 or 500)
uri Request’s URI template prior to variable substitution, if possible (for example, /api/person/{id})
  • WebMvcTagsProvider 구현해서 커스터마이징 가능

6.3.2. Spring WebFlux Metrics

  • 자동구성으로 WebFlux 컨트롤러나 functional 핸들러를 통한 모든 요청을 계측 가능하다
  • 기본적으로 메트릭 이름은 http.server.requests 로 생성 됨
    • management.metrics.web.server.request.metric-name 로 커스텀 가능
  • 기본적인 WebFlux-related 메트릭 정보는 다음의 표처럼 tag 됨
Tag Description
exception Simple class name of any exception that was thrown while handling the request.
method Request’s method (for example, GET or POST)
outcome Request’s outcome based on the status code of the response. 1xx is INFORMATIONAL, 2xx is SUCCESS, 3xx is REDIRECTION, 4xx CLIENT_ERROR, and 5xx is SERVER_ERROR
status Response’s HTTP status code (for example, 200 or 500)
uri Request’s URI template prior to variable substitution, if possible (for example, /api/person/{id})
  • WebFluxTagsProvider 구현해서 커스터마이징 가능

6.3.3. Jersey Server Metrics

  • 생략

6.3.4. HTTP Client Metrics

  • Spring Boot Actuator 는 RestTemplateWebClient 의 계측도 관리한다
    • 이를 위해 자동구성된 빌더를 inject 하고 객체를 만들어야 한다
      • RestTemplateBuilder for RestTemplate
      • WebClient.Builder for WebClient
    • MetricsRestTemplateCustomizerMetricsWebClientCustomizer 로 수동으로 커스터마이징 가능
  • 기본적으로 메트릭 이름은 http.server.requests 로 생성 됨
    • management.metrics.web.server.request.metric-name 로 커스텀 가능
  • 기본적인 메트릭 정보는 다음의 표처럼 tag 됨
Tag Description
clientName Host portion of the URI
method Request’s method (for example, GET or POST)
outcome Request’s outcome based on the status code of the response. 1xx is INFORMATIONAL, 2xx is SUCCESS, 3xx is REDIRECTION, 4xx CLIENT_ERROR, and 5xx is SERVER_ERROR, UNKNOWN otherwise
status Response’s HTTP status code if available (for example, 200 or 500), or IO_ERROR in case of I/O issues, CLIENT_ERROR otherwise
uri Request’s URI template prior to variable substitution, if possible (for example, /api/person/{id})
  • 태그 커스터마이징을 하기 위해선 RestTemplateExchangeTagsProviderWebClientExchangeTagsProvider 를 구현면 됨
    • 또한 편리한 static functions 가 RestTemplateExchangeTagsWebClientExchangeTags 에 있음

6.3.5. Cache Metrics

  • 자동구성으로 startup 시 cache prefix 붙은 사용가능한 모든 Cache 를 계측 가능하다
  • 캐시 계측은 기본 메트릭 세트로 표준화 되었음
  • 추가적인 캐시 라이브리리들
    • Caffeine
    • EhCache 2
    • Hazelcast
    • Any compliant JCache (JSR-107) implementation
  • 메트릭은 태그는 CacheManager 에 있는 cacheName 으로 된다

오로지 startup 시에 이용가능한 캐시만 bound 된다. on-the-fly 혹은 startup 이후 프로그래밍적으로 만들려면, 명시적으로 등록해라. CacheMetricsRegistrar bean 은 프로세스를 보다 쉽게 해준다

6.3.6. DataSource Metrics

  • 자동구성으로 시 jdbc.connections prefix 붙은 사용가능한 모든 DataSource 를 계측 가능하다
  • Data source 계측으로 currently active, idle, maximum allowed, and minimum allowed connections in the pool 을 알 수 있다
  • 메트릭은 DataSource 의 bean 이름 기반으로 태그 된다

기본적으로 스프링부트가 제공하는 모든 data sources 의 메타데이터를 제공한다. 별도로 추가하려면 DataSourcePoolMetadataProvider bean 을 만들어라. DataSourcePoolMetadataProvidersConfiguration 에 예제 있음

  • Hikari-specific metrics 은 hikaricp prefix 로 expose 된다. 각 메트릭은 풀 이름으로 태그 된다. (spring.datasource.name 로 조절 가능)

6.3.7. Hibernate Metrics

  • 자동구성으로 이용가능한 Hibernate EntityManagerFactory 객체를 hibernate 란 이름으로 계측 된다
  • 메트릭은 EntityManagerFactory bean 이름으로 태그된다
  • 표준 JPA 설정을 enable 해야 한다. hibernate.generate_statistics
  • 다음 예제처럼 자동구성된 EntityManagerFactory 를 활성화 한다
spring.jpa.properties.hibernate.generate_statistics=true

6.3.8. RabbitMQ Metrics

  • 자동구성으로 이용가능한 모든 RabbitMQ 커넥션 팩토리를 rabbitmq 란 이름으로 계측가능하다

6.4. Registering custom metrics

  • 커스텀 메트릭을 등록하려면 MeterRegistry 를 컨포넌트로 주입하라
class Dictionary {

    private final List<String> words = new CopyOnWriteArrayList<>();

    Dictionary(MeterRegistry registry) {
        registry.gaugeCollectionSize("dictionary.size", Tags.empty(), this.words);
    }

    // …

}
  • 반복적으로 메트릭을 계측하려면 MeterBinder 구현체를 캡슐화 한다
    • 기본적으로 모든 MeterBinder beans 은 자동으로 Spring-managed MeterRegistry 에 바인드 된다

6.5. Customizing individual metrics

  • 특정 Meter 객체를 커스텀해야 한다면, io.micrometer.core.instrument.config.MeterFilter 객체를 이용해라
    • 기본적으로 모든 MeterFilter beans 은 자동으로 MeterRegistry.Config 마이크로미터에 적용된다
  • 예를들어 com.example 로 시작하는 모든 meter IDs 의 mytag.region 태그 이름을 mytag.area 로 바꾸려면 다음과 같이 해라
@Bean
public MeterFilter renameRegionTagMeterFilter() {
    return MeterFilter.renameTag("com.example", "mytag.region", "mytag.area");
}

6.5.1. Common tags

  • Common 태그는 일반적으로 운영 환경의 dimensional drill-down 에 사용된다. (host, instance, region, stack, etc.)
  • Common 태그는 모든 meters 에 적용되며 다음과 같이 구성 가능하다
management.metrics.tags.region=us-east-1
management.metrics.tags.stack=prod
  • 위 설정은 모든 meter로 regionstack 태그를 us-east-1prod 에 추가한다.

Graphite 를 사용할때에는 common 태그의 순서가 중요하다. 이 방법으로는 common 태그의 순서를 보장하지 못하므로, Graphite 사용자는 MeterFilter 를 정의해서 쓰는게 낫다

6.5.2. Per-meter properties

  • MeterFilter beans 이외에도 properties 를 사용해서 per-meter 제한된 커스텀이 가능하다
  • Per-meter 커스텀은 주어진 이름으로 시작하는 모든 meter IDs 에 적용된다
    • 예를 들어 다음은 example.remote 로 시작하는 ID 를 disable 한다
management.metrics.enable.example.remote=false

Table 1. Per-meter customizations

Property Description
management.metrics.enable Whether to deny meters from emitting any metrics.
management.metrics.distribution.percentiles-histogram Whether to publish a histogram suitable for computing aggregable (across dimension) percentile approximations.
management.metrics.distribution.minimum-expected-value, management.metrics.distribution.maximum-expected-value Publish less histogram buckets by clamping the range of expected values.
management.metrics.distribution.percentiles Publish percentile values computed in your application
management.metrics.distribution.sla Publish a cumulative histogram with buckets defined by your SLAs.

6.6. Metrics endpoint

  • Spring Boot 는 수집한 메트릭을 검사하는 metrics 엔드포엔트를 제공한다
    • 기본적으로 이용못하지만 expose 해야만 한다.
  • /actuator/metrics 에 가보면 이용가능한 meter 이름 목록이 있다
    • 특정 meter 에 대한 정보를 디릴 다운 가능하다.
    • e.g. /actuator/metrics/jvm.memory.max

여기에서 사용하는 이름은 코드와 일치해야 한다. Prometheus 에서는 jvm.memory.maxjvm_memory_max 로 나타내므로, 엔드포인트에서 meter 를 검사할때 jvm.memory.max 를 사용 해야 한다

  • 또한 tag=KEY:VALUE 쿼리 파라미터를 URL 끝에 추가할 수 있다.
    • e.g. /actuator/metrics/jvm.memory.max?tag=area:nonheap

reported 된 측정치는 미터 이름, 태그와 일치하는 모든 통계의 합(sum) 이다. 따라서 위 응답의 "Value" 는 "Code Cache", "Compressed Class Space", and "Metaspace" areas of the heap 의 합이다. 메타스페이스의 최대 크기를 알고 싶다면 tag=id:Metaspace 를 추가해라. i.e. /actuator/metrics/jvm.memory.max?tag=area:nonheap&tag=id:Metaspace

7. Auditing

  • Spring Security 가 실행되면 Spring Boot Actuator 는 이벤트를 publish 하는 유연한 audit 프레임워크를 갖는다.
    • by default, “authentication success”, “failure” and “access denied” exceptions
  • 이는 인증 실패를 기반으로 잠금 정책(lock-out policy) 구현하는데 유용하다
  • AuditEventRepository 로 구성하여 활성화 가능
  • Spring Boot 는 InMemoryAuditEventRepository 제공한다
    • InMemoryAuditEventRepository 는 기능이 제한적이라 개발 환경에서만 써라
    • 프로덕션 환경에서는 AuditEventRepository 를 직접 만들어라

7.1. Custom Auditing

  • publish 된 보안 이벤트를 커스텀 하기 위해 AbstractAuthenticationAuditListener AbstractAuthorizationAuditListener 구현해라
  • 자체적인 비지니스 이벤트 audit 사용도 가능하다
    • AuditEventRepository 빈 직접 주입
    • AuditApplicationEvent ApplicationEventPublisher 구현 (by implementing ApplicationEventPublisherAware)

8. HTTP Tracing

  • HttpTraceRepository 타입을 HTTP 추적(Tracing) 가능
  • 편의상 스프링부트가 InMemoryHttpTraceRepository 제공하는데 마지막 100개의 요청-응답을 추적가능하다
    • InMemoryHttpTraceRepository 는 개발환경에서만 쓰고, 프로덕션에서는 Zipkin, Spring Cloud Sleuth 추천한다
  • 혹은 HttpTraceRepository 를 직접 만들어라
  • httptrace 엔드포인트에서 HttpTraceRepository에 저장된 request-response exchanges 정보를 얻을 수 있다

8.1. Custom HTTP tracing

  • 각 추적을 include 하려면 management.trace.http.include 를 이용해라
  • 부가적인 커스텀을 하려면 HttpExchangeTracer 를 구현해라

9. Process Monitoring

  • 스프링부트에서 프로세스 모니터링을 위한 파일을 생성하는 두가지 클래스가 있음
    • ApplicationPidFileWriter 는 애플리케이션 PID 를 포함하는 파일 만듦 (기본적으로 application.pid 란 파일)
    • WebServerPortFileWriter 실행중인 웹서버 포트를 포함하는 파일을 만듦 (기본적으로 application.port 란 파일)

9.1. Extending Configuration

  • META-INF/spring.factories 파일에서 리스너 활성화 가능
org.springframework.context.ApplicationListener=\
org.springframework.boot.context.ApplicationPidFileWriter,\
org.springframework.boot.web.context.WebServerPortFileWriter

9.2. Programmatically

  • pringApplication.addListeners(…​)Writer 객체를 전달해서 리스너 주입 가능
    • 이 메소드를 사용하면 파일 이름과 path 커스텀 가능

10. Cloud Foundry Support

  • 생략