장정우님이 지음, [스프링부트 핵심가이드 :: 스프링 부트를 활용한 애플리케이션 개발 실무] 책을 읽고 정리한 필기입니다.📢

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

앞에서 살펴봤듯이 액추에이터는 다양한 정보를 가공해서 제공한다. 그 밖에 개발자의 요구사항에 맞춘 커스텀 기능 설정도 제공한다. 커스텀 기능을 개발하는 방식에는 크게 두 가지가 있다. 첫 번째는 기존 기능에 내용을 추가하는 방식이고, 두 번째는 새로운 엔드포인트를 개발하는 방식이다.

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

액추에이터를 커스터마이징하는 가장 간단한 방법은 앞에서 /info 엔드포인트의 내용을 추가한 것처럼 application.properties 파일 내에 내용을 추가하는 것이다. 그러나 이 방법은 많은 내용을 담을 때는 관리 측면이 좋지 않다.

그래서 커스텀 기능을 설정할 때는 별도의 구현체 클래스를 작성해서 내용을 추가하는 방법을 많이 활용된다. 액추에이터에서는 InfoContributor 인터페이스를 제공하고 있는데, 이 인터페이스를 구현하는 클래스를 생성하면 된다. 아래와 같이 InfoContributor 인터페이스에 대한 구현 클래스를 생성한다.


1
2
3
4
5
6
7
8
9
@Component
public class CustomInfoContributor implements InfoContributor {
    @Override
    public void contribute(Info.Builder builder) {
        Map<String, Object> content = new HashMap<>();
        content.put("code-info", "InfoContributor 구현체에서 정의한 정보입니다.");
        builder.withDetail("custom-info-contributor", content);
    }
}


새로 생성한 클래스를 InfoContributor 인터페이스의 구현체로 설정하면 contributor 메서드를 오버라이딩할 수 있게 된다. 이 메서드에서 파라미터로 받은 Builder객체는 액추에이터 패키지의 Info클래스 안에 정의돼 있는 클래스로서 info 엔드포인트에서 보여줄 내용을 담는 역할을 수행한다. 이렇게 객체를 가져와 6~8번 줄처럼 콘텐츠를 담아 builder에 포함하면 엔드포인트 출력 결과에서 확인할 수 있다. 아래와 같이 설정한 후 애플리케이션을 재가동해서 엔드포인트를 호출하면 아래와 같은 결과를 볼 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
{
  "organization":{
    "name":"wikibooks"
  },
  "contact":{
    "email":"thinkground.flature@email.com",
    "phoneNumber":"010-1234-5678"
  },
  "custom-info-contributor":{
    "code-info":"InfoContributor 구현체에서 정의한 정보입니다."
  }
}


보다시피 기존 application.properties 에서 정의했던 속성값을 비롯해 구현체 클래스에서 포함한 내용이 추가된 것을 볼 수 있다.

커스텀 엔드포인트 생성

@EndPoint 어노테이션으로 빈에 추가된 객체들은 @ReadOperation, @WriteOperation, @DeleteOperation 어노테이션을 사용해 JMX나 HTTP를 통해 커스텀 엔드포인트를 노출시킬 수 있다. 만약 JMX에서만 사용하거나 HTTP에서만 사용하는 것을 제한하고 싶다면 @JmxEndpoint, @WebEndpoint 어노테이션을 사용하면 된다.

이 책에서는 간단하게 애플리케이션에 메모 기록을 남길 수 있는 기능을 엔드포인트로 생성하겠다. 아래와 같이 엔드포인트 클래스를 생성한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Component
@Endpoint(id = "note")
public class NoteEndpoint {
    
    private Map<String, Object> noteContent = new HashMap<>();
    
    @ReadOperation
    public Map<String, Object> getNote(){
        return noteContent;
    }
    
    @WriteOperation
    public Map<String, Object> writeNote(String key, Object value){
        noteContent.put(key, value);
        return noteContent;
    }
    
    @DeleteOperation
    public Map<String, Object> deleteNote(String key){
        noteContent.remove(key);
        return noteContent;
    }
}


위 코드의 2번 줄에서는 @Endpoint 어노테이션을 사용하고 있다. 이 어노테이션을 선언하면 액추에이터에 엔드포인트로 자동으로 등록되며 id 속성값으로 경로를 정의할 수 있다. 또한 enableByDefault라는 속성으로 현재 생성하는 엔드포인트의 기본 활성화 여부도 설정 가능하다. enableByDefault속성의 기본값은 true로서 값을 별도로 설정하지 않으면 활성화된다.

엔드포인트를 설정하는 클래스에는 @ReadOpertation, @WriteOperation, @DeleteOperation 어노테이션을 사용해 각 동작 메서드를 생성할 수 있다.

7~10번 줄에서는 @ReadOperation 어노테이션을 정의해 HTTP, GET 요청을 반응하는 메서드를 생성했다. 이 클래스에서는 noteContent라고 하는 Map타입의 객체를 전달하고 있다. 애플리케이셔을 재가동한 후 다음 엔드포인트를 호출해 보겠다.



http://localhost:8080/actuator/note


1
{}


보다시피 아직 값을 넣지 않은 상태라서 JSON 형태의 빈 값이 표현된다. 그럼 @WriteOperation 동작을 확인하기 위해 아래와 같이 Talend API Tester를 POST호출을 시도한다.


image


위와 같이 메서드에서 받고자 하는 파라미터의 이름을 JSON의 키 값으로 설정하고, 그에 해당하는 값을 후가할 수 있다. 이렇게 값을 추가하고 다시 GET 메서드로 커스텀 엔드포인트인 /note를 호출하면 다음과 같은 결괏값이 확인된다.


1
2
3
{
  "description": "설명 부분을 기입한다."
}


이번에는 @DeleteOperation 어노테이션이 선언된 메서드를 호출해 보겠다. @DeleteOperation 어노테이션이 선언된 메서드는 DELETE 호출을 통해 사용할 수 있으며, [Query Parameters] 에 값을 넣어 호출한다. 현재 구성된 메서드에서는 key 값을 받아 Map객체에서 해당 값을 삭제하는 작업을 수행하게 된다. 아래와 같이 호출을 시도한다.


image


위와 같이 호출하면 아래와 같이 지정한 키 값이 상제된 결과를 확인할 수 있다.

지즘까지의 액추에이터의 커스텀 엔드포인트를 생성해봤다. 커스텀 엔드포인트는 코드로 구현되기 때문에 더욱 확장성 있는 기능을 개발할 수 있다.


💡 Tip.

스프링 부트 액추에이터의 자세한 내용은 공식 페이지에서 확인할 수 있다.

SpringBoot 카테고리 내 다른 글 보러가기

댓글남기기