Java & Kotlin/Spring
[Spring Actuator] Example 3편 - Counter
전봉근
2023. 11. 26. 17:16
반응형
이전글: https://bkjeon1614.tistory.com/782
- Counter (https://micrometer.io/docs/concepts#_counters)
- 횟수를 세어 metric 으로 제공 단, 자연수만 가능하며 소수나 음수는 불가능하며 일반적으로는 cache hit 에 대한 누적 counter 및 http request 누적 횟수 등과 같이 지금까지 특정 이벤트가 몇 번 발생했는지 누적값을 제공할 때 Counter 를 사용한다. ()
- 사용법
- Counter.builder()
[ApplicationRequestManager.java]
[CounterController.java]package com.example.bkjeon.base.actuator.counter; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.MeterRegistry; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; @Service @RequiredArgsConstructor public class ApplicationRequestManager { // MeterRegistry 는 기본적으로 Bean 으로 등록되기 때문에 바로 사용하면 된다. private final MeterRegistry meterRegistry; private Counter httpRequestCounter; @PostConstruct void init() { httpRequestCounter = Counter.builder("application.http.request").register(meterRegistry); } public void increase() { httpRequestCounter.increment(); } }
package com.example.bkjeon.base.services.api.v1.actuator; import com.example.bkjeon.base.actuator.counter.ApplicationRequestManager; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("v1/counter") @RequiredArgsConstructor public class CounterController { private final ApplicationRequestManager applicationRequestManager; @GetMapping("req") public String req() { applicationRequestManager.increase(); return "ok"; } }
- /actuator/metrics/application.http.request 에서 확인이 가능하다.
- Counter.builder()
- Function Counter (https://micrometer.io/docs/concepts#_function_tracking_counters)
- Counter 의 경우 기존에 만든 횟수 관리 클래스를 재활용하지 못하는 단점이 있어서 Function Counter 를 사용하자.
- 사용법
[ApplicationRequestWithoutMicrometer.java]
[ApplicationFunctionCounterConfig.java]package com.example.bkjeon.base.actuator.counter; import org.springframework.stereotype.Service; import java.util.concurrent.atomic.AtomicLong; @Service public class ApplicationRequestWithoutMicrometer { private AtomicLong count = new AtomicLong(0); public long getCount() { return count.get(); } public void increase() { count.incrementAndGet(); } }
[CounterController.java]package com.example.bkjeon.base.config.actuator; import com.example.bkjeon.base.actuator.counter.ApplicationRequestWithoutMicrometer; import io.micrometer.core.instrument.FunctionCounter; import io.micrometer.core.instrument.MeterRegistry; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; @Configuration @RequiredArgsConstructor public class ApplicationFunctionCounterConfig { private final ApplicationRequestWithoutMicrometer manager; private final MeterRegistry meterRegistry; @PostConstruct void init() { FunctionCounter.builder("application.function.counter", manager, ApplicationRequestWithoutMicrometer::getCount).register(meterRegistry); } }
package com.example.bkjeon.base.services.api.v1.actuator; import com.example.bkjeon.base.actuator.counter.ApplicationRequestManager; import com.example.bkjeon.base.actuator.counter.ApplicationRequestWithoutMicrometer; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("v1/counter") @RequiredArgsConstructor public class CounterController { private final ApplicationRequestManager applicationRequestManager; private final ApplicationRequestWithoutMicrometer applicationRequestWithoutMicrometer; // 추가 @GetMapping("req") public String req() { applicationRequestManager.increase(); applicationRequestWithoutMicrometer.increase(); // 추가 return "ok"; } }
- MeterBinder 사용
- FunctionCounter 를 meterRegistry 에 등록하는 방법으로 MeterBinder 를 이용할 수 있다.
[CounterConfigWithMeterBinder.java]package com.example.bkjeon.base.config.actuator; import com.example.bkjeon.base.actuator.counter.ApplicationRequestWithoutMicrometer; import io.micrometer.core.instrument.FunctionCounter; import io.micrometer.core.instrument.binder.MeterBinder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class CounterConfigWithMeterBinder { // MeterBinder 를 이용하면 @PostConstruct 없이 구현이 가능 @Bean public MeterBinder applicationCounterWithMeterBinder( ApplicationRequestWithoutMicrometer manager) { return registry -> FunctionCounter.builder("application.function.counter2", manager, ApplicationRequestWithoutMicrometer::getCount).register(registry); } }
- FunctionCounter 를 meterRegistry 에 등록하는 방법으로 MeterBinder 를 이용할 수 있다.
- @Counted
- Micrometer 에서 @Counted 라는 Annotation 을 통해서 AOP 를 제공하고 있다.
- 예제
- @Counted 를 사용하려면 AOP 를 사용해야 하므로 build.gradle 에 추가
[build.gradle]dependencies { ... implementation 'org.springframework.boot:spring-boot-starter-aop' }
- 코드적용
[CountConfig.java]
[CounterController.java]package com.example.bkjeon.base.actuator.counter; import io.micrometer.core.aop.CountedAspect; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class CountConfig { // @Counted 를 사용하기위한 Aspect 등록 @Bean public CountedAspect countedAspect(MeterRegistry meterRegistry) { return new CountedAspect(meterRegistry); } }
@RestController @RequestMapping("v1/counter") @RequiredArgsConstructor public class CounterController { ... // @Counted 만 추가하면 된다. @Counted("my.counted.counter") @GetMapping("req2") public String req2() { return "OK"; } }
- http://localhost:9090/api/v1/counter/req2 호출 후 http://localhost:9090/api/actuator/metrics/my.counted.counter 에서 확인
- @Counted 를 사용하려면 AOP 를 사용해야 하므로 build.gradle 에 추가
참고
- https://semtul79.tistory.com/
나는 학생이다
semtul79.tistory.com
Spring | Home
Cloud Your code, any cloud—we’ve got you covered. Connect and scale your services, whatever your platform.
spring.io
- https://www.inflearn.com/course/spring-boot-actuator-%ED%8C%8C%ED%97%A4%EC%B9%98%EA%B8%B0/dashboard
반응형