인프라

EC2를 이용한 AWS ECS 기반 Spring Boot 3 DataDog 적용

dev.Dove 2024. 10. 3. 16:53

글과 상관없는 DataDog live Seoul 2024

 

들어가기 전...

인프라: AWS ECS, AWS EC2, AWS Linux 2023

서버: Spring Boot 3(Java 17), Micrometer Tracing


 

결말 미리 보기

DataDog에 서버의 정보를 보내려면 DataDog agent를 이용해야 하고 EC2 내 서비스들은 APM을 이용해 Agent에게 정보를 보내도록 설정한다.

 

EC2 인스턴스 타입을 c5.large 기준 ENI 제한이 3이다. 이로 인해 ECS 서비스 2개를 실행하고 DataDog agent는 각 ec2에서 2개의 서버 정보를 수집한다. 인스턴스 타입을 변경해서 단일 EC2에 더 많은 서비스를 기동 하면, DataDog host 비용을 절약할 수 있다. DataDog은 agent의 수로 host 수를 측정한다.

 

infrastructure 수집을 포기한다면 단일 agent만 서비스로 실행하고 모든 서비스의 정보를 수집할 수도 있다. 다만 이러면, Datadog을 사용하는 이유가.. 있을까?

 


1. DataDog agent ECS 내 등록, 실행

1. datadog-agent.json 파일을 만든다.

본 글에서는 agent 내 별도 기능을 미설정했습니다. 문서를 통해 로그 수집, 프로세스 데이터 수집, 네트워크 정보 수집이 가능하다. 

 

공식문서는 memory를 256으로 세팅하는 json을 보여준다. 본 글에서는 512를 했다. 중요한 건 EC2 기반 ECS에서는 서비스 실행을 위해 task에 설정한 메모리가 EC2 내 여유자원으로 있어야 서비스가 실행된다. c5a.large은 4GB의 메모리를 설정되어 있으나, 실제 사용가능한 메모리는 약 3800MB다. datadog agent를 ec2에서 실행할 경우 512MB를 제외한 용량에서 서비스 메모리를 설정해야 한다.

 

datadog-agent.json

{
    "family": "datadog-agent-task",
    "containerDefinitions": [
        {
            "name": "datadog-agent",
            "image": "public.ecr.aws/datadog/agent:latest",
            "cpu": 100,
            "memory": 512,
            "portMappings": [
                {
                    "containerPort": 8126,
                    "hostPort": 8126,
                    "protocol": "tcp"
                }
            ],
            "essential": true,
            "environment": [
                {
                    "name": "DD_SITE",
                    "value": "datadoghq.com"
                },
                {
                    "name": "DD_API_KEY",
                    "value": "{datadog api key}"
                }
            ],
            "mountPoints": [
                {
                    "sourceVolume": "docker_sock",
                    "containerPath": "/var/run/docker.sock",
                    "readOnly": true
                },
                {
                    "sourceVolume": "cgroup",
                    "containerPath": "/host/sys/fs/cgroup",
                    "readOnly": true
                },
                {
                    "sourceVolume": "proc",
                    "containerPath": "/host/proc",
                    "readOnly": true
                },
                {
                    "sourceVolume": "pointdir",
                    "containerPath": "/opt/datadog-agent/run",
                    "readOnly": false
                },
                {
                    "sourceVolume": "containers_root",
                    "containerPath": "/var/lib/docker/containers",
                    "readOnly": true
                }
            ],
            "volumesFrom": [],
            "systemControls": []
        }
    ],
    "volumes": [
        {
            "name": "docker_sock",
            "host": {
                "sourcePath": "/var/run/docker.sock"
            }
        },
        {
            "name": "proc",
            "host": {
                "sourcePath": "/proc/"
            }
        },
        {
            "name": "cgroup",
            "host": {
                "sourcePath": "/sys/fs/cgroup/"
            }
        },
        {
            "name": "pointdir",
            "host": {
                "sourcePath": "/opt/datadog-agent/run"
            }
        },
        {
            "name": "containers_root",
            "host": {
                "sourcePath": "/var/lib/docker/containers"
            }
        }
    ]
}

 

 

2. json 파일을 이용해 task 등록

aws ecs register-task-definition --cli-input-json datadog-agent.json

 

명령어를 통해 ECS task에 DataDog agent를 등록한다.

 

3. DataDog Agent deamon 실행

위 사진처럼 서비스를 생성하면 각 EC2에 DataDog agent가 실행된다.

 


2. Spring Boot 3 trace id 설정

개발, 운영 모두 DataDog을 못 사용할 수 도 있다. 또는 spring boot를 이용해 MSA 환경을 구성한 경우 서버에서 Spring Cloud Sleuth를 사용한다. Spring Boot3에서 sleuth는 더 이상 사용이 불가하다. 대신 Micrometer Tracing를 사용하여 log를 설정할 수 있다.

 

1. (선택) Micrometer 설정

build.gradle에 micrometer를 설정한다. datadog을 이용하기에 io.zipkin.reporter2는 제외한다. openfeign 사용을 위한 라이브러리도 추가한다.

    // Micrometer Tracing
    implementation('io.micrometer:micrometer-tracing-bridge-brave') {
        exclude group: 'io.zipkin.reporter2'
    }
    implementation 'io.github.openfeign:feign-micrometer'

 

logback은 다음과 같이 설정한다.

%X{traceId},%X{spanId}

2.  logback 설정

datadog traceid는 dd.traceId로 설정해야 주입받을 수 있다.

출처: https://docs.datadoghq.com/ko/tracing/other_telemetry/connect_logs_and_traces/java/?tab=log4j2

 

Correlating Java Logs and Traces

Connect your Java logs and traces to correlate them in Datadog.

docs.datadoghq.com

 

<property name="LOG_PATTERN"
  value="%clr(%d{yyyy-MM-dd HH:m:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) [%clr(${springAppName:-}){yellow},%X{dd.trace_id},%X{dd.span_id:-} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
   
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>${LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>

 


3. Dockerfile을 이용한 datadog apm 설정

Dockerfile에 apm을 설정하는 건 다음 코드를 참고하면 된다.

 

서버에서 traceId를 출력하도록 주입을 위해 DD_LOGS_INJECTION를 설정한다. 추가로 W3C기반 traceid를 사용하기 위해 DD_TRACE_PROPAGATION_STYLE도 설정한다. 

 

DD_AGENT_HOST는 Amazon Linux 2023 기준으로 작성했다. 다른 OS는 문서를 참고...

#!/bin/bash
FROM amazoncorretto:17
WORKDIR /app

ENV VERSION="{버전}"
ENV APP_NAME="{artifact 이름}"

COPY build/libs/${APP_NAME}-${VERSION}.jar .

#DataDog 설정
ENV DD_SERVICE={서비스 명}
ENV DD_LOGS_INJECTION=true 
ENV DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED=true
ENV DD_TRACE_PROPAGATION_STYLE=tracecontext,datadog
ENV DD_ENV=prod
ENV DD_TRACE_SAMPLE_RATE=1
ENV DD_VERSION=1.0.0

ADD 'https://dtdg.co/latest-java-tracer' dd-java-agent.jar

CMD export DD_AGENT_HOST=$(TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600");curl http://169.254.169.254/latest/meta-data/local-ipv4 -H "X-aws-ec2-metadata-token: $TOKEN"); \
    java -javaagent:dd-java-agent.jar \
    -jar \
    -Djava.net.preferIPv4Stack=true -Dspring.profiles.active=prod \
    ${APP_NAME}-${VERSION}.jar;

 

 


번외. Datadog console에서 보이는 traceid와 서버 traceid가 다르다!

 

 

https://docs.datadoghq.com/ko/tracing/guide/span_and_trace_id_format/

 

Trace and Span ID Formats

Datadog, the leading service for cloud-scale monitoring.

docs.datadoghq.com

 

trace id의 형식이 달라 생긴 문제다. 아래 설정을 통해 128비트 Trace ID는 32자의 소문자 16진수로 보이며 로그의 traceid를 datadog에서 동일하게 보여준다.

DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED=true

 

 


참고한 글

https://docs.datadoghq.com/ko/containers/amazon_ecs/apm/?tab=ec2%EB%A9%94%ED%83%80%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%97%94%EB%93%9C%ED%8F%AC%EC%9D%B8%ED%8A%B8

 

ECS 애플리케이션 추적

Datadog, the leading service for cloud-scale monitoring.

docs.datadoghq.com

https://docs.datadoghq.com/ko/tracing/guide/span_and_trace_id_format/

 

Trace and Span ID Formats

Datadog, the leading service for cloud-scale monitoring.

docs.datadoghq.com

https://docs.datadoghq.com/ko/tracing/trace_collection/automatic_instrumentation/dd_libraries/java/?tab=wget

 

Tracing Java Applications

Datadog, the leading service for cloud-scale monitoring.

docs.datadoghq.com

https://docs.datadoghq.com/ko/containers/

 

컨테이너 모니터링

컨테이너화된 인프라스트럭처에서 데이터를 수집하기 위한 에이전트 설치 및 설정

docs.datadoghq.com