CloudWatch完全ガイド
CloudWatch完全ガイド
Section titled “CloudWatch完全ガイド”CloudWatchは、AWSリソースの監視とログ管理サービスです。実務で使える監視設定とアラートを詳しく解説します。
1. CloudWatchとは
Section titled “1. CloudWatchとは”CloudWatchの役割
Section titled “CloudWatchの役割”CloudWatchは、AWSリソースのメトリクス収集、ログ管理、アラートを提供する監視サービスです。
AWSリソース(EC2、Lambda、RDSなど) ↓(メトリクス・ログを送信)CloudWatch ├─ メトリクス(CPU、メモリ、リクエスト数など) ├─ ログ(アプリケーションログ、システムログ) └─ アラーム(閾値超過時の通知)なぜCloudWatchが必要か
Section titled “なぜCloudWatchが必要か”問題のある構成(CloudWatchなし):
# 問題: 手動での監視# 1. サーバーにSSH接続# 2. ログを確認# 3. リソース使用状況を確認# 4. 問題を手動で検知
# 問題点:# 1. リアルタイム監視が困難# 2. 自動アラートがない# 3. 履歴データの保存が困難# 4. 複数リソースの監視が困難解決: CloudWatchによる自動監視
# 解決: CloudWatchによる自動監視Resources: CPUAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: HighCPUUtilization MetricName: CPUUtilization Threshold: 80 AlarmActions: - !Ref SNSTopic
# メリット:# 1. リアルタイム監視(自動的にメトリクスを収集)# 2. 自動アラート(閾値超過時に自動通知)# 3. 履歴データの保存(15か月間保持)# 4. 複数リソースの監視(統合ダッシュボード)2. CloudWatchメトリクス
Section titled “2. CloudWatchメトリクス”標準メトリクス
Section titled “標準メトリクス”EC2:- CPUUtilization- NetworkIn/NetworkOut- DiskReadOps/DiskWriteOps
RDS:- CPUUtilization- DatabaseConnections- ReadLatency/WriteLatency
Lambda:- Invocations- Duration- Errors- Throttlesカスタムメトリクス
Section titled “カスタムメトリクス”// Node.jsでのカスタムメトリクス送信const AWS = require('aws-sdk');const cloudwatch = new AWS.CloudWatch();
cloudwatch.putMetricData({ Namespace: 'MyApplication', MetricData: [ { MetricName: 'RequestCount', Value: 100, Unit: 'Count', Timestamp: new Date(), Dimensions: [ { Name: 'Environment', Value: 'Production' }, { Name: 'API', Value: 'users' } ] }, { MetricName: 'ResponseTime', Value: 250, Unit: 'Milliseconds', Timestamp: new Date(), Dimensions: [ { Name: 'Environment', Value: 'Production' } ] } ]}, (err, data) => { if (err) console.error(err); else console.log('Metrics sent:', data);});Pythonでの実装
Section titled “Pythonでの実装”import boto3from datetime import datetime
cloudwatch = boto3.client('cloudwatch')
cloudwatch.put_metric_data( Namespace='MyApplication', MetricData=[ { 'MetricName': 'RequestCount', 'Value': 100, 'Unit': 'Count', 'Timestamp': datetime.utcnow(), 'Dimensions': [ { 'Name': 'Environment', 'Value': 'Production' } ] } ])3. CloudWatch Logs
Section titled “3. CloudWatch Logs”ロググループとログストリーム
Section titled “ロググループとログストリーム”Resources: LogGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: /aws/lambda/my-function RetentionInDays: 30
LogStream: Type: AWS::Logs::LogStream Properties: LogGroupName: !Ref LogGroup LogStreamName: stream1アプリケーションからのログ送信
Section titled “アプリケーションからのログ送信”// Node.jsでのログ送信const AWS = require('aws-sdk');const logs = new AWS.CloudWatchLogs();
// ロググループの作成logs.createLogGroup({ logGroupName: '/myapp/application'}, (err, data) => { if (err && err.code !== 'ResourceAlreadyExistsException') { console.error(err); }});
// ログストリームの作成logs.createLogStream({ logGroupName: '/myapp/application', logStreamName: 'stream1'}, (err, data) => { if (err && err.code !== 'ResourceAlreadyExistsException') { console.error(err); }});
// ログイベントの送信logs.putLogEvents({ logGroupName: '/myapp/application', logStreamName: 'stream1', logEvents: [ { message: 'Application started', timestamp: Date.now() }, { message: 'User logged in: user123', timestamp: Date.now() } ]}, (err, data) => { if (err) console.error(err); else console.log('Logs sent:', data);});Lambda関数のログ
Section titled “Lambda関数のログ”import loggingimport json
logger = logging.getLogger()logger.setLevel(logging.INFO)
def lambda_handler(event, context): logger.info('Event received: %s', json.dumps(event))
try: # 処理 result = process_event(event) logger.info('Processing successful: %s', result) return { 'statusCode': 200, 'body': json.dumps(result) } except Exception as e: logger.error('Error occurred: %s', str(e), exc_info=True) return { 'statusCode': 500, 'body': json.dumps({'error': str(e)}) }4. CloudWatchアラーム
Section titled “4. CloudWatchアラーム”基本的なアラーム
Section titled “基本的なアラーム”Resources: HighCPUAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: HighCPUUtilization AlarmDescription: Alert when CPU utilization exceeds 80% MetricName: CPUUtilization Namespace: AWS/EC2 Statistic: Average Period: 300 EvaluationPeriods: 2 Threshold: 80 ComparisonOperator: GreaterThanThreshold Dimensions: - Name: InstanceId Value: !Ref EC2Instance AlarmActions: - !Ref SNSTopic OKActions: - !Ref SNSTopic TreatMissingData: notBreaching
SNSTopic: Type: AWS::SNS::Topic Properties: TopicName: AlertsTopic Subscription: - Protocol: email Endpoint: admin@example.com複合アラーム
Section titled “複合アラーム”Resources: CPUAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: HighCPU MetricName: CPUUtilization Threshold: 80 ComparisonOperator: GreaterThanThreshold
MemoryAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: HighMemory MetricName: MemoryUtilization Threshold: 90 ComparisonOperator: GreaterThanThreshold
CompositeAlarm: Type: AWS::CloudWatch::CompositeAlarm Properties: AlarmName: CriticalSystemAlarm AlarmRule: !Sub 'ALARM(${CPUAlarm}) OR ALARM(${MemoryAlarm})' AlarmActions: - !Ref SNSTopicメトリクス数式アラーム
Section titled “メトリクス数式アラーム”Resources: CustomMetricAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmName: HighErrorRate Metrics: - Id: m1 MetricStat: Metric: Namespace: MyApplication MetricName: Errors Stat: Sum Period: 60 - Id: m2 MetricStat: Metric: Namespace: MyApplication MetricName: Requests Stat: Sum Period: 60 - Id: e1 Expression: 'm1 / m2 * 100' Label: ErrorRate Threshold: 5 ComparisonOperator: GreaterThanThreshold EvaluationPeriods: 25. CloudWatch Logs Insights
Section titled “5. CloudWatch Logs Insights”基本的なクエリ
Section titled “基本的なクエリ”-- エラーログの検索fields @timestamp, @message| filter @message like /ERROR/| sort @timestamp desc| limit 20高度なクエリ
Section titled “高度なクエリ”-- エラーログの分析fields @timestamp, @message, @logStream| filter @message like /ERROR/| parse @message "ERROR: *" as errorMessage| stats count() by errorMessage| sort count desc| limit 10パフォーマンス分析
Section titled “パフォーマンス分析”-- レスポンスタイムの分析fields @timestamp, @message| parse @message "ResponseTime: * ms" as responseTime| stats avg(responseTime), max(responseTime), min(responseTime) by bin(5m)ユーザーアクティビティ分析
Section titled “ユーザーアクティビティ分析”-- ユーザーアクティビティの分析fields @timestamp, @message| parse @message "User * logged in" as userId| stats count() by userId| sort count desc| limit 106. CloudWatchダッシュボード
Section titled “6. CloudWatchダッシュボード”ダッシュボードの作成
Section titled “ダッシュボードの作成”Resources: Dashboard: Type: AWS::CloudWatch::Dashboard Properties: DashboardName: MyDashboard DashboardBody: !Sub | { "widgets": [ { "type": "metric", "properties": { "metrics": [ ["AWS/EC2", "CPUUtilization", "InstanceId", "${EC2Instance}"], [".", "NetworkIn", ".", "."], [".", "NetworkOut", ".", "."] ], "period": 300, "stat": "Average", "region": "${AWS::Region}", "title": "EC2 Metrics" } }, { "type": "log", "properties": { "query": "SOURCE '/aws/lambda/my-function' | fields @timestamp, @message\n| filter @message like /ERROR/\n| sort @timestamp desc\n| limit 20", "region": "${AWS::Region}", "title": "Error Logs" } } ] }7. 実務でのベストプラクティス
Section titled “7. 実務でのベストプラクティス”パターン1: アプリケーションメトリクス
Section titled “パターン1: アプリケーションメトリクス”// カスタムメトリクスの送信const metrics = { requestCount: 0, errorCount: 0, responseTime: []};
// リクエスト処理後metrics.requestCount++;metrics.responseTime.push(responseTime);
// エラー発生時metrics.errorCount++;
// 定期的にメトリクスを送信(例: 1分ごと)setInterval(() => { cloudwatch.putMetricData({ Namespace: 'MyApplication', MetricData: [ { MetricName: 'RequestCount', Value: metrics.requestCount, Unit: 'Count' }, { MetricName: 'ErrorCount', Value: metrics.errorCount, Unit: 'Count' }, { MetricName: 'ResponseTime', Value: calculateAverage(metrics.responseTime), Unit: 'Milliseconds' } ] });
// リセット metrics.requestCount = 0; metrics.errorCount = 0; metrics.responseTime = [];}, 60000);パターン2: 構造化ログ
Section titled “パターン2: 構造化ログ”// 構造化ログの送信const logData = { timestamp: new Date().toISOString(), level: 'INFO', message: 'User logged in', userId: 'user123', ipAddress: '192.168.1.1', requestId: 'req-123'};
console.log(JSON.stringify(logData));8. よくある問題と解決策
Section titled “8. よくある問題と解決策”問題1: メトリクスが表示されない
Section titled “問題1: メトリクスが表示されない”原因:
- メトリクスの送信が失敗している
- 名前空間が間違っている
解決策:
# メトリクスの確認aws cloudwatch list-metrics \ --namespace MyApplication
# メトリクス統計の取得aws cloudwatch get-metric-statistics \ --namespace MyApplication \ --metric-name RequestCount \ --start-time 2024-01-01T00:00:00Z \ --end-time 2024-01-01T23:59:59Z \ --period 3600 \ --statistics Average問題2: アラームが発火しない
Section titled “問題2: アラームが発火しない”原因:
- 閾値が適切でない
- 評価期間が長すぎる
解決策:
# アラームの状態を確認aws cloudwatch describe-alarms --alarm-names HighCPUUtilization
# アラーム履歴の確認aws cloudwatch describe-alarm-history \ --alarm-name HighCPUUtilization \ --start-date 2024-01-01T00:00:00Zこれで、CloudWatchの基礎知識と実務での監視設定を理解できるようになりました。