일단 씻고 나가자

[스프링 부트 핵심 가이드] 11. 액추에이터 활용하기 본문

Backend/Spring

[스프링 부트 핵심 가이드] 11. 액추에이터 활용하기

일단 씻고 나가자 2023. 6. 27. 16:39

(본 포스팅은 해당 도서의 정리 및 개인 공부의 목적 포스팅임을 밝힙니다.)
장정우, 『스프링 부트 핵심 가이드 : 스프링 부트를 활용한 애플리케이션 개발 실무』, 위키북스, 2022

 

 

 

11. 액추에이터 활용하기

애플리케이션 개발의 단계를 지나 운영 단계에 접어들면 애플리케이션의 정상 작동에 대한 모니터링이 필요하다.

스프링 부트 액추에이터는 HTTP 엔드포인트나 JMX(Java Management Extensions)를 활용하여 애플리케이션을 모니터링하고 관리할 수 있는 기능을 제공하므로, 이번 장에선 해당 기능에 대해 학습과 실습을 진행한다.

 

 

 

11.1 프로젝트 생성 및 액추에이터 종속성 추가

이번 장의 실습을 위해 새로운 프로젝트를 생성한다.

start.spring.io에 접속하여 다음과 같이 설정하고 [GENERATE], 압축을 풀어 IDE로 open 한다.

 

 

이후 이전 장들에서 활용했던 swagger 관련 의존성과 config 패키지 내의 SwaggerConfiguration 클래스를 추가하고,

액추에이터 기능 관련 종속성을 다음과 같이 추가한다.

 

swagger 관련 클래스 추가

 

swagger 관련 springfox 의존성 및 액추에이터 관련 의존성 추가

추가적으로 pom.xml 파일의 최상단 부에서 <parent> org.springframework.boot 의 version을 2.5.6으로 조정해준다.

이는 swagger 버전과의 충돌을 막기 위함이다.

 

 

 

11.2 엔드포인트

액추에이터의 엔드포인트는 애플리케이션의 모니터링을 사용하는 경로이다.

(이때 엔드포인트란 API가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL)

스프링 부트에는 여러 내장 엔드포인트가 있으며, 커스텀 엔드포인트의 설정도 가능하다.

 

액추에이터를 활성화하면 기본적으로 URL 경로 뒤에 "/actuator"를 추가하고 뒤에 추가 경로를 적어 상세 내역에 접근할 수 있으며, /actuator가 아닌 다른 명칭의 경로 지정 방법은 application.properties 파일에서 다음과 같이 코드를 추가하는 것으로 지정할 수 있다. (my-actuator 부에 원하는 명칭으로 작성하면 됨)

management.endpoints.web.base-path=/my-actuator

 

 

자주 활용되는 액추에이터 엔드포인트는 다음과 같다.

 

  auditevents   호출된 Audit 이벤트 정보를 표시 (AuditEventRepository 빈 필요)
  beans   애플리케이션의 모든 스프링 빈 리스트 표시
  caches   사용 가능 캐시 표시
  conditions   자동 구성 조건 내역 생성
  configprops   @ConfigurationProperties의 속성 리스트 표시
  env   애플리케이션의 사용 가능한 환경 속성 표시
  health   애플리케이션의 상태 정보 표시
  httptrace   최근 100건의 요청 기록 표시 (HttpTraceRepository 빈 필요)
  info   애플리케이션의 정보 표시
  intergrationgraph   스프링 통합 그래프 표시 (spring-integration-core 모듈 의존성 추가 필요)
  loggers   애플리케이션의 로거 구성 표시 및 수정
  metrics   애플리케이션의 매트릭 정보 표시
  mappings   @RequestMapping의 모든 매핑 정보 표시
  quartz   Quartz 스케줄러 작업에 대한 정보 표시
  scheduledtasks   애플리케이션의 예약된 작업 표시
  sessions   스프링 세션 저장소에서 사용자의 세션 검색 및 삭제
  (스프링 세션을 사용하는 서블릿 기반 웹 애플리케이션 필요)
  shutdown   애플리케이션을 정상적으로 종료 가능 (기본값은 비활성화 상태)
  startup   애플리케이션 시작 시 수집된 시작 단계 데이터 표시
  (BufferingApplicationStartup으로 구성된 스프링 애플리케이션 필요)
  threaddump   스레드 덤프 수행

 

Spring MVC, Spring WebFlux, Jersey를 사용할 시 다음과 같은 엔드포인트를 추가로 사용할 수 있다.

 

  heapdump   힙 덤프 파일 반환
  (HotSpot VM 상에서 hprof 포맷 파일이 반환되며, OpenJ9 JVM 상에서 PHD 파일 반환)
  jolokia   Jolokia가 클래스패스에 있을 때 HTTP를 통해 JMX 빈을 표시
  (jolokia-core 모듈 의존성 추가 필요 / WebFlux에서 사용 불가)
  logfile   logging.file.name 또는 logging.file.path 속성이 설정돼 있는 경우 로그 파일 내용 반환
  Prometheus   Promtheus 서버에서 스크랩할 수 있는 형식으로 메트릭 표시
  (micrometer-registry-prometheus 묘듈 의존성 추가 필요)

 

엔드포인트를 활성화하면 해당 기능을 이용할 수 있고, 비활성화하면 애플리케이션 컨텍스트에서 완전히 제거된다.

활성화 여부는 application.properties에서 설정할 수 있으며,
다음과 같이 "management.endpoint.특정 기능.enabled" 속성을 true 혹은 false로 설정하는 것으로 결정할 수 있다.

management.endpoint.shutdown.enabled=true

 

유사한 설정으로, 액츄에이터의 특정 환경/특정 기능의 노출 여부만을 설정하는 것도 가능하다.

management.endpoints.web.exposure.include=*

management.endpoints.jmx.exposure.include=*
management.endpoints.jmx.exposure.exclude=threaddump, heapdump

해당 코드에 대한 설명은 web 환경에선 엔드포인트를 전체적으로 노출하며, jmx 환경에선 엔포인트를 전체적으로 노출하되 threaddump, heapdump 기능은 제외하겠다는 의미이다. 이는 노출의 여부만이므로 애플리케이션 컨텍스트에서 완전히 제거하는 enabled 설정과는 차이가 있다.

 

애플리케이션에 대한 액츄에이터 엔드포인트는 민감한 정보를 가지고 있으므로, 노출 설정을 신중히 고려하여야 한다.

다음은 노출 설정에 대한 환경별, 기능별 기본값이다.

 

ID JMX WEB
auditevents O X
beans O X
caches O X
conditions O X
configprops O X
env O X
flyway O X
health O O
heapdump 해당 없음 X
httptrace O X
info O X
integrationgraph O X
jolokia 해당 없음 X
logfile 해당 없음 X
loggers O X
liquibase O X
metrics O X
mappings O X
Prometheus 해당 없음  
quartz O X
scheduledtasks O X
sessions O X
shutdown O X
startup O X
threaddump O X

 

 

 

11.3 액추에이터 기능 살펴보기

액추에이터 활성화 및 노출 지점 설정을 마치면 애플리케이션에서 해당 기능의 활용이 가능해진다.

모든 기능에 대해 살펴보기 위해서는 별도의 의존성 및 설정이 추가되어야 하므로, 쉬운 실습을 위해 별도의 추가 없이 기본적인 설정으로 볼 수 있는 기능 위주로 실습을 진행한다.

 

 

11.3.1 애플리케이션 기본 정보(/info)

액추에이터의 /info 엔드포인트로 실행 중인 애플리케이션의 정보를 볼 수 있다.

(http://localhost:8080/actuator/info)

 

제공하는 정보의 범위로는 애플리케이션에서 몇 가지 방법을 거쳐 제공할 수도 있지만,

가장 쉬운 방법은 application.properties 파일에 "info."로 시작하는 속성 값들을 정의하는 것이다.

 

다음과 같이 application.properties 파일을 작성한다.

management.endpoints.web.exposure.include=*

info.organization.name=wikibooks
info.contact.email=spring@boot.com
info.contact.phoneNumber=010-0000-0000

 

이후 /info 엔드포인에 접속하면 다음과 같이 설정한 속성을 표기하는 화면이 나온다.

 

 

이를 확장 프로그램인 JSON Formatter로 보기 쉽게 출력한다면 다음과 같다.

 

 

 

11.3.2 애플리케이션 상태(/health)

/health 엔드포인트는 애플리케이션의 상태를 보여준다.

(http://localhost:8080/actuator/health)

 

별도의 설정 없이 이전의 실습 상태에서 /health 엔드포인트에 접속하면 다음과 같은 화면을 출력한다.

 

 

status 속성은 UP, DOWN, UNKNOWN, OUT_OF_SERVICE 네 가지로 구분되며,

이는 흔히 네트워크의 L4(Loadbalancing) 레벨에서 애플리케이션의 상태를 확인하기 위해 사용된다.

 

상세 상태의 확인을 위해 application.properties에 다음과 같이 추가 후 다시 확인해보자.

management.endpoint.health.show-details=always

 

이때 show-details는 never(기본값, 세부 사항은 표기 안 함), when-authorized(승인된 사용자에게만 세부 상태 표시. management.endpoint.health.roles 속성으로 권한 설정), always(모든 사용자에게 세부 상태 표시) 세 가지로 구분된다. 

 

설정 이후 다시 /health 엔드포인트에 접속한 화면은 다음과 같다.

 

만약 데이터베이스 연동이 되어 있는 애플리케이션이라면 인프라 관련 상태까지 출력해주며,

모든 "status" 정보가 "UP"이어야 정상적인 HTTP 상태 코드와 함께 애플리케이션의 상태도 UP으로 표기된다.

 

 

11.3.3 빈 정보 확인(/beans)

/bean 엔드포인트는 스프링 컨테이너에 등록된 모든 스프링 빈의 전체 목록을 보여준다.

(http://localhost:8080/actuator/beans)

 

 

 

11.3.4 스프링 부트의 자동설정 내역 확인(/conditions)

/conditions 엔드포인트는 스프링 부트의 자동설정(AutoConfiguration) 조건 내역을 보여준다.

(http://localhost:8080/actuator/conditions)

 

출력 속성은 크게 positiveMatches, negativeMatches로 나뉘는데,

자동설정의 @Conditional에 따라 평가된 내용을 표시한다.

 

 

11.3.5 스프링 환경변수 정보(/env)

/env 엔드포인트는 스프링 부트의 환경변수 정보를 보여준다.

(http://localhost:8080/actuator/env)

 

기본적으로 application.properties 파일의 변수들이 표기되며, OS, JVM의 환경변수도 포함된다.

일부 내용의 포함된 민감한 정보를 가리기 위해선 management.endpoint.env.keys-to-sanitize 속성을 사용하는데,

해당 속성은 단순 문자열이나 정규식으로 설정한다.

 

 

11.3.6 로깅 레벨 확인(/loggers)

/loggers 엔드포인트는 애플리케이션의 로깅 레벨 수준을 보여준다.

(http://localhost:8080/actuator/loggers)

 

GET, POST 형식마다 호출 시 각각 로깅 레벨의 변경이 가능하다.

 

 

 

11.4 액추에이터에 커스텀 기능 만들기

앞선 액추에이터가 기본적으로 제공하는 엔드포인트 외에, 개발자의 요구사항에 맞춘 커스텀 기능 설정도 가능하다.

커스텀은 기존 기능에 내용을 추가하는 방법과, 새로운 엔드포인트를 개발하는 방식이 있다.

 

 

11.4.1 정보 제공 인터페이스의 구현체 생성

액추에이터 커스터마이징의 가장 기본적인 방법은 application.properties 파일 내에 내용을 추가하는 것이지만, 이 방법은 많은 내용을 담을 때의 관리 측면에서 좋지 않다.

따라서 일반적으로 액추에이터에서 제공하는 InfoContributor 인터페이스를 구현하고 public void contribute(Builder builder) 메서드를 오버라이드하는 클래스를 만듦으로써, /info 엔드포인트에서 보여줄 내용을 담는 방법을 선택한다.

 

해당 방법으로 커스텀 액추이에터를 만드는 실습을 진행해보자. 다음과 같이 config 패키지 내에 actuator 패키지를 만들고 CustomInfoContributor 클래스를 작성한다.

 

파라미터의 Builder는 액추에이터 패키지의 Info 클래스 내부에서 정의된 클래스로, Info 엔드포인트에서 보여줄 내용을 담는 역할을 수행한다. 즉, Builder에 내용을 포함하면 엔드포인트 출력 결과에 반영하게 된다.

 

이후 서버를 재실행하고 /info 엔드포인트를 실행한 결과 화면은 다음과 같다.

 

이전에 application.properties에 정의한 내용과 함께 추가된 내용이 잘 출력되는 모습이다.

 

 

11.4.2 커스텀 엔드포인트 생성

커스텀 엔드포인트는 기존의 엔드포인트 외에 새로운 경로의 엔드포인트를 만드는 방법이다.

 

커스텀 엔드포인트 실습을 위해 config.actuator 패키지 내에 NoteEndpoint 클래스를 다음과 같이 작성한다.

 

기본적으로 커스텀 엔드포인트는 @Endpoint 어노테이션을 활용해 빈에 추가하며, 내부 속성인 id를 통해 url 경로를 정의하고 enableByDefault 속성으로 기본 활성화 여부(정의하지 않을 시 기본 값 true)를 정의할 수 있다.

해당 실습 코드는 JMX, HTTP 모두에서 노출시킬 수 있는 설정이며 만약 JMX 혹은 HTTP에서만 사용하는 것으로 제한하려면 @Endpoint를 @JmxEndpoint, @WebEndpoint 어노테이션으로 바꾸어 활용한다.

 

내부의 @Read/Write/DeleteOperation 어노테이션들은 동작 메서드를 정의하는 어노테이션들이다.

각각 Read는 GET, Write는 POST, Delete는 DELETE의 프로토콜 기능을 담당한다.

 

현재 엔드포인트에는 아무 정보를 넣지 않았기 때문에 서버를 실행하고 Talented API Tester에서 POST를 통해 정보를 먼저 넣어주어야 한다. (Postman 등의 도구를 활용해도 무방하다) 우선 다음과 같이 [BODY]를 작성 후 [Send] 한다.

 

 

그럼 200의 status code와 함께 데이터가 무사히 저장됐음을 볼 수 있으며,

이후 /note 엔드포인트에 접속하면 다음과 같이 정보가 잘 저장됐음을 확인할 수 있다.

(http://localhost:8080/actuator/note)

 

 

추가로 @DeleteOperation을 통해 구현한 데이터 삭제 기능도 실습해보자.

Talented API Tester에서 다음과 같이 [METHOD] 부를 [DELETE]로 설정하고, [QUERY PARAMETERS]에 key(description)를 입력하여 DELETE 요청을 보내본다. 삭제가 잘 진행됐다면 200 status code를 반환할 것이다.

 

 

이후 /note 엔드포인트에 다시 접속해보면 이전에 저장했던 데이터가 삭제되어 빈 데이터를 출력하는 것을 볼 수 있다.

 

 

이렇게 커스텀 엔드포인트의 활용은 코드를 통한 확장성 있는 개발을 가능하게 해준다.