일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- redis
- 요리
- java
- Design Patterns
- AWS
- tool
- Spring
- Spring Boot
- linux
- Git
- db
- laravel
- Oracle
- it
- springboot
- IntelliJ
- devops
- 맛집
- jenkins
- Spring Batch
- php
- Web Server
- Gradle
- javascript
- elasticsearch
- MySQL
- ReactJS
- ubuntu
- JVM
- jsp
Archives
- Today
- Total
아무거나
[Spring Actuator] Example 1편 - Custom Endpoint 생성 본문
반응형
소스코드는: https://github.com/bkjeon1614/java-example-code/tree/develop/bkjeon-mybatis-codebase 를 참고하시면 됩니다.
개념
- Actuator 은 상태정보를 Hateoas(헤이티오스) 를 사용하여 표시한다. (ex: /actuator)
- Hateoas(헤이티오스) 란
- 서버가 클라이언트에게 하이퍼 미디어를 통해 정보를 동적으로 제공 (API 에서 리소스에 대해 어떠한 행동을 할 수 있는지 URL 을 전달하여 클라이언트가 참고하고 사용할 수 있도록 하며 해당 리소스의 상태에 따라 링크 정보가 바뀌며 동적으로 리소스를 구성)
- Hateoas(헤이티오스) 란
- Actuator Lib (의존성 라이브러리)
- core lib 는
micrometer
를 사용하고 있다. (중요) - micrometer 를 spring boot 에서 bean 을 등록하기 위한 코드들은
spring-boot-actuator-autoconfigure
를 확인
- core lib 는
의존성 추가
[build.gradle]
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}
설정
Custom Endpoint 생성
- actuator 접근 시 기본 제공되는 endpoints 말고 추가하는 방법
- 공식페이지에 Endpoints 쪽을 보면 종류를 확인할 수 있다. 참고
- 필요한 종류
- beans: 등록된 bean 목록 제공
- caches: cache 사용중이라면 cache 관련 정보 제공
- conditions: spring auto configuration 에 의해 bean 으로 등록된 것과 그렇지 않은 것의 상세 이유를 제공
- health: application 구동중인지, 연동되는 다른 서비스가 구동중인지에 대한 여부 제공
- info: application 의 대략적인 정보
- metrics: cpu, mem, thread count 등 모니터링용 메트릭 정보
- logger: 현재 로거의 설정 확인 및 실시간 로그 레벨 변경 제공
- quartz: quartz 라는 스케쥴링 관련 라이브러리를 사용하고 있다면 해당 정보를 상세히 제공
- 설정방법 (설정한다고 무조건 되는것은 아니다 공식문서를 참고해보면 특정 필요 조건들이 존재하는 경우도 있다.)
- Endpoint 활성화 설정
[application.yml]management: endpoint: health: enabled: true beans: enabled: false caches: enabled: true heapdump: enabled: true
- 노출설정
[application.yml]management: endpoint: health: enabled: true beans: enabled: false caches: enabled: true heapdump: enabled: true endpoints: web: exposure: include: # 다 할꺼면 "*" 로 하면 된다. 또한 exclude 가 우선순위가 높다. (단, 아무데서나 접근이 불가능하게 Security 를 설정하자) - caches - heapdump - health exclude: - beans
- Endpoint 활성화 설정
- 설정 후 /actuator 로 접속하면 각 endpoint 들을 확인할 수 있다.
- Endpoint Cache 적용
[application.yml]management: endpoint: health: enabled: true cache: time-to-live: 1d # 1m: 1분, 1d: 1일 등 직관적으로 정할 수 있다. beans: enabled: false caches: enabled: true heapdump: enabled: true ...
- CORS 허용
[application.yml]management: endpoint: web: cors: allowed-origins: http://www.test.com, http://test2.com allowed-methods: GET
- Custom Endpoint 생성
- 공식가이드
- https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html#actuator.endpoints.implementing-custom
- application 에서 참조하는 라이브러리 이름과 버전 정보를 응답으로 내보내는 Custom Endpoint 를 생성하는 예제
- 샘플코드
[ApplicationLibInfoEndpoint.java]
[LibarayInfo.java]import com.example.bkjeon.dto.actuator.LibarayInfo; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import java.util.Arrays; import java.util.List; // @Endpoint(id = "applicationLibInfo") // @JmxEndpoint(id = "applicationLibInfo") @WebEndpoint(id = "applicationLibInfo") // web 만 열어준다. public class ApplicationLibInfoEndpoint { @ReadOperation public List<LibarayInfo> getLibraryInfo() { LibarayInfo libarayInfo = LibarayInfo.builder() .name("bkjeon") .version("1.0.0") .build(); LibarayInfo libarayInfo2 = LibarayInfo.builder() .name("bkjeon2") .version("2.0.0") .build(); return Arrays.asList(libarayInfo, libarayInfo2); } }
[ApplicationLibInfoEndpoint.java]import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @Getter @Builder @AllArgsConstructor @NoArgsConstructor public class LibarayInfo { private String name; private String version; }
[application.yml]// ApplicationLibInfoEndpoint 자체적으로는 bean 등록을 하지 않으므로 @Component 추가 또는 bean 등록을 해준다. import com.example.bkjeon.base.services.api.v1.actuator.ApplicationLibInfoEndpoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ApplicationLibInfoEndpointConfig { @Bean public ApplicationLibInfoEndpoint applicationLibInfoEndpoint() { return new ApplicationLibInfoEndpoint(); } }
... endpoints: web: exposure: include: health, heapdump, info, metrics, prometheus, retries, applicationLibInfo # applicationLibInfo 를 추가해준다. ...
- 생성 후 /actuator 로 접속하면 _links 하위에 applicationLibInfo 관련 endpoint 가 추가된걸 확인할 수 있다. 추가된 href 로 접속하면 결과가 표시된다.
[ { "name": "bkjeon", "version": "1.0.0" }, { "name": "bkjeon2", "version": "2.0.0" } ]
- 샘플코드
- 상기 생성된 Endpoint 에
Querystring
을 받아서 조건에 맞게 표시하는 방법- 코드
[ApplicationLibInfoEndpoint.java]import com.example.bkjeon.dto.actuator.LibarayInfo; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.lang.Nullable; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @Endpoint(id = "applicationLibInfo") public class ApplicationLibInfoEndpoint { @ReadOperation public List<LibarayInfo> getLibraryInfo(@Nullable String name, boolean includeVersion) { LibarayInfo libarayInfo = LibarayInfo.builder() .name("bkjeon") .version("1.0.0") .build(); LibarayInfo libarayInfo2 = LibarayInfo.builder() .name("bkjeon2") .version("2.0.0") .build(); List<LibarayInfo> libarayInfoList = Arrays.asList(libarayInfo, libarayInfo2); if (name != null) { libarayInfoList = libarayInfoList.stream() .filter(lib -> lib.getName().equals(name)) .collect(Collectors.toList()); } if (!includeVersion) { libarayInfoList = libarayInfoList.stream() .map(lib -> LibarayInfo.builder().name(lib.getName()).build()) .collect(Collectors.toList()); } return libarayInfoList; } }
- /actuator/applicationLibInfo?includeVersion=true&name=bkjeon 와 같이 파라미터를 전송하면 확인할 수 있다.
- 코드
http body
정보를 파라미터로 전달하는 방법- 샘플코드
[ApplicationLibInfoEndpoint.java]@Slf4j @Endpoint(id = "applicationLibInfo") public class ApplicationLibInfoEndpoint { // 여기서는 복합객체를 갖고있는 @RequestBody 와 같은 방식을 지원하지 않아서 하기와 같은 방법으로 진행 @WriteOperation public void changeSomething(String name, boolean enableSomething) { log.info("name: {}, enableSomething: {} ", name, enableSomething); } ... }
- 파라미터값들을 json 으로 전송하여 확인하자.
- 샘플코드
path parameter
정보를 전달하는 방법- 샘플코드
[ApplicationLibInfoEndpoint.java]... // 단일 path 값 @ReadOperation public String getPathParameter(@Selector String path) { return "path: " + path; } // 여러개의 path 값 @ReadOperation public String getPathParameters(@Selector(match = Selector.Match.ALL_REMAINING) String[] paths) { return "pathList: " + Arrays.asList(paths); }
- 단일: /actuator/applicationLibInfo/1234 또는 여러개: /actuator/applicationLibInfo/1234/567 로 접근하여 path 에 찍히는 결과값을 확인할 수 있다.
- 샘플코드
- 공식가이드
생각해보면 결국 RestController 을 만들면 되는거지 않나? 라고 생각하게 되는데 그렇게 된다면 prometheus 와 같은 actuator 와 호환이 되는 여러 라이브러리와 연동이 될 수 없다. 즉, actuator 가 일종의 인터페이스 역할이므로 타 라이브러리와의 연동을 위해 actuator 를 이용하는걸 권장한다.
참고
- https://semtul79.tistory.com/
- https://docs.spring.io/
- https://www.inflearn.com/course/spring-boot-actuator-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0/dashboard
반응형
'Java & Kotlin > Spring' 카테고리의 다른 글
[Spring Actuator] Example 4편 - Metrics Tags (0) | 2023.11.27 |
---|---|
[Spring Actuator] Example 3편 - Counter (0) | 2023.11.26 |
[Redis 시리즈 2편] Lettuce 를 사용한 Read / Write 분리 (0) | 2023.08.22 |
[Redis 시리즈 1편] Spring Boot 에 Redis 라이브러리인 Lettuce 적용 (1) | 2023.07.31 |
Spring Boot Ehcache3 Multiple CacheManager 적용 (0) | 2023.07.28 |
Comments