흰 스타렉스에서 내가 내리지

프로덕션 준비 - 액츄에이터 (actuator) 본문

Spring

프로덕션 준비 - 액츄에이터 (actuator)

주씨. 2023. 12. 17. 00:51
728x90

- 지표(metric), 추적(trace), 감사(auditing), 모니터링

 

스프링부트가 제공하는 액추에이터는 위 프로덕션 준비 기능을 매우 편리하게 사용할 수 있는 다양한 편의 기능을 제공함. 

프로메테우스, 그라파나 같은 최근 유행하는 모니터링 시스템과 매우 쉽게 연동할 수 있는 기능 제공

implementation 'org.springframework.boot:spring-boot-starter-actuator'

 

http://localhost:8080/actuator  경로를 통해 기능을 제공한다. 

/actuator/health 경로에 접속하면 health 결과를 제공한다. 

 

액츄에이터가 제공하는 수많은 기능을 웹 환경에서 보이도록 노출하려면,

* 액츄에이터 기능을 웹에 노출

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

 

액츄에이터가 제공하는 수 많은 기능을 확인할 수 있다. 

액츄에이터가 제공하는 기능 하나하나를 엔드포인트라 한다.

health 는 헬스 정보를, beans 는 스프링 컨테이너에 등록된 빈을 보여준다. 

 

각각의 엔트포인트는 /actuator/{엔드포인트명} 과 같은 형식으로 접근할 수 있다. 

 

 


# 엔드포인트 설정

엔드포인트를 사용하려면 다음 2가지 과정이 모두 필요

1. 엔드포인트 활성화

     : 해당 기능 자제를 on/off 할지 선택

2. 엔드포인트 노출

     : 활성화된 엔드포인트를 HTTP에 노출할지 아니면 JMX에 노출할지

 

엔드포인트는 대부분 기본으로 활성화 되어 있고, 노출은 되어있지 않다.

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

"*" 옵션은 모든 엔드포인트를 웹에 노출하는 것이다. shutdown 엔드포인트는 기본으로 활성화되지 않기 때문에 노출도 되지 않는다. 

 

엔트포인트 활성화 + 엔드포인트 노출이 둘 다 적용되어야 사용할 수 있다.

 

 

# 엔드포인트 활성화

management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: "*"

 

특정 엔드포인트를 활성화 하려면 management.endpoint.{엔드포인트명}.enabled=true 를 적용하면 된다. 

이제 HTTP POST 로 http://localhost:8080/actuator/shutdown 를 호출하면 서버가 종료된다. 

 

 

# 엔드포인트 노출

management:
  endpoints:
    web:
      exposure:
        include: "health,info"

- web에 health, info 를 노출한다.

management:
  endpoints:
    web:
      exposure:
        include: "*"
        exclude: "env,beans"

- web에 모든 엔드포인트를 노출하지만,  {env, beans} 는 제외한다. 

 

 

# 헬스 정보  :: health

- 헬스 정보를 사용하면 애플리케이션에 문제가 발생했을 때 문제를 빠르게 인지할 수 있다. 

- 헬스 정보는 단순히 애플리케이션이 요청에 응답을 할 수 있는지 판단하는 것을 넘어서 애플리케이션이 사용하는 DB가 응답하는지, 디스크 사용량에는 문제가 없는지 같은 다양한 정보들을 포함해서 만들어진다. 

 

management:
  endpoint:
    health:
      show-details: always
  endpoints:
    web:
      exposure:
        include: "*"

 

before / after

 

 

위처럼 너무 자세하게 노출되는 것이 부담스러우면 아래와 같이.

management:
  endpoint:
    health:
      show-components: always
  endpoints:
    web:
      exposure:
        include: "*"

 

각 헬스 컴포넌트의 상태정보만 간략하게 노출된다. 

헬스 컴포넌트 중에 하나라도 DOWN 이 있으면 전체 상태는 DOWN이 된다.

 

 

 

# 애플리케이션 정보 :: info

info가 제공하는 기능들

- java : 자바 런타임 정보 

- os : os 정보 

- env : Environment에서 info. 로 시작하는 정보

- build : 빌드 정보, META-INF/build-info.properties 파일이 필요하다.

- git : git 정보, git.properties 파일이 필요하다.

 

env, java, os는 기본으로 비활성화 되어 있다

 

management:
  info:
    java:
      enabled: true
    os:
      enabled: true
    env:
      enabled: true

  endpoint:
    health:
      show-components: always
  endpoints:
    web:
      exposure:
        include: "*"

 

주의! : management.endpoint 하위가 아니다. management 바로 다음에 info가 나온다. 

 

 

* git

- 빌드 시점에 사용한 git 정보도 노출할 수 있다. 

- git 정보를 노출하려면 git.properties 파일이 필요하다.

plugins { ...
        id "com.gorylenko.gradle-git-properties" version "2.4.1" //git info
    }

 

git 커밋을 하고 빌드를 해보면, build 폴더 안에 resources/main/git.properties 파일을 확인할 수 있다. 

 

- info 엔드포인트에도 git에 대한 정보가 나타난다.

- 애플리케이션을 배포할 때 가끔 기대와 전혀 다르게 동작할 때가 있는데, 확인해보면 다른 커밋이나 다른 브랜치의 내용이 배포된 경우가 종종 있다. 

 

 

 

# Log

logging:
  level:
    hello.controller: debug

 

- hello.controller 패키지 내에서 찍히는 로그들은 debug 부터 찍힌다. 

 

http://localhost:8080/actuator/loggers

http://localhost:8080/actuator/loggers/hello.controller

 

- 로그를 별도로 설정하지 않으면 스프링 부트는 기본으로 INFO를 사용한다.

- 우리는 hello.controller 를 DEBUG 로 설정했다. 

- 그 하위도 DEBUG 레벨이 적용된다. 

 

 

* 실시간 로그 레벨 변경

- 개발 서버는 보통 DEBUG 를 사용하지만, 운영서버는 보통 요청이 아주 많아 로그도 많이 남기 때문에, DEBUG 로그까지 모두 출력하게 되면 성능이나 디스크에 영향을 주게 된다. 

그래서 운영서버는 중요하다고 판단되는 INFO 로그 레벨을 사용한다. 

 

만약 급하게 운영중에 DEBUG나 TRACE 로그를 남겨서 확인하고 싶다면?

→ loggers 엔드포인트를 사용하여 애플리케이션을 다시 시작하지 않고, 실시간으로 로그 레벨을 변경할 수 있다. 

 

POST http://localhost:8080/actuator/loggers/hello.controller

{
	"configuredLevel" : "TRACE"
}

요청에 성공하면 204 응답이 온다. 

 

 

* HTTP 요청 응답 기록

- HTTP 요청과 응답의 과거 기록을 확인하고 싶다면 httpexchanges 엔드포인트를 사용한다.

- HttpExchangeRepository 인터페이스의 구현체를 빈으로 등록하면 httpexchanges 엔드포인트를 사용할 수 있다. 

    - 해당 빈을 등록하지 않으면 httpexchanges 엔드포인트가 활성화되지 않는다. 

- 스프링 부트는 기본으로 InMemoryHttpExchangeRepository 구현체를 제공한다. 

 

@SpringBootApplication
public class ActuatorApplication {

    public static void main(String[] args) {
        SpringApplication.run(ActuatorApplication.class, args);
    }

    @Bean
    public InMemoryHttpExchangeRepository httpExchangeRepository(){
        return new InMemoryHttpExchangeRepository();
    }

 

 

InMemoryHttpExchangeRepository 구현체를 까보면,

InMemoryHttpExchangeRepository.java

 

이 구현체는 최대 100개의 HTTP 요청을 제공한다. 최대 요청이 넘어가면 과거 요청을 삭제한다. 

setCapacity() 로 최대 요청수를 변경할 수 있다. 

 

http://localhost:8080/actuator/httpexchanges

 

실행해보면 지금까지 실행한 HTTP 요청과 응답 정보를 확인할 수 있다. 

이 기능은 매우 단순하고 기능에 제한이 많기 때문에 개발 단계에서만 사용하고, 실제 운영 서비스에서는 모니터링 툴이나 핀포인트, Zipkin 같은 다른 기술을 사용하는 것이 좋다. 

 

 

 

# 보안

- 액츄에이터가 제공하는 기능들은 우리 애플리케이션의 내부 정보를 너무 많이 노출한다. 

- 외부 인터넷 망이 공개된 곳에 액츄에이터의 엔드포인트를 공개하는 것은 보안상 좋은 방안이 아니다. 

- 액츄에이터의 엔드포인트들은 외부 인터넷에서 접근이 불가능하게 막고, 내부에서만 접근 가능한 내부망을 사용하는 것이 안전하다. 

 

* 액츄에이터를 다른포트에서 실행 

- 액츄에이터의 기능을 에플리케이션 서버와는 다른 포트에서 실행하려면 다음과 같이 설정하면 된다. 

management.server.port=9292

 

* 액츄에이터 URL 경로에 인증 설정

- 포트를 분리하는 것이 어렵다면, /actuator 경로에 서블릿 필터, 스프링 인터셉터 또는 스프링 시큐리티를 통해서 인증된 사용자만 접근 가능하도록 추가개발이 필요하다.

 

* 엔드포인트 경로 변경

management:
  endpoints:
    web:
      base-path: "/manage"

- /actuator/{엔드포인트} 대신에 /manage/{엔드포인트} 로 변경된다.