mcpField
C
cloudwatch

cloudwatch

github.com/itsmostafaクラウド・DevOps1.2k243 回インストール2 日前に更新
リポジトリ

cloudwatch について

AWS リソースやアプリケーションを監視する開発者・運用担当者向けの CloudWatch リファレンススキルです。メトリクス、ログ、アラーム、ダッシュボードを扱い、AWS CLI と boto3 の例や設定上の注意、問題の診断方法を示します。

主な機能

  1. 01メトリクスの発行と取得
  2. 02ログ検索と Insights クエリの実行
  3. 03メトリクス・ログアラームの設定
  4. 04ダッシュボードとメトリクスフィルターの作成
  5. 05アラーム・ログ・コストの調査

活用シーン

  1. 01EC2 や Lambda のメトリクス監視
  2. 02アプリケーションログからエラーを検索
  3. 03しきい値やログクエリに対するアラーム設定
  4. 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-queryInsights クエリを開始する
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

参考資料

コメント