Claude Code × AWS CloudWatch 완벽 가이드 | 로그 분석·알람 설정·대시보드 자동 구축
Claude Code로 AWS CloudWatch를 효율화하세요. 로그 패턴 분석·알람 자동 설정·메트릭 대시보드 구축·인시던트 조사까지 실전 코드로 해설합니다.
“프로덕션에서 에러가 났어요! 그런데 로그가 너무 많아서 어디를 봐야 할지 모르겠어요.” — 인시던트 대응에서 흔히 겪는 당혹스러운 상황입니다.
CloudWatch는 AWS의 표준 모니터링 서비스지만, 로그 양이 방대해서 핵심 정보가 묻히고 알람 설정도 뒤로 미루기 쉽습니다. 저는 업무에서 ECS + Lambda 시스템을 모니터링하고 있는데, Claude Code에 로그를 읽혀 원인을 특정시킴으로써 인시던트 대응 시간을 평균 40% 단축했습니다.
이 글에서는 CloudWatch 로그 분석·알람 설계·대시보드 구축을 Claude Code로 자동화하는 실전 절차를 해설합니다.
CloudWatch 주요 컴포넌트
CloudWatch Logs : 앱·AWS 서비스의 로그 저장·검색
CloudWatch Metrics : CPU 사용률·요청 수 등의 수치 데이터
CloudWatch Alarms : 메트릭 임계값 초과를 감지하여 SNS 등에 알림
CloudWatch Dashboards: 메트릭·로그를 시각화하는 커스텀 화면
Log Insights : 로그를 SQL 형태로 분석하는 쿼리 엔진
Step 1: 로그 패턴 분석을 Claude Code에 맡기기
인시던트 발생 시 먼저 “에러 로그의 패턴”을 파악하는 것이 중요합니다.
# 최근 1시간의 에러 로그 가져오기
aws logs filter-log-events \
--log-group-name "/ecs/myapp" \
--start-time $(date -d "1 hour ago" +%s000) \
--filter-pattern "ERROR" \
--output json > error-logs.json
claude -p "
다음 CloudWatch 에러 로그를 분석해줘:
1. 에러 종류별로 분류 (5xx, 4xx, DB 연결 에러, 타임아웃 등)
2. 가장 빈도가 높은 에러 특정
3. 에러가 급증한 시각 특정
4. 근본 원인 가설 제시
5. 조사해야 할 다음 액션 제안
$(cat error-logs.json | head -500)
"
Log Insights 쿼리 자동 생성
claude -p "
다음 목적의 CloudWatch Log Insights 쿼리를 생성해줘:
1. 최근 1시간의 엔드포인트별 에러율 (상위 10건)
2. 레이턴시가 500ms 이상인 요청의 상세
3. 특정 사용자 (user_id: 12345)의 모든 작업 로그
4. 배포 후 30분 이내에 발생한 최초 에러
로그 포맷: JSON (timestamp, level, message, user_id, endpoint, duration_ms, status_code)
"
생성되는 Log Insights 쿼리 예시:
-- 엔드포인트별 에러율
fields @timestamp, endpoint, status_code
| filter status_code >= 400
| stats count() as error_count by endpoint
| sort error_count desc
| limit 10
-- 레이턴시 500ms 초과 요청
fields @timestamp, endpoint, duration_ms, user_id
| filter duration_ms > 500
| sort duration_ms desc
| limit 50
-- 특정 사용자의 작업 로그
fields @timestamp, level, message, endpoint
| filter user_id = "12345"
| sort @timestamp desc
| limit 100
Step 2: 알람 설정 자동 생성
claude -p "
다음 시스템에 필요한 CloudWatch 알람을 모두 설계해줘.
CDK TypeScript로 구현할 것.
【시스템 구성】
- ECS Fargate (API 서버, 2~10대)
- RDS PostgreSQL
- ALB (Application Load Balancer)
- Lambda (배치 처리)
【알람 요건】
- 프로덕션 환경: 5분 이내에 알아챌 수 있는 알람 설정
- 알림처: SNS → Slack과 PagerDuty
- 단계적 알람 (Warning/Critical 2단계)
- 비즈니스 시간 외에는 Critical만 알림
"
// lib/monitoring-stack.ts
import * as cdk from "aws-cdk-lib";
import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch";
import * as actions from "aws-cdk-lib/aws-cloudwatch-actions";
import * as sns from "aws-cdk-lib/aws-sns";
export class MonitoringStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const alertTopic = sns.Topic.fromTopicArn(
this, "AlertTopic",
`arn:aws:sns:${this.region}:${this.account}:prod-alerts`
);
const warnTopic = sns.Topic.fromTopicArn(
this, "WarnTopic",
`arn:aws:sns:${this.region}:${this.account}:prod-warnings`
);
// ALB 5xx 에러율 알람
const alb5xxAlarm = new cloudwatch.Alarm(this, "Alb5xxAlarm", {
alarmName: "prod-alb-5xx-critical",
alarmDescription: "ALB 5xx 에러율이 5% 초과",
metric: new cloudwatch.Metric({
namespace: "AWS/ApplicationELB",
metricName: "HTTPCode_Target_5XX_Count",
dimensionsMap: { LoadBalancer: "app/myapp/xxx" },
statistic: "Sum",
period: cdk.Duration.minutes(5),
}),
threshold: 10,
evaluationPeriods: 2,
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
});
alb5xxAlarm.addAlarmAction(new actions.SnsAction(alertTopic));
// ECS CPU 사용률 알람 (Warning/Critical)
const ecsCpuWarning = new cloudwatch.Alarm(this, "EcsCpuWarning", {
alarmName: "prod-ecs-cpu-warning",
metric: new cloudwatch.Metric({
namespace: "AWS/ECS",
metricName: "CPUUtilization",
dimensionsMap: { ClusterName: "myapp-cluster", ServiceName: "myapp-service" },
statistic: "Average",
period: cdk.Duration.minutes(5),
}),
threshold: 70,
evaluationPeriods: 3,
});
ecsCpuWarning.addAlarmAction(new actions.SnsAction(warnTopic));
const ecsCpuCritical = new cloudwatch.Alarm(this, "EcsCpuCritical", {
alarmName: "prod-ecs-cpu-critical",
metric: new cloudwatch.Metric({
namespace: "AWS/ECS",
metricName: "CPUUtilization",
dimensionsMap: { ClusterName: "myapp-cluster", ServiceName: "myapp-service" },
statistic: "Average",
period: cdk.Duration.minutes(5),
}),
threshold: 90,
evaluationPeriods: 2,
});
ecsCpuCritical.addAlarmAction(new actions.SnsAction(alertTopic));
// RDS 연결 수 알람
const rdsConnectionAlarm = new cloudwatch.Alarm(this, "RdsConnectionAlarm", {
alarmName: "prod-rds-connections-critical",
metric: new cloudwatch.Metric({
namespace: "AWS/RDS",
metricName: "DatabaseConnections",
dimensionsMap: { DBInstanceIdentifier: "myapp-db" },
statistic: "Maximum",
period: cdk.Duration.minutes(5),
}),
threshold: 80, // db.t3.micro 최대 연결 수의 80%
evaluationPeriods: 2,
});
rdsConnectionAlarm.addAlarmAction(new actions.SnsAction(alertTopic));
// Lambda 에러율 알람
const lambdaErrorAlarm = new cloudwatch.Alarm(this, "LambdaErrorAlarm", {
alarmName: "prod-lambda-errors-critical",
metric: new cloudwatch.Metric({
namespace: "AWS/Lambda",
metricName: "Errors",
dimensionsMap: { FunctionName: "myapp-batch" },
statistic: "Sum",
period: cdk.Duration.minutes(15),
}),
threshold: 5,
evaluationPeriods: 1,
});
lambdaErrorAlarm.addAlarmAction(new actions.SnsAction(alertTopic));
}
}
Step 3: 커스텀 대시보드 자동 생성
claude -p "
다음 정보를 표시하는 CloudWatch 대시보드를 CDK로 생성해줘.
【대시보드 구성】
Row 1: 시스템 전체 헬스 (ALB 요청 수·5xx율·레이턴시 P50/P95/P99)
Row 2: ECS 서비스 (CPU·메모리·실행 태스크 수)
Row 3: RDS (연결 수·레이턴시·CPU 사용률)
Row 4: Lambda (실행 횟수·에러 수·실행 시간)
Row 5: 비즈니스 메트릭 (신규 가입 수·결제 성공률) ← 커스텀 메트릭
"
// 대시보드 정의 (발췌)
const dashboard = new cloudwatch.Dashboard(this, "AppDashboard", {
dashboardName: "myapp-production",
});
dashboard.addWidgets(
new cloudwatch.Row(
new cloudwatch.GraphWidget({
title: "ALB 요청 수",
left: [new cloudwatch.Metric({
namespace: "AWS/ApplicationELB",
metricName: "RequestCount",
statistic: "Sum",
period: cdk.Duration.minutes(1),
})],
width: 8,
}),
new cloudwatch.GraphWidget({
title: "ALB 5xx 에러율 (%)",
left: [new cloudwatch.MathExpression({
expression: "5xx / (2xx + 3xx + 4xx + 5xx) * 100",
usingMetrics: {
"5xx": new cloudwatch.Metric({ metricName: "HTTPCode_Target_5XX_Count", namespace: "AWS/ApplicationELB", statistic: "Sum" }),
"2xx": new cloudwatch.Metric({ metricName: "HTTPCode_Target_2XX_Count", namespace: "AWS/ApplicationELB", statistic: "Sum" }),
"3xx": new cloudwatch.Metric({ metricName: "HTTPCode_Target_3XX_Count", namespace: "AWS/ApplicationELB", statistic: "Sum" }),
"4xx": new cloudwatch.Metric({ metricName: "HTTPCode_Target_4XX_Count", namespace: "AWS/ApplicationELB", statistic: "Sum" }),
},
period: cdk.Duration.minutes(1),
})],
width: 8,
}),
)
);
Step 4: 인시던트 조사를 Claude Code에 맡기기
claude -p "
프로덕션 인시던트를 조사하고 싶어. 다음 커맨드를 실행해서 결과를 분석해줘:
1. aws logs filter-log-events --log-group-name '/ecs/myapp' \
--start-time \$(date -d '2 hours ago' +%s000) \
--filter-pattern 'ERROR' --limit 100
2. aws cloudwatch get-metric-statistics \
--namespace AWS/ApplicationELB \
--metric-name HTTPCode_Target_5XX_Count \
--start-time \$(date -d '2 hours ago' -u +%Y-%m-%dT%H:%M:%SZ) \
--end-time \$(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 300 --statistics Sum
위 결과를 바탕으로:
- 인시던트 발생 시각
- 영향받은 사용자 수 (추정)
- 근본 원인 가설 (TOP3)
- 즉시 대응 액션
을 정리해줘
"
Step 5: 커스텀 메트릭 자동 설계
claude -p "
EC 사이트의 비즈니스 KPI를 CloudWatch 커스텀 메트릭으로
Node.js (AWS SDK v3)로 측정하는 코드를 생성해줘.
측정할 메트릭:
- 결제 성공 수·실패 수 (1분마다)
- 카트 이탈율 (5분마다)
- 신규 회원 가입 수 (1시간마다)
네임스페이스: MyApp/Business
각 메트릭에 환경 태그 (Production/Staging) 부여
"
// src/monitoring/business-metrics.ts
import { CloudWatchClient, PutMetricDataCommand } from "@aws-sdk/client-cloudwatch";
const cw = new CloudWatchClient({ region: process.env.AWS_REGION });
const NAMESPACE = "MyApp/Business";
const ENV = process.env.NODE_ENV ?? "development";
export async function recordPaymentSuccess() {
await cw.send(new PutMetricDataCommand({
Namespace: NAMESPACE,
MetricData: [{
MetricName: "PaymentSuccess",
Value: 1,
Unit: "Count",
Dimensions: [{ Name: "Environment", Value: ENV }],
}],
}));
}
export async function recordPaymentFailure(reason: string) {
await cw.send(new PutMetricDataCommand({
Namespace: NAMESPACE,
MetricData: [{
MetricName: "PaymentFailure",
Value: 1,
Unit: "Count",
Dimensions: [
{ Name: "Environment", Value: ENV },
{ Name: "Reason", Value: reason },
],
}],
}));
}
주의할 함정 4가지
1. 알람의 evaluationPeriods가 너무 짧음
// ❌ 순간적인 스파이크에도 즉시 알람
evaluationPeriods: 1,
threshold: 10,
// ✅ 3기간 연속 초과 시에만 알람 (오탐 방지)
evaluationPeriods: 3,
threshold: 10,
datapointsToAlarm: 2, // 3기간 중 2회 초과 시 알람
2. Log Insights의 비용을 고려하지 않음
Log Insights는 스캔한 데이터 양에 따라 과금됩니다. 시간 범위를 좁히지 않고 실행하면 예상치 못한 요금이 발생합니다. --start-time --end-time을 반드시 지정하세요.
3. 커스텀 메트릭의 고해상도는 고비용
표준 메트릭 (60초)은 무료지만 고해상도 메트릭 (1초)은 비용이 약 10배입니다. 비즈니스 메트릭은 1분 집계로 충분한 경우가 많습니다.
4. Lambda의 로그 보존 기간을 설정하지 않음
기본값은 “무기한”이어서 스토리지 비용이 계속 증가합니다. 로그 그룹의 보존 기간을 반드시 설정하세요.
new logs.LogGroup(this, "AppLogGroup", {
logGroupName: "/ecs/myapp",
retention: logs.RetentionDays.ONE_MONTH, // 30일 후 자동 삭제
});
정리
| 태스크 | Claude Code의 기여 |
|---|---|
| 로그 분석 | 에러 로그를 읽어 원인 가설과 대응책 제시 |
| Log Insights 쿼리 | 분석 목적을 전달하기만 하면 쿼리 생성 |
| 알람 설정 | 시스템 구성을 전달하면 CDK 코드 일괄 생성 |
| 대시보드 | 표시하고 싶은 정보를 전달하면 위젯 정의 생성 |
| 인시던트 조사 | AWS CLI 커맨드를 실행시켜 결과 분석 |
“모니터링은 나중에 설정하자”고 미룬 결과, 인시던트 발생 시 아무것도 모르는 상황은 피하고 싶습니다. Claude Code를 사용하면 30분에 프로덕션 수준의 알람과 대시보드가 갖춰집니다.
관련 글
- Claude Code × AWS ECS/Fargate 완벽 가이드
- Claude Code × AWS CodePipeline/CodeBuild 완벽 가이드
- Claude Code × AWS IAM 완벽 가이드
참고 자료
Claude Code 워크플로우를 한 단계 업그레이드하세요
지금 바로 Claude Code에 복사해 쓸 수 있는 검증된 프롬프트 템플릿 50선.
무료 PDF: 5분 완성 Claude Code 치트시트
이메일 주소만 등록하시면 A4 한 장짜리 치트시트 PDF를 즉시 보내드립니다.
개인정보는 엄격하게 관리하며 스팸은 보내지 않습니다.
이 글을 작성한 사람
Masa
Claude Code를 적극 활용하는 엔지니어. 10개 언어, 2,000페이지 이상의 테크 미디어 claudecode-lab.com을 운영 중.
관련 글
Claude Code × Amazon Bedrock 완전 가이드 | AWS에서 Claude 프로덕션 운영하기
Claude Code로 Amazon Bedrock을 활용하는 완전 가이드. IAM 인증, 스트리밍, Lambda 통합, RAG 구현, 비용 최적화까지 — Masa의 실제 프로덕션 구현 경험을 바탕으로 해설.
Claude Code × AWS CodePipeline/CodeBuild 완전 가이드 | CI/CD 파이프라인 자동 구축
Claude Code로 AWS CodePipeline·CodeBuild CI/CD를 자동 구축. 파이프라인 설계·buildspec.yml 생성·테스트 자동화·CDK 인프라 정의까지 실전 코드로 해설.
Claude Code × AWS ECS/Fargate 완전 가이드 | 컨테이너 배포 자동화하기
Claude Code로 AWS ECS/Fargate 배포를 자동화하세요. 태스크 정의부터 서비스 설정, Blue/Green 배포, CDK 인프라 구축까지 — Masa의 실무 경험을 바탕으로 해설합니다.