1. 개요
actuator는 스프링 부트 애플리케이션의 모니터링이나 메트릭 기능을 HTTP와 JMX의 엔드포인트를 통해 제공한다.
사용하는 방식은 spring-boot-starter-actuator
의존성을 추가하는 것이다.
Maven 프로젝트에서는 아래와 같이 추가할 수 있다.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
2. Endpoints
기술에 구애받지 않는 공통적인 enpoint
ID | Description |
---|---|
auditevents | 현재 애플리케이션의 audit event 정보를 노출한다. AuditEventRepositoryBean 이 필요하다. |
beans | 애플리케이션 내의 모든 스프링 빈의 목록을 표시한다. |
caches | 사용 가능한 캐쉬를 노출한다. |
conditions | configuration과 자동 구성 클래스, 매칭이 되지않은 이유에 대한 조건을 표시한다. |
configprops | 모든 @ConfigurationProperties 의 목록을 나타낸다. |
env | 스프링의 ConfigurableEnvironment 의 프로퍼티를 노출한다. |
flyway | 적용되어 있는 Flyway 데이터베이스 마이그레이션을 표시한다. 한 개 이상의 Flyway bean이 필요하다. |
health | 애플리케이션 health 정보를 표시한다. |
httpexchanges | HTTP exchange 정보를 나타낸다. (기본적으로 최근 100개의 request-response) |
info | 애플리케이션의 정보를 나타낸다. |
integrationgraph | Spring Integration 그래프를 나타낸다. spring-integration-core 의 의존성이 필요하다. |
loggers | 애플리케이션의 로거 구성을 나타내고 수정한다. |
liquibase | Liquibase 데이터베이스 마이그레이션을 나타낸다. 하나 이상의 Liquibase 빈이 필요하다. |
metrics | 애플리케이션의 metric 정보를 나타낸다. |
mappings | 모든 @RequestMapping path 정보를 나타낸다. |
quartz | Quartz 스케쥴러 잡 정보를 나타낸다. |
scheduledtasks | 애플리케이션의 스케쥴 작업을 나타낸다. |
sessions | 스프링 세션 저장소의 사용자 세션 조회 및 삭제를 할 수 있게 한다. Spring Session을 사용하는 서블릿 기반 웹 애플리케이션이 필요하다. |
shutdown | 애플리케이션을 gracefully shutdown을 하게 한다. jar 패키징을 사용할 때만 동작한다. 기본값: false |
startup | 애플리케이션 시작 시 수집되는 데이터를 표시한다. SpringApplication이 BufferingApplicationStartup으로 구성되어야 한다. |
threaddump | 쓰레드 덤프를 수행한다. |
웹 애플리케이션(Spring MVC, Spring WebFlux, Jersey)을 사용하면 다음 endpoint를 사용할 수 있다.
ID | Description |
---|---|
heapdump | 힙 덤프파일을 만든다. HotSpot JVM에서는 HPROF 파일 포맷이 생성이 되고 OpenJ9에서는 PHD 포맷이 생성이 된다. |
logfile | 로그 파일 내용을 리턴한다 (logging.file.name 혹은 logging.file.path 값이 설정되어 있는 경우) |
endpoint path 커스트마이징
/actuator 경로를 변경하려면
base-path에 변경할 경로를 입력하면 된다.
management:
endpoints:
web:
base-path: /manage
http://localhost:8080/actuator으로 접속되지 않고 http://localhost:8080/manage 로 접속이 가능하다.
endpoint의 경로를 변경하려면
path-mapping에 변경할 enpoint와 변경할 이름을 적으면 된다.
아래 예제는 beans
를 springbeans
로 변경한 것이다.
management:
endpoints:
web:
path-mapping:
beans: springbeans
http://localhost:8080/actuator/beans 대신 http://localhost:8080/actuator/springbeans로 접속이 된다.
포트 정보를 변경하려면
actuator를 다른 포트로 사용하려면 아래에 포트정보를 입력하면 된다.
management:
server:
port: 8081
http://localhost:8080/actuator 대신 http://localhost:8081/actuator으로 접속이 된다.
3. 주요 endpoint
beans
url
http://localhost:8080/actuator/beans
설명
BeanFactory의 모든 빈을 표시한다. 필터링 기능을 제공하지 않는다.
health
url
http://localhost:8080/actuator/health
설명
- 운영 중인 애플리케이션의 상태 체크를 위해 health 정보를 사용할 수 있다. 때로는 운영 중인 시스템이 다운되었을 때 알림용도로 사용되기도 한다.
- 의존성에
HealthIndicator
를 구현한 구현체가 있다면 동작을 한다.- db, diskspace, elasticsearch, hazelcast 등이 있다.
- RoutingDataSourceHealthContributor는 여러 DataSource의 헬스를 체크하는데 여러 개 중 하나의 DataSource만 문제가 발생하더라도 서비스 다운으로 표시한다.
Name | Description |
---|---|
never | 상세정보를 나타내지 않는다. |
when-authorized | 상세정보는 권한있는 사용자에게만 표시한다. 역할이 management.endpoint.health.roles 을 통해서 구성될 수 있다. |
always | 상세정보가 모든 사용자에게 표시된다. |
- 기본값은
never
이다. - 사용자는 하나 이상의 역할에 포함되어 있을 때 권한이 있다고 판단된다.
- 구성된 역할이 없다면 모든 인증된 사용자는 접근된다. (기본값)
- 역할은
management.endpoint.health.roles
속성을 통해 구성할 수 있다.
[never]
{
"status": "UP"
}
[always]
{
"status": "UP",
"components": {
"db": {
"status": "UP",
"details": {
"database": "H2",
"validationQuery": "isValid()"
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 494384795648,
"free": 258507841536,
"threshold": 10485760,
"exists": true
}
},
"ping": {
"status": "UP"
}
}
}
커스텀 HealthIndicator 생성
HealthIndicator를 구현한 스프링 빈을 등록하여 커스텀 HealthIndicator을 만들 수 있다.
@Component
public class CustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
int errorCode = check();
if (errorCode != 0) {
return Health.down().withDetail("Error Code", errorCode).build();
}
return Health.up().build();
}
private int check() {
return 0;
}
}
이렇게 구현하면 http://localhost:8080/actuator/health 응답값에 custom이 포함되는 것을 확인할 수 있다.
{
"status": "UP",
"components": {
"custom": {
"status": "UP"
},
...
}
conditions
url
http://localhost:8080/actuator/conditions
설명
스프링 부트의 자동구성과 개발자가 직접 구성한 빈의 평가된 조건에 대한 정보
- positiveMatches: 매칭된 조건의 클래스와 메소드
- negativeMatches: 매칭되지 않은 조건의 클래스와 메소드
{
"contexts" : {
"application" : {
"positiveMatches" : {
"EndpointAutoConfiguration#endpointOperationParameterMapper" : [ {
"condition" : "OnBeanCondition",
"message" : "@ConditionalOnMissingBean (types: org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; SearchStrategy: all) did not find any beans"
} ],
...
},
"negativeMatches" : {
"WebFluxEndpointManagementContextConfiguration" : {
"notMatched" : [ {
"condition" : "OnWebApplicationCondition",
"message" : "not a reactive web application"
} ],
"matched" : [ {
"condition" : "OnClassCondition",
"message" : "@ConditionalOnClass found required classes 'org.springframework.web.reactive.DispatcherHandler', 'org.springframework.http.server.reactive.HttpHandler'"
} ]
},
...
},
"unconditionalClasses" : [ "org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration", "org.springframework.boot.actuate.autoconfigure.endpoint.jackson.JacksonEndpointAutoConfiguration", "org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration" ]
}
}
}
configprops
url
http://localhost:8080/actuator/configprops
설명
configprops
endpoint는 @ConfigurationProperties
빈에 대한 정보를 제공한다.
{
"contexts" : {
"application" : {
"beans" : {
"management.endpoints.web.cors-org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties" : {
"prefix" : "management.endpoints.web.cors",
"properties" : {
"allowedOrigins" : [ ],
"maxAge" : "PT30M",
"exposedHeaders" : [ ],
"allowedOriginPatterns" : [ ],
"allowedHeaders" : [ ],
"allowedMethods" : [ ]
},
"inputs" : {
"allowedOrigins" : [ ],
"maxAge" : { },
"exposedHeaders" : [ ],
"allowedOriginPatterns" : [ ],
"allowedHeaders" : [ ],
"allowedMethods" : [ ]
}
},
...
}
}
}
}
prefix로 @ConfigurationProperties 빈 조회하기
특정 prefix를 가진 빈을 조회하려면, http://localhost:8080/actuator/configprops/{prefix}로 조회하면 된다.
예) http://localhost:8080/actuator/configprops/spring.transaction
env
url
http://localhost:8080/actuator/env
설명
애플리케이션의 전체 환경정보를 조회한다.
{
"activeProfiles" : [ ],
"propertySources" : [ {
"name" : "servletContextInitParams",
"properties" : { }
}, {
"name" : "systemProperties",
"properties" : {
"java.specification.version" : {
"value" : "17"
},
"java.class.path" : {
"value" : "/root/.gradle/caches/7.6.2/workerMain/gradle-worker.jar:.............."
},
"java.vm.vendor" : {
"value" : "BellSoft"
}
}
}, {
"name" : "systemEnvironment",
"properties" : {
"JAVA_HOME" : {
"value" : "/opt/openjdk",
"origin" : "System Environment Property \"JAVA_HOME\""
}
}
}, {
"name" : "Config resource 'class path resource [application.properties]' via location 'classpath:/'",
"properties" : {
"com.example.cache.max-size" : {
"value" : "1000",
"origin" : "class path resource [application.properties] - 1:29"
}
}
} ]
}
단일 속성 조회
단일 속성을 조회하려면 http://localhost:8080/actuator/env/{property.name} 으로 조회하면 된다.
예) http://localhost:8080/actuator/env/java.specification.version
caches
url
http://localhost:8080/actuator/caches
설명
애플리케이션의 캐시정보를 표시한다.
응답값
{
"cacheManagers" : {
"anotherCacheManager" : {
"caches" : {
"countries" : {
"target" : "java.util.concurrent.ConcurrentHashMap"
}
}
},
"cacheManager" : {
"caches" : {
"cities" : {
"target" : "java.util.concurrent.ConcurrentHashMap"
},
"countries" : {
"target" : "java.util.concurrent.ConcurrentHashMap"
}
}
}
}
}
캐쉬 이름으로 조회하기
캐쉬 이름으로 조회하기 위해서 /actuator/caches/{name}
으로 요청을 하면 된다.
예) http://localhost:8080/actuator/caches/cities
응답값
{
"target" : "java.util.concurrent.ConcurrentHashMap",
"name" : "cities",
"cacheManager" : "cacheManager"
}
모든 캐쉬 evict하기
$ curl 'http://localhost:8080/actuator/caches' -i -X DELETE
캐쉬 이름으로 evict하기
$ curl 'http://localhost:8080/actuator/caches/countries?cacheManager=anotherCacheManager' -i -X DELETE \
-H 'Content-Type: application/x-www-form-urlencoded'
info
url
http://localhost:8080/actuator/info
설명
자동 구성 InfoContributors
스프링에서 자동으로 구성해주는 InfoContributors
빈이다.
ID | Name | Description | Prerequisites |
---|---|---|---|
build | BuildInfoContributor | 빌드 정보 | A META-INF/build-info.properties resource. |
env | EnvironmentInfoContributor | info로 시작하는 이름의 Environment 의 속성을 노출 |
None. |
git | GitInfoContributor | git 정보를 노출 | A git.properties resource. |
java | JavaInfoContributor | Java Runtime 정보 노출 | None. |
os | OsInfoContributor | 운영 체제 정보 노출 | None. |
- management.info.<id>.enabled 프로퍼티 속성으로 활성화할 수 있다.
커스텀 애플리케이션 정보
application.yml에 info.*
로 설정함으로써 info 엔드포인트에 정보를 노출하게 할 수 있다.
info:
app:
name: rudaks-app
이렇게 설정하면 아래와 같이 info의 응답결과에 포함되는 것을 알 수 있다.
{
"app": {
"name": "rudaks-app",
...
}
하드코딩된 값을 사용하지 않고 build time에 info 정보를 포함할 수 있다.
info: app: encoding: "@project.build.sourceEncoding@" java: source: "@java.version@" target: "@java.version@"
Git Commit 정보
GitProperties
빈은 git.properties
파일이 클래스 패스 루트에 있다면 자동으로 구성이 된다.
git.properties를 자동생성하는 방법은 아래 플러그인을 추가하면 빌드 시
git.properties
를 생성한다.maven에서는 아래를 추가하면 된다.
<build> <plugins> <plugin> <groupId>io.github.git-commit-id</groupId> <artifactId>git-commit-id-maven-plugin</artifactId> </plugin> </plugins> </build>
- 기본적으로 git.branch, git.commit.id, git.commit.time을 노출한다.
management:
info:
git:
mode: "full" # simple/full
build 정보
클래스 패스에 META-INF/build-info.properties
파일이 있다면 표시한다.
maven에서 build정보를 생성하려면 아래와 같이 info-info goal을 실행하면 된다.
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>3.0.5</version> <executions> <execution> <goals> <goal>build-info</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
다시 실행해보면 아래와 같이 표시된다.
{
...
"build": {
"artifact": "spring-boot-actuator-sample",
"name": "spring-boot-actuator-sample",
"time": "2023-10-11T23:05:44.860Z",
"version": "0.0.1-SNAPSHOT",
"group": "com.example"
},
...
}
loggers
url
http://localhost:8080/actuator/loggers
설명
애플리케이션에 설정된 logger와 레벨 구성을 확인할 수 있다.
{
"levels" : [ "OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" ],
"loggers" : {
"ROOT" : {
"configuredLevel" : "INFO",
"effectiveLevel" : "INFO"
},
"com.example" : {
"configuredLevel" : "DEBUG",
"effectiveLevel" : "DEBUG"
}
},
"groups" : {
"test" : {
"configuredLevel" : "INFO",
"members" : [ "test.member1", "test.member2" ]
},
"web" : {
"members" : [ "org.springframework.core.codec", "org.springframework.http", "org.springframework.web", "org.springframework.boot.actuate.endpoint.web", "org.springframework.boot.web.servlet.ServletContextInitializerBeans" ]
},
"sql" : {
"members" : [ "org.springframework.jdbc.core", "org.hibernate.SQL", "org.jooq.tools.LoggerListener" ]
}
}
}
단일 logger 조회하기
단일 logger를 조회하기 위해서는 /actuator/loggers/{logger.name}
를 조회하면 된다.
예) http://localhost:8080/actuator/loggers/com.example
응답값
Path | Type | Description |
---|---|---|
configuredLevel | String | logger의 설정된 레벨이 있다면 표시한다. 없으면 null |
effectiveLevel | String | logger가 설정되어 있으면 그 값을 반환하고 없다면 상위수준으로 검색한 다음 적용된 레벨을 표시한다. |
로그 레벨 변경하기
logger의 레벨을 변경하기 위해 /actuator/loggers/{logger.name}
으로 POST
요청을 하면 된다.
$ curl 'http://localhost:8080/actuator/loggers/com.example' -i -X POST \
-H 'Content-Type: application/json' \
-d '{"configuredLevel":"debug"}'
요청값
Path | Type | Description |
---|---|---|
configuredLevel | String | logger의 레벨. 레벨을 초기화하라면 제외하면 된다. |
로그 레벨 초기화하기
$ curl 'http://localhost:8080/actuator/loggers/com.example' -i -X POST \
-H 'Content-Type: application/json' \
-d '{}'
logger의 레벨을 초기화하기 위해 /actuator/loggers/{logger.name}
으로 빈 값으로 POST
요청을 하면 된다.
httptrace
url
http://localhost:8080/actuator/httptrace
설명
HTTP 요청-응답에 대한 정보를 표시한다.
활성화하기 위해서 HttpTraceRepository
의 구현체를 빈으로 등록해줘야 한다. 여기서는 InMemoryHttpTraceRepository
를 사용한다.
@Bean
public HttpTraceRepository createTraceRepository() {
return new InMemoryHttpTraceRepository();
}
응답값
{
"exchanges" : [ {
"timestamp" : "2022-12-22T13:43:41Z",
"request" : {
"uri" : "https://api.example.com",
"method" : "GET",
"headers" : {
"Accept" : [ "application/json" ]
}
},
"response" : {
"status" : 200,
"headers" : {
"Content-Type" : [ "application/json" ]
}
},
"principal" : {
"name" : "alice"
},
"session" : {
"id" : "52f5e16e-b804-4d9b-a02a-c556b70a2deb"
},
"timeTaken" : "PT0.023S"
} ]
}
스프링 3.0에서는
HttpTraceRepository
의 이름이HttpExchangeRepository
으로 변경이 되었다.
호출하는 endpoint도/actuator/httptrace
에서/actuator/httpexchanges
으로 변경되었다.
scheduledtasks
url
http://localhost:8080/actuator/scheduledtasks
설명
애플리케이션의 스케쥴 작업에 대한 정보를 제공한다.
/actuator/scheduledtasks
으로 요청을 하면 아래와 같이 표시된다.
{
"cron": [
],
"fixedDelay": [
],
"fixedRate": [
{
"runnable": {
"target": "com.example.actuator.scheduled.ScheduleBean.fixedRateJob"
},
"initialDelay": 0,
"interval": 1000
}
],
"custom": [
]
}
mappings
url
http://localhost:8080/actuator/mappings
설명
애플리케이션의 request mapping에 대한 정보를 제공한다.
응답값
{
"contexts" : {
"application" : {
"mappings" : {
"dispatcherServlets" : {
"dispatcherServlet" : [ {
"handler" : "Actuator web endpoint 'mappings'",
"predicate" : "{GET [/actuator/mappings], produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}",
"details" : {
"handlerMethod" : {
"className" : "org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler",
"name" : "handle",
"descriptor" : "(Ljakarta/servlet/http/HttpServletRequest;Ljava/util/Map;)Ljava/lang/Object;"
},
"requestMappingConditions" : {
"consumes" : [ ],
"headers" : [ ],
"methods" : [ "GET" ],
"params" : [ ],
"patterns" : [ "/actuator/mappings" ],
"produces" : [ {
"mediaType" : "application/vnd.spring-boot.actuator.v3+json",
"negated" : false
}, {
"mediaType" : "application/vnd.spring-boot.actuator.v2+json",
"negated" : false
}, {
"mediaType" : "application/json",
"negated" : false
} ]
}
}
},
...
}
}
}
startup
url
http://localhost:8080/actuator/startup
설명
애플리케이션의 시작 과정 기록된 단계를 조회하기 위해 사용한다.
{
"springBootVersion" : "3.1.4",
"timeline" : {
"startTime" : "2023-09-21T10:29:31.057906113Z",
"events" : [ {
"endTime" : "2023-09-21T10:29:31.162405607Z",
"duration" : "PT0.000005249S",
"startTime" : "2023-09-21T10:29:31.162400358Z",
"startupStep" : {
"name" : "spring.beans.instantiate",
"id" : 3,
"tags" : [ {
"key" : "beanName",
"value" : "homeController"
} ],
"parentId" : 2
}
}, {
"endTime" : "2023-09-21T10:29:31.162418344Z",
"duration" : "PT0.000027345S",
"startTime" : "2023-09-21T10:29:31.162390999Z",
"startupStep" : {
"name" : "spring.boot.application.starting",
"id" : 2,
"tags" : [ {
"key" : "mainApplicationClass",
"value" : "com.example.startup.StartupApplication"
} ]
}
} ]
}
}
startup을 사용하기 위해서 SpringBootApplication을 BufferingApplicationStartup으로 변경해야 한다.
public static void main(String[] args) { // SpringApplication.run(ActuatorApplication.class, args); SpringApplication app = new SpringApplication(ActuatorApplication.class); app.setApplicationStartup(new BufferingApplicationStartup(2048)); app.run(args); }
참고
https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html
https://docs.spring.io/spring-boot/docs/current/actuator-api/htmlsingle/
http://forward.nhnent.com/hands-on-labs/java.spring-boot-actuator/04-endpoint.html