[DevOps] AWS EC2에서 CloudWatch Agent와 FastAPI 연동

JUNYOUNG·2024년 12월 8일
post-thumbnail

출시를 앞둔 시점에서 우리 서비스는 기획과 설계 없이 대표님의 강경한 추진력으로 만들어진, 소위 말하는 '스크럼 서비스'다. 하하하.

그렇기 때문에 빈번한 장애가 예상되고, 즉각적인 대응이 무엇보다 중요하다. 로깅과 모니터링은 이런 환경에서 필수적이라 판단했고, 특히 장애 발생 시 즉각적으로 알람을 받을 수 있는 시스템 구축이 필요하다고 느꼈다.

Slack API를 활용해 알림 시스템을 구축하고자 했고, AWS의 다양한 모니터링 도구도 고민했지만, 우선 애플리케이션 단에서 어떤 장애가 발생했는지 파악하는 것이 가장 중요하다고 판단했다. 이를 위해 직접 로그를 관리하고 확인할 수 있도록 AWS CloudWatch Agent를 설치해 연동을 진행했다. 아래는 이번 작업의 주요 내용이다.


1. AWS CLI 설치 및 설정

1-1. AWS CLI 설치

AWS CLI는 AWS 리소스를 명령어로 관리할 수 있는 도구다. EC2 인스턴스에서 CloudWatch Agent를 설정하거나 IAM 역할을 확인하는 작업을 CLI를 통해 처리할 수 있다.

AWS CLI는 기본적으로 AWS와의 통신을 위한 API 호출을 간단하게 처리할 수 있는 도구이기 때문에, CloudWatch Agent 설정뿐만 아니라 이후 AWS 리소스 관리에서도 자주 사용된다.

설치 명령어

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

설치 확인

aws --version

출력 예시

aws-cli/2.12.3 Python/3.9.11 Linux/x86_64

1-2. AWS CLI 설정

AWS CLI를 설정하면 EC2 인스턴스가 IAM Role을 통해 인증 정보를 자동으로 가져오도록 구성할 수 있다.

만약 IAM Role이 없는 환경이라면 Access KeySecret Key 를 수동으로 설정해야 한다.

명령어

aws configure

입력값

AWS Access Key ID [None]: <Access Key>
AWS Secret Access Key [None]: <Secret Key>
Default region name [None]: ap-northeast-2
Default output format [None]: json

2. 메타데이터 서비스(IMDS) 확인

2-1. IMDS란?

IMDS는 EC2 인스턴스가 AWS API를 호출할 때 필요한 인증 정보를 제공하는 서비스다.
특히 IMDSv2는 보안성을 강화한 최신 메타데이터 서비스 버전으로, HTTP PUT 요청을 통해 토큰을 발급받아야 인증 정보를 사용할 수 있다.
이 작업은 EC2 인스턴스가 IAM 역할(Role)을 통해 AWS API를 호출할 수 있는지 확인하는 데 필수적이다.

IMDSv2를 사용한 토큰 생성

TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")

IAM Role 확인

curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/

IAM Role 자격 증명 확인

curl -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>

출력 예시

{
  "Code": "Success",
  "LastUpdated": "2024-12-08T12:00:00Z",
  "AccessKeyId": "AKIA...",
  "SecretAccessKey": "abcd...",
  "Token": "FQoGZX...",
  "Expiration": "2024-12-08T17:00:00Z"
}

3. CloudWatch Agent 설정 및 구성

3-1. CloudWatch Agent 설치

CloudWatch Agent는 애플리케이션 로그와 시스템 메트릭을 CloudWatch로 전송하는 도구다.

AWS에서 기본적으로 제공하는 Agent이기 때문에 EC2 환경에 최적화되어 있다.

설치 명령어

sudo apt update
sudo apt install amazon-cloudwatch-agent

설치 확인

sudo systemctl status amazon-cloudwatch-agent

3-2. CloudWatch Agent 설정 파일 작성

CloudWatch Agent는 설정 파일을 통해 어떤 로그를 수집할지 정의한다.

JSON 형식의 설정 파일을 작성하여 CloudWatch Agent에 적용하면 로그가 지정된 로그 그룹으로 전송된다.

설정 파일 예시

{
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/home/ubuntu/lemon/backend/log/application/error.log",
            "log_group_name": "application-error-log-group",
            "log_stream_name": "{instance_id}-error",
            "retention_in_days": 7
          }
        ]
      }
    }
  },
  "append_dimensions": {
    "InstanceId": "${aws:InstanceId}",
    "InstanceType": "${aws:InstanceType}"
  }
}

설정 파일 저장

sudo vi /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json

3-3. CloudWatch Agent 시작 및 설정 적용

CloudWatch Agent를 시작하고 설정을 적용하면 애플리케이션 로그가 CloudWatch로 전송되기 시작한다.
이 과정에서 IAM 역할이 올바르게 연결되어 있어야 하며, 로그 그룹이 정상적으로 생성되어 있어야 한다.

설정 파일 적용

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config \
  -m ec2 \
  -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
  -s

서비스 재시작 및 상태 확인

sudo systemctl restart amazon-cloudwatch-agent
sudo systemctl status amazon-cloudwatch-agent

로그 확인

sudo journalctl -u amazon-cloudwatch-agent

4. AWS CLI를 통한 CloudWatch 로그 설정

4-1. 로그 그룹 생성

CloudWatch 로그를 수집하려면 먼저 로그 그룹을 생성해야 한다.

로그 그룹 생성

aws logs create-log-group --log-group-name "application-error-log-group"

보관 기간 설정

aws logs put-retention-policy \
  --log-group-name "application-error-log-group" \
  --retention-in-days 7

출력 예시

{
  "logGroupName": "application-error-log-group",
  "retentionInDays": 7
}

5. FastAPI와 CloudWatch Agent 연동

5-1. FastAPI 에러 로그 설정

FastAPI에서 발생하는 에러 로그를 CloudWatch로 전송하려면 로그 파일을 지정 경로에 작성해야 한다.

이를 위해 Python의 logging 모듈을 활용하여 로그를 CloudWatch Agent가 수집할 수 있도록 설정한다.

코드 예시

import logging
from fastapi import FastAPI

app = FastAPI()

# 로그 설정
logging.basicConfig(
    level=logging.ERROR,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    handlers=[
        logging.FileHandler("/home/ubuntu/<애플리케이션경로>/log/application/error.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

@app.get("/error")
def create_error():
    logger.error("Test error log")
    return {"message": "This is a test error!"}


profile
Onward, Always Upward - 기록은 성장의 증거

0개의 댓글