AWS 기초 #7 CloudWatch 입문: 로그 / 메트릭

8 분 소요

#1 ~ #6으로 AWS 셋업의 기반이 모였습니다. 이제 운영의 또 다른 축이 남았습니다. 무엇이 어디서 무슨 일을 하고 있는가를 보는 도구입니다.

CloudWatch는 AWS의 관측 (Observability) 표준입니다. AWS 안의 거의 모든 서비스가 기본으로 메트릭을 CloudWatch로 보내고, 로그도 CloudWatch Logs가 받습니다. 운영의 첫 시야는 여기서 시작합니다.

이 글은 CloudWatch의 4가지 구성인 Logs / Metrics / Alarms / Dashboards를 한 번에 정리하겠습니다.

큰 그림: CloudWatch의 4가지 구성 #

구성 요소무엇흔한 사용처
Logs텍스트 로그 저장 / 검색EC2 / Lambda / ECS / API Gateway의 로그
Metrics시계열 숫자 (CPU%, 요청 수 등)모든 AWS 서비스가 자동 송신
Alarms메트릭이 임계 넘으면 알림 / 액션운영 알림, 자동 스케일
Dashboards그래프 / 위젯 페이지팀 / 서비스별 한눈 보기

이 넷이 한 흐름으로 엮입니다. 로그 → 메트릭 → 알람 → 대시보드.

CloudWatch Logs #

로그 그룹과 로그 스트림 #

구조
Log Group           : 보통 한 애플리케이션 / 서비스 단위
  └── Log Stream    : 보통 한 프로세스 / 컨테이너 단위
        └── Log Event : 한 줄
항목
Log Group/aws/lambda/my-function, /ecs/my-service, /var/log/myapp
Log StreamLambda 실행 환경 ID, ECS Task ID, EC2 인스턴스 ID
Log Event한 줄 텍스트 + timestamp

Lambda / ECS Fargate는 자동으로 로그를 CloudWatch Logs로 보냅니다. EC2는 CloudWatch Agent 또는 보조 도구 (fluent-bit 등)가 필요합니다.

Retention: 가장 중요한 설정 #

기본 retention은 영구. 그대로 두면 로그가 영원히 쌓여 비용 폭주. 가입 직후 / 새 로그 그룹마다 retention을 정해야 합니다.

항목권장 retention
일반 애플리케이션 로그30~90일
디버그 / 개발 로그7일
보안 / 감사 로그 (CloudTrail)1~7년 (S3로 보내는 게 더 쌈)
Lambda 로그14~30일
retention 설정
aws logs put-retention-policy \
  --log-group-name /aws/lambda/my-function \
  --retention-in-days 30
모든 로그 그룹에 일괄 적용
aws logs describe-log-groups --query 'logGroups[].logGroupName' --output text \
  | tr '\t' '\n' \
  | while read name; do
      aws logs put-retention-policy --log-group-name "$name" --retention-in-days 30
    done

이 한 줄이 CloudWatch 비용 사고를 절반 이상 막아 줍니다.

새 로그 그룹의 자동 retention #

새로 만들어지는 로그 그룹에 자동으로 retention을 적용하는 방법은 두 가지.

방법 1: EventBridge + Lambda. CreateLogGroup 이벤트를 받아 자동 적용합니다 (실전에서 자주 씁니다).

방법 2: 정책으로 강제. 만들 때 retention을 명시하지 않으면 거부합니다 (살짝 과합니다).

Lambda 로그 보내기 #

Lambda: 그냥 print
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def handler(event, context):
    logger.info("Received event: %s", event)
    return {"ok": True}

stdout / stderr가 자동으로 CloudWatch Logs로 흘러갑니다. 로그 그룹 이름은 /aws/lambda/<함수명>.

EC2 / ECS: CloudWatch Agent #

EC2는 자동이 아닙니다. CloudWatch Agent 설치 필요.

Amazon Linux 2023 / Ubuntu
sudo yum install -y amazon-cloudwatch-agent       # AL
# 또는
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i amazon-cloudwatch-agent.deb

설정 파일 /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json:

간단 설정
{
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/myapp/*.log",
            "log_group_name": "/myapp/server",
            "log_stream_name": "{instance_id}",
            "retention_in_days": 30
          }
        ]
      }
    }
  },
  "metrics": {
    "metrics_collected": {
      "mem":  { "measurement": ["mem_used_percent"] },
      "disk": { "measurement": ["used_percent"], "resources": ["*"] }
    }
  }
}

ECS의 Fargate는 컨테이너 정의에 awslogs 드라이버를 적으면 자동입니다. 이건 고급 #1에서 자세히 다룹니다.

Logs Insights: 쿼리로 검색 #

CloudWatch Logs의 검색 / 분석 도구. SQL 비슷한 자체 문법.

가장 단순한 쿼리
fields @timestamp, @message
| sort @timestamp desc
| limit 100
ERROR만
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 50
요청 시간 분포 (Lambda)
fields @timestamp, @duration
| filter @type = "REPORT"
| stats avg(@duration), max(@duration), count(*) by bin(5m)
API Gateway: 5xx 비율
fields @timestamp, status, path
| filter status >= 500
| stats count(*) as errors by path
| sort errors desc

자주 쓰는 명령어:

명령무엇
fields보일 필드
filter조건 필터
parse문자열에서 필드 추출
stats집계 (count, avg, max, percentile)
sort정렬
limit최대 결과 수
bin(5m)시간 버킷

Logs Insights 비용 주의 #

쿼리 시 스캔한 데이터 GB당 과금 (~$0.005/GB). 큰 로그 그룹을 무제한 시간으로 쿼리하면 비용 사고. 항상 시간 범위 좁게.

CloudWatch Metrics #

메트릭은 시계열 숫자. AWS의 거의 모든 서비스가 자동 송신합니다.

자주 보는 메트릭 #

서비스자주 보는 메트릭
EC2CPUUtilization, NetworkIn/Out, DiskReadOps
RDSCPUUtilization, DatabaseConnections, FreeStorageSpace, ReadLatency
LambdaInvocations, Errors, Duration, Throttles, ConcurrentExecutions
ECSCPUUtilization, MemoryUtilization (Service / Task 별)
ALBRequestCount, TargetResponseTime, HTTPCode_Target_5XX_Count
API GatewayCount, Latency, 4XXError, 5XXError
S3BucketSizeBytes, NumberOfObjects (1일 1회)
DynamoDBConsumedReadCapacity/WriteCapacity, ThrottledRequests

메트릭의 차원 (Dimensions) #

같은 메트릭이라도 차원으로 쪼개집니다.

예: CPUUtilization
Service: AWS/EC2
Metric:  CPUUtilization
Dimensions:
  - InstanceId: i-1234567890
  - InstanceId: i-2345678901
  - InstanceId: i-3456789012

차원이 다르면 별도 메트릭. 메트릭 수 = 비용이라 차원이 폭발하면 비용 사고.

통계 (Statistic) #

통계무엇
Sum합계. Invocations, RequestCount
Average평균. CPU, Latency
Maximum최대. Spike 감지
Minimum최소
p95 / p99백분위수. Latency
SampleCount데이터 포인트 수

대부분의 경우 Average + p95가 의미 있습니다. p99 / p99.9는 SLA / 사용자 경험에 직접 영향.

표준 vs 고해상도 #

종류해상도비용
표준1분표준
고해상도1초고가. 스파이크 짧은 경우만

대부분 표준 1분으로 충분합니다.

커스텀 메트릭 보내기 #

애플리케이션이 직접 메트릭을 송신합니다.

Python: boto3
import boto3

cloudwatch = boto3.client("cloudwatch")
cloudwatch.put_metric_data(
    Namespace="MyApp",
    MetricData=[{
        "MetricName": "OrderCreated",
        "Value": 1,
        "Unit": "Count",
        "Dimensions": [
            {"Name": "Environment", "Value": "prod"},
            {"Name": "Region", "Value": "ap-northeast-2"},
        ],
    }],
)

비용: 메트릭당 $0.30 / 월. 차원의 조합마다 별도. 사용자 ID 같은 고카디널리티 차원은 절대 금지.

EMF (Embedded Metric Format): Lambda 용 패턴 #

Lambda에선 put_metric_data 호출 자체가 비용 / 지연 부담. 로그에 특정 JSON 형식으로 적으면 CloudWatch가 자동으로 메트릭으로 변환.

EMF 형식
import json
print(json.dumps({
    "_aws": {
        "Timestamp": int(time.time() * 1000),
        "CloudWatchMetrics": [{
            "Namespace": "MyApp",
            "Dimensions": [["Environment"]],
            "Metrics": [{"Name": "OrderCreated", "Unit": "Count"}],
        }],
    },
    "Environment": "prod",
    "OrderCreated": 1,
}))

aws-embedded-metrics-python 같은 SDK가 이걸 더 깔끔하게 도와줍니다.

Metric Filter: 로그에서 메트릭 만들기 #

이미 로그에 있는 정보 (ERROR 발생, 응답 시간 등)를 메트릭으로 변환.

콘솔에서 만들기
CloudWatch → Log groups → 그룹 선택 → Metric filters → Create
- Filter pattern: ERROR
- Metric namespace: MyApp
- Metric name: ErrorCount
- Metric value: 1

이제 ERROR가 한 번 발생할 때마다 메트릭이 +1씩 올라갑니다. 알람 / 대시보드에 활용할 수 있습니다.

Filter pattern 예
ERROR                       # ERROR 단어 포함
[..., level="ERROR", ...]   # 구조화된 로그의 필드
{ $.level = "ERROR" }       # JSON 로그의 키

CloudWatch Alarms #

메트릭이 임계를 넘으면 액션을 실행합니다. 알림의 본진입니다.

첫 알람: Lambda Errors #

콘솔
CloudWatch → Alarms → Create alarm
- Metric: AWS/Lambda → Errors → Function: my-function
- Statistic: Sum
- Period: 1 minute
- Threshold: > 0 for 1 datapoint within 5 minutes
- Action: SNS → 알림 토픽
- Name: lambda-my-function-errors

Alarm의 상태 #

상태의미
OK임계 안
ALARM임계 초과. 액션 발생
INSUFFICIENT_DATA데이터 부족. 새로 만든 경우 / 메트릭 안 옴

INSUFFICIENT_DATA를 알람 처리 (== 알림) 할지는 옵션입니다. 새 알람 평가 중에 자주 뜨는 상태라 일반적으론 무시합니다.

Composite Alarms #

여러 알람의 AND / OR로 조합합니다. “ALB 5xx ≥ 1% AND CPU > 80%” 같은 패턴.

조합 예
ALARM("alb-5xx") AND ALARM("ec2-high-cpu")

오탐을 줄이는 데 효과적입니다.

Alarm 액션 #

액션무엇
SNS Topic이메일 / Slack / SMS / Lambda 등으로 fanout
EC2 Action인스턴스 stop / terminate / reboot / recover
Auto ScalingASG 스케일 in / out
Systems ManagerOpsItem 만들기

운영의 90%는 SNS → Slack / 이메일입니다.

Anomaly Detection #

기준선 (band)을 자동으로 학습해 그 밖이면 알람을 울립니다. 트래픽 / CPU처럼 패턴이 있는 메트릭에 효과적입니다. 정적 임계값보다 오탐이 적습니다.

SNS 통합: 알림을 보내는 방법 #

대부분의 알람이 SNS Topic으로 가고, 거기서 다음 단계로 fanout.

구독어디로
Email이메일
HTTPSSlack incoming webhook
Lambda가공 후 다른 단계
SMS휴대폰 (드물게)
SQS큐로

Slack 연동: Lambda 패턴 #

직접 webhook으로 보내거나, AWS Chatbot으로.

Lambda: SNS → Slack 변환
import json, os, urllib.request

WEBHOOK = os.environ["SLACK_WEBHOOK"]

def handler(event, context):
    msg = json.loads(event["Records"][0]["Sns"]["Message"])
    payload = json.dumps({
        "text": f"🚨 *{msg['AlarmName']}*: {msg['NewStateValue']}",
        "blocks": [...]
    }).encode()
    req = urllib.request.Request(WEBHOOK, data=payload,
                                  headers={"Content-Type": "application/json"})
    urllib.request.urlopen(req)

고급 #4 API Gateway + Lambda, 고급 #5 EventBridge / SQS / SNS에서 더 깊게.

CloudWatch Dashboards #

팀 / 서비스별 핵심 지표를 한눈에 보는 위젯 페이지입니다. JSON으로 정의해 코드로 관리할 수 있습니다.

자주 만드는 대시보드 #

종류무엇
서비스 대시보드한 서비스의 핵심 메트릭 (요청, 지연, 에러, 인프라)
인프라 대시보드EC2/RDS의 CPU / 메모리 / 네트워크
비즈니스 대시보드가입 / 결제 / 주문 같은 비즈니스 메트릭
온콜 대시보드활성 알람 / 최근 사고 / 핵심 지표

위젯 종류 #

  • 메트릭 그래프 (line, stacked, number)
  • 로그 (Logs Insights 쿼리 결과)
  • 텍스트 (Markdown. 대시보드 안내)
  • Alarm status

좋은 대시보드 = “이 한 페이지를 30초 보면 시스템 상태를 안다.”

가입 직후 켜야 할 설정 #

이 시리즈가 끝나는 시점, 다음 설정들이 갖춰져 있어야 합니다.

항목어디서
새 로그 그룹에 retention 자동 적용콘솔 / EventBridge + Lambda
Lambda Errors 알람함수마다
RDS FreeStorageSpace 알람DB마다
ALB 5xx 알람LB마다
빌링 알람 (#3)계정 단위
GuardDuty findings 알람 (#6)계정 단위

이 6가지가 작은 운영의 알림 기반입니다.

자주 만나는 함정 #

1) 로그 retention 영구 #

가장 흔한 비용 사고입니다. 로그 그룹마다 retention을 명시하고 새 그룹은 자동화합니다. 이 한 줄이 비용을 절반 이상 절감합니다.

2) 고카디널리티 커스텀 메트릭 #

Dimensions: [{Name: 'UserId', Value: user_id}]. 사용자 1만 명이면 메트릭 1만 개 × 차원 조합. 한 달 $3000+. 사용자별은 로그 (Logs Insights)가 답.

3) Logs Insights 무제한 시간 쿼리 #

큰 로그 그룹에 시간 범위 안 정하면 GB 단위 스캔 비용. 항상 시간 범위 좁게.

4) Alarm의 Period 너무 짧음 #

1분 1 데이터포인트로 알람을 걸면 일시적 spike마다 알람이 폭주합니다. 보통 5분 / 3 데이터포인트 정도가 노이즈가 적당합니다.

5) Alarm 액션 안 붙임 #

알람을 만들고 SNS / 액션을 안 붙이면 콘솔에서만 빨갛게 됩니다. 아무도 모릅니다. 만들 때 액션을 같이 붙입니다.

6) 대시보드만 만들고 안 봄 #

만든 직후엔 모두 보지만 시간 지나면 잊힙니다. 온콜 / 일일 standup의 첫 체크 항목으로 정착시킵니다.

7) Metric Math 미사용 #

여러 메트릭의 비율 / 합계 / 변환을 계산할 수 있는 Metric Math. “5xx / 총 요청 = 에러율” 같은 계산입니다. 잘 쓰면 대시보드 / 알람이 훨씬 깔끔합니다.

정리 #

이번 글에서 잡은 것:

  • CloudWatch의 4가지 구성. Logs / Metrics / Alarms / Dashboards입니다.
  • Logs. 그룹 → 스트림 → 이벤트 구조입니다. retention을 가입 직후 설정하고, CloudWatch Agent로 EC2 로그를 수집합니다.
  • Logs Insights. fields / filter / stats / sort / parse + bin(5m)을 쓰고, 시간 범위를 좁게 잡습니다.
  • Metrics. AWS 서비스가 자동 송신합니다. 차원 / 통계 (Avg, p95, p99)를 쓰고, 고카디널리티 차원은 금지합니다.
  • Metric Filter. 로그에서 메트릭을 추출합니다 (ERROR 등).
  • EMF. Lambda에서 로그로 메트릭을 보냅니다 (put_metric_data 대안).
  • Alarms. 임계 + Period + Datapoints로 구성합니다. SNS / EC2 액션 / ASG, Composite / Anomaly를 씁니다.
  • SNS. 알람을 fanout합니다. Slack / 이메일 / Lambda로 보냅니다.
  • Dashboards. 서비스 / 인프라 / 비즈니스 / 온콜용으로 만듭니다.
  • 함정. retention 영구, 고카디널리티 차원, Insights 무제한 시간 쿼리, Period 너무 짧음, 액션 미연결, 대시보드 안 봄입니다.

다음 시리즈: AWS 중급 #

이로써 AWS 기초 7편이 끝났습니다. 콘솔 / 계정 / IAM / 비용 / CLI / SSO / 보안 / CloudWatch. AWS 위에서 무언가를 시작하는 데 필요한 도구상자가 한 곳에 모였습니다.

이제 진짜 자원을 만들 차례입니다. AWS 중급 7편은 백엔드 운영의 핵심 요소들을 정리하겠습니다.

AWS 중급 #1 EC2와 VPC 기초에서는 가상 머신 EC2, 그리고 그 EC2가 사는 가상 네트워크 VPC의 구조를 Subnet / Internet Gateway / Route Table / Security Group / NACL까지 한 줄에 정리하겠습니다.

X