cloudwatch について
AWS リソースやアプリケーションを監視する開発者・運用担当者向けの CloudWatch リファレンススキルです。メトリクス、ログ、アラーム、ダッシュボードを扱い、AWS CLI と boto3 の例や設定上の注意、問題の診断方法を示します。
主な機能
- 01メトリクスの発行と取得
- 02ログ検索と Insights クエリの実行
- 03メトリクス・ログアラームの設定
- 04ダッシュボードとメトリクスフィルターの作成
- 05アラーム・ログ・コストの調査
活用シーン
- 01EC2 や Lambda のメトリクス監視
- 02アプリケーションログからエラーを検索
- 03しきい値やログクエリに対するアラーム設定
- 04メトリクス欠落や予期しないアラーム状態の診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ itsmostafa/ aws-agent-skills --skill cloudwatchインストール後、Claude Code で/cloudwatchを入力して読み込まれたか確認します。
同梱ファイルalarms-metrics.md
詳細
AWS CloudWatch
Amazon CloudWatch は、AWS リソースとアプリケーションの監視と可観測性を提供します。メトリクス、ログ、イベントを収集し、AWS 環境の監視、トラブルシューティング、最適化を可能にします。
目次
主要な概念
メトリクス
CloudWatch に公開される、時系列順のデータポイントです。主な構成要素は次のとおりです。
- 名前空間:メトリクスのコンテナです(例:
AWS/Lambda) - メトリクス名:測定項目の名前です(例:
Invocations) - ディメンション:フィルタリングに使用する名前と値のペアです(例:
FunctionName=MyFunc) - 統計情報:集計値です(Sum、Average、Min、Max、SampleCount、pN)
ログ
AWS サービスやアプリケーションのログデータです。
- ロググループ:ログストリームの集合です
- ログストリーム:同じソースからのログイベントの連続です
- ログイベント:タイムスタンプとメッセージを含む個々のログエントリです
アラーム
メトリクスのしきい値に基づく自動アクションです。
- 状態:OK、ALARM、INSUFFICIENT_DATA
- アクション:SNS 通知、Lambda 関数、Auto Scaling、EC2 アクション、Systems Manager OpsItems
- タイプ:メトリクス(メトリクス数学、異常検出、Metrics Insights を含む)、複合、ログ(スケジュールされた Logs Insights クエリの結果を M-out-of-N で評価)
- ミュートルール:アラームの評価は継続しながら、アクションをミュートするスケジュール済みの時間帯です
一般的なパターン
メトリクスアラームを作成する
AWS CLI:
# CPU utilization alarm for EC2
aws cloudwatch put-metric-alarm \
--alarm-name "HighCPU-i-1234567890abcdef0" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:alerts \
--ok-actions arn:aws:sns:us-east-1:123456789012:alerts
boto3:
import boto3
cloudwatch = boto3.client('cloudwatch')
cloudwatch.put_metric_alarm(
AlarmName='HighCPU-i-1234567890abcdef0',
MetricName='CPUUtilization',
Namespace='AWS/EC2',
Statistic='Average',
Period=300,
Threshold=80.0,
ComparisonOperator='GreaterThanThreshold',
EvaluationPeriods=2,
Dimensions=[
{'Name': 'InstanceId', 'Value': 'i-1234567890abcdef0'}
],
AlarmActions=['arn:aws:sns:us-east-1:123456789012:alerts'],
OKActions=['arn:aws:sns:us-east-1:123456789012:alerts']
)
Lambda エラー率アラーム
aws cloudwatch put-metric-alarm \
--alarm-name "LambdaErrorRate-MyFunction" \
--metrics '[
{
"Id": "errors",
"MetricStat": {
"Metric": {
"Namespace": "AWS/Lambda",
"MetricName": "Errors",
"Dimensions": [{"Name": "FunctionName", "Value": "MyFunction"}]
},
"Period": 60,
"Stat": "Sum"
},
"ReturnData": false
},
{
"Id": "invocations",
"MetricStat": {
"Metric": {
"Namespace": "AWS/Lambda",
"MetricName": "Invocations",
"Dimensions": [{"Name": "FunctionName", "Value": "MyFunction"}]
},
"Period": 60,
"Stat": "Sum"
},
"ReturnData": false
},
{
"Id": "errorRate",
"Expression": "errors/invocations*100",
"Label": "Error Rate",
"ReturnData": true
}
]' \
--threshold 5 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 3 \
--alarm-actions arn:aws:sns:us-east-1:123456789012:alerts
Insights でログをクエリする
# Find errors in Lambda logs
aws logs start-query \
--log-group-name /aws/lambda/MyFunction \
--start-time $(date -d '1 hour ago' +%s) \
--end-time $(date +%s) \
--query-string '
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 50
'
# Get query results
aws logs get-query-results --query-id <query-id>
boto3:
import boto3
import time
logs = boto3.client('logs')
# Start query
response = logs.start_query(
logGroupName='/aws/lambda/MyFunction',
startTime=int(time.time()) - 3600,
endTime=int(time.time()),
queryString='''
fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 50
'''
)
query_id = response['queryId']
# Wait for results
while True:
result = logs.get_query_results(queryId=query_id)
if result['status'] == 'Complete':
break
time.sleep(1)
for row in result['results']:
print(row)
メトリクスフィルターを作成する
ログパターンからメトリクスを抽出します。
# Create metric filter for error count
aws logs put-metric-filter \
--log-group-name /aws/lambda/MyFunction \
--filter-name ErrorCount \
--filter-pattern "ERROR" \
--metric-transformations \
metricName=ErrorCount,metricNamespace=MyApp,metricValue=1,defaultValue=0
ログアラームを作成する
Logs Insights クエリを直接対象にしてアラームを作成します(メトリクスフィルターは不要です)。CloudWatch は、基盤となるスケジュール済みクエリを作成して管理します。ScheduledQueryRoleARN ロールでは、logs.amazonaws.com を信頼し、ロググループ ARN に対する logs:StartQuery と logs:GetQueryResults、さらに "Resource": "*" に対する logs:StopQuery と logs:DescribeLogGroups を許可する必要があります(この2つはリソースレベルのアクセス許可に対応していないため、ロググループを対象としたステートメントでは一致しません)。
# ALARM when >100 errors in 3 of the last 5 query runs
aws cloudwatch put-log-alarm \
--alarm-name "HighErrorCount" \
--comparison-operator GreaterThanThreshold \
--threshold 100 \
--query-results-to-evaluate 5 \
--query-results-to-alarm 3 \
--treat-missing-data notBreaching \
--alarm-actions arn:aws:sns:us-east-1:123456789012:alerts \
--scheduled-query-configuration '{
"QueryString": "fields @timestamp, @message | filter @message like /ERROR/",
"LogGroupIdentifiers": ["/aws/lambda/MyFunction"],
"ScheduledQueryRoleARN": "arn:aws:iam::123456789012:role/ScheduledQueryRole",
"AggregationExpression": "count(*)",
"ScheduleConfiguration": {
"ScheduleExpression": "rate(10 minutes)",
"StartTimeOffset": 600
}
}'
# Log alarms are omitted from describe-alarms unless requested
aws cloudwatch describe-alarms --alarm-types LogAlarm
カスタムメトリクスを公開する
import boto3
cloudwatch = boto3.client('cloudwatch')
cloudwatch.put_metric_data(
Namespace='MyApp',
MetricData=[
{
'MetricName': 'OrdersProcessed',
'Value': 1,
'Unit': 'Count',
'Dimensions': [
{'Name': 'Environment', 'Value': 'Production'},
{'Name': 'OrderType', 'Value': 'Standard'}
]
}
]
)
ダッシュボードを作成する
cat > dashboard.json << 'EOF'
{
"widgets": [
{
"type": "metric",
"x": 0, "y": 0, "width": 12, "height": 6,
"properties": {
"title": "Lambda Invocations",
"metrics": [
["AWS/Lambda", "Invocations", "FunctionName", "MyFunction"]
],
"period": 60,
"stat": "Sum",
"region": "us-east-1"
}
},
{
"type": "log",
"x": 12, "y": 0, "width": 12, "height": 6,
"properties": {
"title": "Recent Errors",
"query": "SOURCE '/aws/lambda/MyFunction' | filter @message like /ERROR/ | limit 20",
"region": "us-east-1"
}
}
]
}
EOF
aws cloudwatch put-dashboard \
--dashboard-name MyAppDashboard \
--dashboard-body file://dashboard.json
CLI リファレンス
メトリクスのコマンド
| コマンド | 説明 |
|---|---|
aws cloudwatch put-metric-data | カスタムメトリクスを公開する |
aws cloudwatch get-metric-data | メトリクス値を取得する |
aws cloudwatch get-metric-statistics | 集計された統計情報を取得する |
aws cloudwatch list-metrics | 利用可能なメトリクスを一覧表示する |
アラームのコマンド
| コマンド | 説明 |
|---|---|
aws cloudwatch put-metric-alarm | アラームを作成または更新する |
aws cloudwatch put-log-alarm | ログクエリアラームを作成または更新する |
aws cloudwatch describe-alarms | アラームを一覧表示する(ログアラームには --alarm-types LogAlarm を指定) |
aws cloudwatch describe-alarm-contributors | 複数のコントリビューターがいるアラームで、違反しているコントリビューターを表示する |
aws cloudwatch put-alarm-mute-rule | スケジュール済みのミュート時間帯を作成または更新する |
aws cloudwatch list-alarm-mute-rules | ミュートルールを一覧表示する(--statuses SCHEDULED ACTIVE EXPIRED) |
aws cloudwatch delete-alarm-mute-rule | ミュートルールを削除する(直ちにミュートを解除) |
aws cloudwatch set-alarm-state | アラームの状態を手動で設定する |
aws cloudwatch delete-alarms | アラームを削除する |
ログのコマンド
| コマンド | 説明 |
|---|---|
aws logs create-log-group | ロググループを作成する |
aws logs put-log-events | ログイベントを書き込む |
aws logs filter-log-events | ログイベントを検索する |
aws logs start-query | Insights クエリを開始する |
aws logs put-metric-filter | メトリクスフィルターを作成する |
aws logs put-retention-policy | ログの保持期間を設定する |
ベストプラクティス
メトリクス
- ディメンションは慎重に使用する — 多すぎるとメトリクスが爆発的に増加します
- 公開前に集計する — カスタムメトリクスはバッチ処理します
- 高解像度メトリクス(1 秒)は必要な場合にのみ使用します
- カスタムメトリクスには適切な単位を設定する
アラーム
- 複雑な条件には複合アラームを使用する
- アラーム状態の頻繁な切り替わりを避けるため、適切な評価期間を設定する
- 復旧を追跡できるよう、OK アクションを含める
- 動的なしきい値には異常検出を使用する
- クエリベースの条件では、メトリクスフィルターとメトリクスアラームの組み合わせではなく、ログアラームを使用する。まばらに発生するエラーには
--treat-missing-data notBreachingを設定し、ログの到着停止を検出するにはbreachingを設定します - ログアラームのスケジュールをずらす — アカウントごとの同時スケジュール済みクエリ実行数は 100 件に制限されています
- 新しいリソースと同時に作成するアラームには
--warm-up-configurationを設定する(1~2880 分)。メトリクスが公開される前のノイズを避けられます - 日次/週次のバッチ処理やバックアップのアラームには
--evaluation-window WallClockWindow={Timezone=...}を使用する。Auto Scaling ではデフォルトのスライディングウィンドウを維持します - メンテナンスには
disable-alarm-actionsではなくミュートルールを使用する。enable-alarm-actionsを実行しても、アクティブなミュートルールは解除されません
ログ
- 保持ポリシーを設定する — ログを無期限に保持しないでください
- クエリを改善するため、構造化ロギング(JSON)を使用する
- 重要なイベントにはメトリクスフィルターを作成する
- 上位 N 件の分析にはContributor Insights を使用する
コストの最適化
- 使用していないダッシュボードを削除する
- 重要度の低いログの保持期間を短縮する
- 必要がない限り、高解像度メトリクスを避ける
- ポーリングではなく、ログサブスクリプションフィルターを使用する
トラブルシューティング
メトリクスが見つからない
原因:
- サービスがまだ公開していない(1~5 分待ちます)
- 名前空間/ディメンションが正しくない
- 詳細モニタリングが有効になっていない(EC2)
デバッグ:
# List metrics for a namespace
aws cloudwatch list-metrics \
--namespace AWS/Lambda \
--dimensions Name=FunctionName,Value=MyFunction
アラームが INSUFFICIENT_DATA のままになる
原因:
- メトリクスが公開されていない
- ディメンションが一致していない
- 評価期間が短すぎる
- ウォームアップ期間がまだ有効(
OnlyStartEvaluatingAfterWarmUpPeriodEnds=trueを指定していない場合、ウィンドウにデータが揃うと早期に終了します) - ログアラームの場合:作成/更新したばかり(クエリ、スケジュール、またはロググループの変更によって状態がリセットされます)、スケジュール済みクエリのロールに権限がない(
EvaluationState=EVALUATION_ERROR。StateReasonを確認してください)、または取り込みに遅延がある(EndTimeOffsetでウィンドウを後ろにずらします)
デバッグ:
# Check if metric has data
aws cloudwatch get-metric-statistics \
--namespace AWS/Lambda \
--metric-name Invocations \
--dimensions Name=FunctionName,Value=MyFunction \
--start-time $(date -d '1 hour ago' -u +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 60 \
--statistics Sum
# Log alarm: check evaluation state and reason
aws cloudwatch describe-alarms --alarm-types LogAlarm --alarm-names HighErrorCount \
--query 'LogAlarms[].[StateValue,EvaluationState,StateReason]'
ログイベントが表示されない
原因:
- IAM 権限がない
- CloudWatch Logs エージェントが実行されていない
- ロググループが存在しない
デバッグ:
# Check log streams
aws logs describe-log-streams \
--log-group-name /aws/lambda/MyFunction \
--order-by LastEventTime \
--descending \
--limit 5
CloudWatch のコストが高い
使用状況を確認する:
# Get PutLogEvents usage
aws cloudwatch get-metric-statistics \
--namespace AWS/Logs \
--metric-name IncomingBytes \
--dimensions Name=LogGroupName,Value=/aws/lambda/MyFunction \
--start-time $(date -d '7 days ago' -u +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--period 86400 \
--statistics Sum