1. 개요
보통 HikariCP를 모니터링 하기 위해서는 JConsole과 같은 Java 애플리케이션 모니터링 툴을 통해 진행해야 하지만, 다소 불편하다고 느낄 수 있다.
MBean(Managed Bean)이란, 애플리케이션 혹은 리소스의 상태를 모니터링할 수 있는 Java 객체이다.
HikariCP에서 제공하는 MBean을 통해 다음의 정보를 확인할 수 있다.
- Idle connections의 수
- Active connections(현재 사용하고 있는)의 수
- 모든 connection의 수
- connection을 기다리고 있는 thread의 수
그렇다면 SpringBoot 애플리케이션에서 Datadog에서 JMX MBean을 이용하여 HikariCP 모니터링을 어떻게 할 수 있을까?
전체적으로 다음의 과정이 필요하다.
[1] Java SpringBoot에서의 Hikari Pool Configuration
[2] values.yaml에서 Datadog Agent Image 변경
[3] Pod Annotation 추가함으로써 Datadog Agent가 Auto Discovery 할 수 있도록 설정하기
** 만약 본 내용을 적용하고 싶으실 경우 그대로 따라하시지 본 글은 참고사항으로만 확인 하시길 바랍니다.
1.1) Auto Discovery 수집 원리
우선 아래 공식문서를 참고하시면 된다.
https://docs.datadoghq.com/agent/guide/autodiscovery-with-jmx/?tab=containeragent
https://docs.datadoghq.com/containers/kubernetes/integrations/?tab=kubernetesadv2
컨테이너화된 시스템은 동적인 특성으로 인해 수동으로 모니터링 설정이 힘들다.
→ 기존의 /etc/datadog/conf.d/xxx.yaml 파일에서 Datadog 설정을 하는게 아니라, Auto Discovery란 기능을 통해 설정해야만 한다.
Datadog Agent는 DaemonSet으로 띄워져 있고,
Datadog Agent는 배포된 노드의 Container들에 대하여 Annotation을 지속적으로 쿼리하여 설정값이 주입되어 있는지 확인한다.
2. 내용
Datadog에서는 Hikari CP를 모니터링하기 위해서 JMX Fetch Integration을 활용하여 모니터링을 수행할 수 있다.
2.1 Hikari CP JMX Mbean 설정
참고 문서
https://github.com/brettwooldridge/HikariCP/wiki/MBean-(JMX)-Monitoring-and-Management
registerMbeans=true 설정
JMX Host, Port 설정
MXBean 가져오기
MXBean은 MBean의 종류 중 하나로, 제공되는 데이터를 제한하여 호환성을 높인 MBean이다.
@Bean
public HikariPoolMXBean hikariPoolMXBean() throws MalformedObjectNameException {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName objectName = new ObjectName("com.zaxxer.hikari:type=Pool (hikari)");
return JMX.newMBeanProxy(mBeanServer, objectName, HikariPoolMXBean.class);
}
Hikari CP 코드 살펴보기
if (!config.isRegisterMbeans())
=> application.properties에서 설정한 register-mbeans의 값을 가져와 true일 경우 MXBean 객체를 생성한다.
우리는 위에서 register-mbeans: true로 기 설정한 상태이다.
//HikariPool.java
public HikariPool(final HikariConfig config)
{
// other codes
handleMBeans(this, true);
// other codes
}
void handleMBeans(final HikariPool hikariPool, final boolean register)
{
if (!config.isRegisterMbeans()) {
return;
}
try {
final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
final ObjectName beanConfigName = new ObjectName("com.zaxxer.hikari:type=PoolConfig (" + poolName + ")");
final ObjectName beanPoolName = new ObjectName("com.zaxxer.hikari:type=Pool (" + poolName + ")");
if (register) {
if (!mBeanServer.isRegistered(beanConfigName)) {
mBeanServer.registerMBean(config, beanConfigName);
mBeanServer.registerMBean(hikariPool, beanPoolName);
} else {
logger.error("{} - JMX name ({}) is already registered.", poolName, poolName);
}
}
else if (mBeanServer.isRegistered(beanConfigName)) {
mBeanServer.unregisterMBean(beanConfigName);
mBeanServer.unregisterMBean(beanPoolName);
}
}
catch (Exception e) {
logger.warn("{} - Failed to {} management beans.", poolName, (register ? "register" : "unregister"), e);
}
}
2.2 Datadog Image Tag 변경
EKS(Kubernetes)에 Datadog Agent를 Helm으로 배포했을 경우 values.yaml로 보통 관리하는게 일반적이다.
7.38.2-jmx 처럼 Datadog Agent Image Tag에 -jmx를 추가
2.3 Pod Annotation 설정
Deployment로 배포하였을 경우, spec → template → metadata → annotations에 내용을 추가하면 된다.
[JMX 구성 예시]
아래 빨간색으로 색칠한 부분은 환경에 맞게 설정이 필요하다.
- CONTAINER_IDENTIFIER : Application 구동중인 컨테이너의 이름
ex) my-container
- POOLNAME : Pool 이름
ex) MY-POOL
- JMX_PORT : JMX 포트 번호
ex) 9875
ad.datadoghq.com/<CONTAINER_IDENTIFIER>.check_names: '["jmx"]'
ad.datadoghq.com/<CONATEINR_IDENTIFIER>.init_configs: '[{"is_jmx":true,"conf":[{"include":{"domain":"com.zaxxer.hikari","bean":["com.zaxxer.hikari:type=Pool (POOLNAME)"],"attribute":{"IdleConnections":{"metric_type":"gauge","alias":"jmx.com.zaxxer.hikari.idle_connections"},"ActiveConnections":{"metric_type":"gauge","alias":"jmx.com.zaxxer.hikari.active_connections"},"TotalConnections":{"metric_type":"gauge","alias":"jmx.com.zaxxer.hikari.total_connections"},"ThreadsAwaitingConnection":{"metric_type":"gauge","alias":"jmx.com.zaxxer.hikari.threads_awaiting_connection"}}}}]}]'
ad.datadoghq.com/<CONTAINER_IDENTIFIER>.instances: '[{"host": "%%host%%","port":"<JMX_PORT>"}]'
# 환경에 맞는 파드 이름 설정
POD_NAME=my-pod
NODE=`kubectl get pods -owide | grep -v NODE | grep $POD_NAME | awk '{print $7}'`
DD_AGENT_POD=`kubectl get pods -owide -n kube-system | grep datadog | grep $NODE | awk '{print $1}'`
# 1. agent status
kubectl exec -it $DD_AGENT_POD -n kube-system -- agent status | grep -A 15 JMX
[1] agent status
[2] jmx list everything
kubectl exec -it $DD_AGENT_POD -n kube-system -- agent jmx list everything | grep -i hikari
만약 수집이 잘 안되어 트러블슈팅이 필요할 경우 공식 문서를 참고하면 된다.
https://docs.datadoghq.com/integrations/faq/troubleshooting-jmx-integrations/?tab=agentv6v7
3. 정리
EKS, ECS, Docker와 같은 동적인 환경에서는 Auto Discovery란 기능을 통해 Datadog Agent 설정을 수행해야만 한다.
쿠버네티스의 경우 Pod Annotation에 아래의 형식대로 값을 기입해주면 된다.
ad.datadoghq.com/<CONTAINER_IDENTIFIER>.check_names
ad.datadoghq.com/<CONATEINR_IDENTIFIER>.init_configs
ad.datadoghq.com/<CONTAINER_IDENTIFIER>.instances
설정값은 Application에 따라 전부 다르기 때문에 Docs를 잘 확인해보고, Datadog agent status 등의 명령어를 활용하여 데이터가 잘 수집되는지 디버깅을 하면서 진행하면 좀 더 수월하게 Datadog으로 메트릭을 수집할 수 있다.
1) 설정
2) Datadog Agent Sub command로 수집유무 확인 / Application 데이터독 startup logs 확인
3) Datadog 웹 페이지 -> metrics 들어가서 수집 유무 최종 확인
'Log,Monitorings' 카테고리의 다른 글
[EKS] 로그 시스템 Loki 도입을 위한 몇가지 운영 팁 (6) | 2023.03.11 |
---|---|
[EKS] 아주 가벼운 Loki + Grafana + Promtail 로그 시스템 구성 (2) | 2022.10.31 |
[Datadog] AWS Events 기반으로 Datadog 알람 설정하기 (0) | 2022.06.26 |
[Elasticsearch] Nginx 로그 Fluentd를 통해 Elasticsearch로 보내기 (0) | 2021.12.20 |
[Fluentd] 로그 수집 패턴, Fluentd 개념 정리 (0) | 2021.12.18 |