Use Cases

Claude Code × AWS CloudWatch Komplettanleitung | Log-Analyse, Alarme & Dashboard-Automatisierung

AWS CloudWatch mit Claude Code effizienter nutzen. Praxisnaher Code für Log-Musteranalyse, automatische Alarmkonfiguration, Metriken-Dashboards und Incident-Untersuchung.

„Im Produktivsystem ist ein Fehler aufgetreten! Aber die Logs sind so umfangreich, dass ich nicht weiß, wo ich anfangen soll.” — Das ist ein typisches Stressgefühl bei der Incident-Bearbeitung.

CloudWatch ist der Standard-Monitoring-Dienst von AWS, doch bei riesigen Log-Mengen gehen kritische Informationen unter, und die Alarmkonfiguration wird gerne aufgeschoben. Ich überwache bei der Arbeit ein ECS-+Lambda-System und habe festgestellt, dass Claude Code die Logs liest und die Ursache eingrenzt — das hat unsere durchschnittliche Incident-Bearbeitungszeit um 40 % reduziert.

Dieser Artikel erklärt praxisnah, wie man Log-Analyse, Alarmdesign und Dashboard-Erstellung in CloudWatch mit Claude Code automatisiert.


Wichtigste CloudWatch-Komponenten

CloudWatch Logs      : Speichern und Durchsuchen von App- und AWS-Service-Logs
CloudWatch Metrics   : Numerische Daten wie CPU-Auslastung und Anfragezahlen
CloudWatch Alarms    : Schwellenwertüberschreitungen erkennen und SNS usw. benachrichtigen
CloudWatch Dashboards: Benutzerdefinierte Ansichten zur Visualisierung von Metriken und Logs
Log Insights         : SQL-ähnliche Query-Engine zur Log-Analyse

Schritt 1: Log-Musteranalyse an Claude Code delegieren

Während eines Incidents ist es als erstes wichtig, das Muster der Fehlerlogs zu verstehen.

# Fehlerlogs der letzten Stunde abrufen
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 "
Analysiere die folgenden CloudWatch-Fehlerlogs und:

1. Klassifiziere Fehler nach Typ (5xx, 4xx, DB-Verbindungsfehler, Timeouts usw.)
2. Identifiziere den häufigsten Fehler
3. Bestimme den Zeitpunkt, zu dem Fehler sprunghaft angestiegen sind
4. Stelle Hypothesen zur Grundursache auf
5. Schlage nächste Untersuchungsschritte vor

$(cat error-logs.json | head -500)
"

Log-Insights-Abfragen automatisch generieren

claude -p "
Generiere CloudWatch Log Insights-Abfragen für folgende Zwecke:

1. Fehlerrate pro Endpunkt der letzten Stunde (Top 10)
2. Details zu Anfragen mit Latenz über 500 ms
3. Alle Aktivitätslogs eines bestimmten Nutzers (user_id: 12345)
4. Erstmals aufgetretene Fehler innerhalb von 30 Minuten nach einem Deployment

Log-Format: JSON (timestamp, level, message, user_id, endpoint, duration_ms, status_code)
"

Beispiel einer generierten Log-Insights-Abfrage:

-- Fehlerrate pro Endpunkt
fields @timestamp, endpoint, status_code
| filter status_code >= 400
| stats count() as error_count by endpoint
| sort error_count desc
| limit 10

-- Anfragen mit Latenz über 500 ms
fields @timestamp, endpoint, duration_ms, user_id
| filter duration_ms > 500
| sort duration_ms desc
| limit 50

-- Aktivitätslogs eines bestimmten Nutzers
fields @timestamp, level, message, endpoint
| filter user_id = "12345"
| sort @timestamp desc
| limit 100

Schritt 2: Alarmkonfiguration automatisch generieren

claude -p "
Entwirf alle erforderlichen CloudWatch-Alarme für das folgende System.
Implementierung in CDK TypeScript.

[Systemarchitektur]
- ECS Fargate (API-Server, 2–10 Instanzen)
- RDS PostgreSQL
- ALB (Application Load Balancer)
- Lambda (Batch-Verarbeitung)

[Alarm-Anforderungen]
- Produktion: Alarme, die innerhalb von 5 Minuten ausgelöst werden
- Benachrichtigungsziele: SNS → Slack und PagerDuty
- Zweistufige Alarme (Warning / Critical)
- Außerhalb der Geschäftszeiten: nur 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-Fehlerrate-Alarm
    const alb5xxAlarm = new cloudwatch.Alarm(this, "Alb5xxAlarm", {
      alarmName: "prod-alb-5xx-critical",
      alarmDescription: "ALB-5xx-Fehlerrate hat 5 % überschritten",
      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-Auslastungs-Alarm (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-Verbindungsanzahl-Alarm
    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,  // 80 % der maximalen Verbindungen von db.t3.micro
      evaluationPeriods: 2,
    });
    rdsConnectionAlarm.addAlarmAction(new actions.SnsAction(alertTopic));

    // Lambda-Fehlerrate-Alarm
    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));
  }
}

Schritt 3: Benutzerdefiniertes Dashboard automatisch generieren

claude -p "
Erstelle ein CloudWatch-Dashboard in CDK, das folgende Informationen anzeigt.

[Dashboard-Layout]
Zeile 1: Gesamtsystemstatus (ALB-Anfragezahl, 5xx-Rate, Latenz P50/P95/P99)
Zeile 2: ECS-Service (CPU, Speicher, laufende Task-Anzahl)
Zeile 3: RDS (Verbindungen, Latenz, CPU-Auslastung)
Zeile 4: Lambda (Aufrufe, Fehler, Ausführungsdauer)
Zeile 5: Business-Metriken (Neuregistrierungen, Zahlungserfolgsrate) ← benutzerdefinierte Metriken
"
// Dashboard-Definition (Auszug)
const dashboard = new cloudwatch.Dashboard(this, "AppDashboard", {
  dashboardName: "myapp-production",
});

dashboard.addWidgets(
  new cloudwatch.Row(
    new cloudwatch.GraphWidget({
      title: "ALB-Anfragezahl",
      left: [new cloudwatch.Metric({
        namespace: "AWS/ApplicationELB",
        metricName: "RequestCount",
        statistic: "Sum",
        period: cdk.Duration.minutes(1),
      })],
      width: 8,
    }),
    new cloudwatch.GraphWidget({
      title: "ALB-5xx-Fehlerrate (%)",
      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,
    }),
  )
);

Schritt 4: Incident-Untersuchung an Claude Code delegieren

claude -p "
Ich möchte einen Produktions-Incident untersuchen. Führe folgende Befehle aus und analysiere die Ergebnisse:

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

Fasse auf Basis der obigen Ergebnisse zusammen:
- Startzeitpunkt des Incidents
- Geschätzte Anzahl betroffener Nutzer
- Top-3-Hypothesen zur Grundursache
- Sofortmaßnahmen
"

Schritt 5: Benutzerdefinierte Metriken automatisch entwerfen

claude -p "
Generiere Node.js-Code (AWS SDK v3), um folgende E-Commerce-Business-KPIs
als benutzerdefinierte CloudWatch-Metriken zu messen.

Zu messende Metriken:
- Anzahl erfolgreicher und fehlgeschlagener Zahlungen (jede Minute)
- Warenkorbabbruchrate (alle 5 Minuten)
- Neuanmeldungen (stündlich)

Namespace: MyApp/Business
Jede Metrik mit Umgebungs-Tag versehen (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 häufige Stolperfallen

1. evaluationPeriods ist zu kurz

// ❌ Alarm löst bei jedem kurzzeitigen Spike aus
evaluationPeriods: 1,
threshold: 10,

// ✅ Alarm löst nur nach 3 aufeinanderfolgenden Überschreitungen aus (weniger Fehlalarme)
evaluationPeriods: 3,
threshold: 10,
datapointsToAlarm: 2,  // Alarm, wenn Schwellenwert in 2 von 3 Perioden überschritten wird

2. Log-Insights-Kosten nicht berücksichtigt

Log Insights berechnet Kosten nach der Menge der gescannten Daten. Abfragen ohne Zeiteinschränkung können zu unerwarteten Rechnungen führen. Immer --start-time und --end-time angeben.

3. Hochauflösende benutzerdefinierte Metriken sind teuer

Standardmetriken (60 Sekunden) sind kostenlos, hochauflösende Metriken (1 Sekunde) kosten etwa das 10-Fache. Für Business-Metriken reicht 1-Minuten-Aggregation in den meisten Fällen aus.

4. Keine Log-Aufbewahrungsfrist für Lambda festgelegt

Die Standardeinstellung ist „Nie ablaufen”, wodurch Speicherkosten kontinuierlich steigen. Immer eine Aufbewahrungsfrist für Log-Gruppen festlegen.

new logs.LogGroup(this, "AppLogGroup", {
  logGroupName: "/ecs/myapp",
  retention: logs.RetentionDays.ONE_MONTH,  // Automatisches Löschen nach 30 Tagen
});

Zusammenfassung

AufgabeClaude Code-Beitrag
Log-AnalyseLiest Fehlerlogs und schlägt Grundursachen-Hypothesen mit Lösungsschritten vor
Log-Insights-AbfragenGeneriert Abfragen aus einer einfachen Beschreibung des Analyseziels
AlarmkonfigurationGeneriert CDK-Code aus einer Systembeschreibung
DashboardGeneriert Widget-Definitionen aus einer Beschreibung der gewünschten Anzeige
Incident-UntersuchungFührt AWS-CLI-Befehle aus und analysiert die Ergebnisse

„Monitoring richten wir später ein” — und dann trifft ein Incident ein und man hat keine Sichtbarkeit. Mit Claude Code hat man in 30 Minuten produktionsreife Alarme und Dashboards bereit.

Verwandte Artikel

Referenzen

#claude-code #aws #cloudwatch #monitoring #observability #devops

Bring deinen Claude-Code-Workflow aufs nächste Level

50 in der Praxis erprobte Prompt-Vorlagen zum direkten Copy-and-paste in Claude Code.

Kostenlos

Kostenloses PDF: Claude-Code-Spickzettel in 5 Minuten

Trag einfach deine E-Mail-Adresse ein – wir senden dir den A4-Spickzettel als PDF sofort zu.

Wir behandeln deine Daten sorgfältig und senden niemals Spam.

Masa

Über den Autor

Masa

Ingenieur, der Claude Code intensiv nutzt. Betreibt claudecode-lab.com, ein Tech-Medium in 10 Sprachen mit über 2.000 Seiten.