Dashboards

Dashboards gestalten

Wenn Vorlagen und KI-Widgets nicht reichen, kannst du mit einem CloudWatch-Dashboard deine Metriken auf einem großen Bildschirm auswählen, mit der Metrikauswahl, den Metrikberechnungen und den Schwellenwerten von CloudWatch, und sie in CloudFormation oder Terraform pflegen.

Aktualisiert am 19. Oktober 2026

Warum ein Dashboard?

Du brauchst kein Dashboard, um CloudPeek zu nutzen: Vorlagen und KI-Widgets funktionieren ohne. Ein Dashboard lohnt sich, wenn du genau auswählen willst, welche Metriken du beobachtest: deine eigenen benutzerdefinierten Metriken, bestimmte Ressourcen, Metrikberechnungen, Schwellenwerte oder ausgewählte Alarme. Den richtigen Namespace und die richtigen Dimensionen finden, Metrikberechnungen schreiben und Schwellenwerte festlegen geht mit Tastatur und großem Bildschirm viel leichter, und CloudWatch hat das Werkzeug dafür schon.

Ein CloudWatch-Dashboard ist dann einfach deine Liste dessen, was du beobachten willst:

  • Jedes Widget ist etwas, das du anheften kannst. Ein Widget gruppiert eine oder mehrere Metriken: die CPU von drei Instances in einem Liniendiagramm, deine fünf größten Kosten in einem Balkendiagramm, eine aus zwei Metriken berechnete Fehlerrate in einer Zahl.
  • Jedes Dashboard ist eine Gruppe zusammengehöriger Widgets. Eines pro Service, eines für die Ausgaben, eines für die Rufbereitschaft. Du kannst aus beliebig vielen Dashboards und Konten anheften.
  • Ein Dashboard ist einfaches JSON und lässt sich daher in CloudFormation, Terraform, dem AWS CDK oder allem anderen definieren, das einen String schreiben kann, und zusammen mit den Services bereitstellen, die es überwacht.

Du hast schon Dashboards? Hefte direkt daraus an. Oder erstelle ein kleines nur für dein Smartphone, mit genau den Widgets, die du auf einen Blick sehen willst.

In der AWS-Konsole gestalten

  1. Öffne die CloudWatch-Konsole, wähle Dashboards › Dashboard erstellen und gib ihm einen Namen.
  2. Wähle einen Widget-Typ: Linie, Gestapelte Fläche, Zahl, Messanzeige, Balken, Kreis, Tabelle, Text oder Alarmstatus. Alle funktionieren in CloudPeek (siehe die Widget-Referenz).
  3. Wähle im Tab Durchsuchen einen Namespace, z. B. ApplicationELB oder einen eigenen, und markiere dann die Metriken, die du in diesem Widget haben willst.
  4. Lege im Tab Grafisch dargestellte Metriken für jede Metrik Statistik, Zeitraum und Beschriftung fest. Wähle Mathematik hinzufügen für einen Ausdruck wie eine Fehlerrate und entferne das Häkchen bei den Eingaben, die nicht gezeichnet werden sollen.
  5. Füge im Tab Optionen horizontale Anmerkungen für Schwellenwerte hinzu und lege die Grenzen der Y-Achse fest. Eine Messanzeige braucht sowohl ein Minimum als auch ein Maximum.
  6. Wähle Widget erstellen, gib dem Widget einen kurzen Titel und speichere das Dashboard mit Speichern.

Öffne das Dashboard in CloudPeek, und jedes Widget wird so dargestellt, wie es auf deinem Home-Bildschirm aussehen wird. Hefte die gewünschten an oder füge sie mit Widget erstellen › Aus einem Dashboard hinzu (siehe Widget erstellen).

Gut lesbar auf dem Smartphone

Ein Widget auf deinem Home-Bildschirm ist nur ein paar Zentimeter breit. Mit ein paar Gewohnheiten wird es viel leichter lesbar:

  • Eine Frage pro Widget. „Ist die API in Ordnung?“ lässt sich als Fehlerraten-Zahl und Latenz-Messanzeige besser ablesen als in einem Diagramm mit acht Linien.
  • Wenige Datenreihen pro Diagramm. Auf mittleren und großen Widgets listet die Legende bis zu vier Datenreihen auf, danach „+N weitere“. Ein kleines Widget hat gar keine Legende.
  • Kurze Titel. Auf iPhone und iPad zeigt das Inline-Widget des Sperrbildschirms etwa 18 Zeichen des Titels, das runde etwa 8.
  • Wähle die Ansicht, die auf einen Blick antwortet. Eine Zahl mit "sparkline": true zeigt den aktuellen Wert und seinen Trend, eine Messanzeige zeigt ihn in einem von dir festgelegten Bereich, ein Balkendiagramm bringt Dinge in eine Rangfolge. Sieh dir an, wie die einzelnen Typen aussehen.
  • Lege den Zeitbereich fest, der dich interessiert. Der eigene start-Wert eines Widgets hat Vorrang vor dem des Dashboards; fehlen beide, zeigt CloudPeek die letzten 3 Stunden. Jedes Widget gibt an, welchen Zeitbereich es abdeckt.
  • Beschriftungen statt IDs. Gib Metriken ein label, damit in der Legende „Checkout API“ statt „app/checkout-api/50dc6c495c0c9188“ steht. Eine dynamische Beschriftung wie ${PROP('Dim.ServiceName')} benennt jede Datenreihe nach dem Wert einer Dimension.

Beispiel: Dashboard zum API-Zustand

Drei Widgets für einen Application Load Balancer: die Fehlerrate als Zahl, die p99-Latenz als Messanzeige und Anfragen im Vergleich zu Fehlern als Liniendiagramm. In CloudPeek sehen sie so aus:

Die Fehlerrate wird aus zwei ausgeblendeten Metriken berechnet; die 5xx-Linie hat rechts eine eigene Skala.
api-health.jsonHerunterladen
{
  "start": "-PT3H",
  "widgets": [
    {
      "type": "metric",
      "x": 0,
      "y": 0,
      "width": 6,
      "height": 6,
      "properties": {
        "title": "5xx error rate",
        "view": "singleValue",
        "region": "us-east-1",
        "period": 300,
        "sparkline": true,
        "metrics": [
          [ { "expression": "100 * FILL(m2, 0) / m1", "label": "Errors (%)", "id": "e1" } ],
          [ "AWS/ApplicationELB", "RequestCount", "LoadBalancer", "app/checkout-api/50dc6c495c0c9188", { "stat": "Sum", "id": "m1", "visible": false } ],
          [ ".", "HTTPCode_Target_5XX_Count", ".", ".", { "stat": "Sum", "id": "m2", "visible": false } ]
        ]
      }
    },
    {
      "type": "metric",
      "x": 6,
      "y": 0,
      "width": 6,
      "height": 6,
      "properties": {
        "title": "Latency p99",
        "view": "gauge",
        "region": "us-east-1",
        "stat": "p99",
        "period": 300,
        "yAxis": { "left": { "min": 0, "max": 2 } },
        "metrics": [
          [ "AWS/ApplicationELB", "TargetResponseTime", "LoadBalancer", "app/checkout-api/50dc6c495c0c9188", { "label": "p99 (s)" } ]
        ]
      }
    },
    {
      "type": "metric",
      "x": 12,
      "y": 0,
      "width": 12,
      "height": 6,
      "properties": {
        "title": "Requests and errors",
        "view": "timeSeries",
        "region": "us-east-1",
        "stat": "Sum",
        "period": 300,
        "metrics": [
          [ "AWS/ApplicationELB", "RequestCount", "LoadBalancer", "app/checkout-api/50dc6c495c0c9188", { "label": "Requests" } ],
          [ ".", "HTTPCode_Target_5XX_Count", ".", ".", { "label": "5xx", "yAxis": "right", "color": "#d62728" } ]
        ]
      }
    }
  ]
}
  • Fehlerrate: Der Ausdruck 100 * FILL(m2, 0) / m1 teilt die 5xx-Antworten durch die Anfragen. FILL zählt einen Zeitraum ohne Fehler als null, statt eine Lücke zu lassen. Beide Eingaben haben "visible": false, sodass nur die Rate angezeigt wird.
  • Latenz: Eine Messanzeige verwendet min und max der Y-Achse als Bereich (hier 0 bis 2 Sekunden). Ohne sie nimmt CloudPeek 0 bis 100 an.
  • Anfragen und Fehler: "yAxis": "right" gibt der 5xx-Anzahl eine eigene Skala, damit eine Handvoll Fehler neben Tausenden von Anfragen nicht zur flachen Linie wird. "." wiederholt den Wert, der in der Zeile darüber an derselben Stelle steht.
  • Ersetze app/checkout-api/50dc6c495c0c9188 durch den Namen deines Load Balancers aus seinem ARN (der Teil nach loadbalancer/) oder lass CloudFormation oder Terraform ihn einsetzen, wie unten gezeigt.

Als Code verwalten

Gestalte ein Dashboard in der Konsole, bis es passt, und kopiere dann sein JSON über Aktionen › Quelle anzeigen/bearbeiten in deinen Infrastrukturcode. Von da an wird es zusammen mit den Services, die es überwacht, geprüft, versioniert und bereitgestellt, und es ist in jedem Konto und jeder Region gleich, in die du bereitstellst.

Du musst Dashboards nicht in Code ablegen. Ein Dashboard, das du in der Konsole bearbeitest, übernimmt CloudPeek genauso beim nächsten Aktualisieren.

Wird ein Dashboard mit CloudFormation oder Terraform verwaltet, betrachte die Konsole als Skizzenblock: Änderungen, die du dort speicherst, werden beim nächsten Deployment überschrieben. Probiere eine Idee in der Konsole aus und kopiere die Quelle dann zurück in deinen Code (Aktionen › Quelle anzeigen/bearbeiten).

Lege das JSON in der Versionsverwaltung ab und stelle es mit put-dashboard bereit. So startest du mit einem Dashboard, das du in der Konsole gestaltet hast:

Shell
aws cloudwatch get-dashboard \
  --dashboard-name Checkout-API \
  --query DashboardBody --output text > api-health.json

aws cloudwatch put-dashboard \
  --dashboard-name Checkout-API \
  --dashboard-body file://api-health.json

put-dashboard ersetzt das gesamte Dashboard, die Datei beschreibt also immer den vollständigen Stand.

Eine AWS::CloudWatch::Dashboard-Ressource nimmt das JSON als String entgegen. Schließt du es in !Sub ein, kannst du Werte aus demselben Stack einsetzen, etwa die Dimension des Load Balancers, statt IDs einzufügen:

CloudFormation
  CheckoutApiDashboard:
    Type: AWS::CloudWatch::Dashboard
    Properties:
      DashboardName: Checkout-API
      DashboardBody: !Sub
        - |
          {
            "start": "-PT3H",
            "widgets": [
              {
                "type": "metric", "x": 0, "y": 0, "width": 6, "height": 6,
                "properties": {
                  "title": "5xx error rate",
                  "view": "singleValue",
                  "region": "${AWS::Region}",
                  "period": 300,
                  "sparkline": true,
                  "metrics": [
                    [ { "expression": "100 * FILL(m2, 0) / m1", "label": "Errors (%)", "id": "e1" } ],
                    [ "AWS/ApplicationELB", "RequestCount", "LoadBalancer", "${Alb}", { "stat": "Sum", "id": "m1", "visible": false } ],
                    [ ".", "HTTPCode_Target_5XX_Count", ".", ".", { "stat": "Sum", "id": "m2", "visible": false } ]
                  ]
                }
              },
              {
                "type": "metric", "x": 6, "y": 0, "width": 6, "height": 6,
                "properties": {
                  "title": "Latency p99",
                  "view": "gauge",
                  "region": "${AWS::Region}",
                  "stat": "p99",
                  "period": 300,
                  "yAxis": { "left": { "min": 0, "max": 2 } },
                  "metrics": [
                    [ "AWS/ApplicationELB", "TargetResponseTime", "LoadBalancer", "${Alb}", { "label": "p99 (s)" } ]
                  ]
                }
              },
              {
                "type": "metric", "x": 12, "y": 0, "width": 12, "height": 6,
                "properties": {
                  "title": "Requests and errors",
                  "view": "timeSeries",
                  "region": "${AWS::Region}",
                  "stat": "Sum",
                  "period": 300,
                  "metrics": [
                    [ "AWS/ApplicationELB", "RequestCount", "LoadBalancer", "${Alb}", { "label": "Requests" } ],
                    [ ".", "HTTPCode_Target_5XX_Count", ".", ".", { "label": "5xx", "yAxis": "right", "color": "#d62728" } ]
                  ]
                }
              }
            ]
          }
        - Alb: !GetAtt LoadBalancer.LoadBalancerFullName
  • LoadBalancer ist die AWS::ElasticLoadBalancingV2::LoadBalancer-Ressource im selben Template; ihr LoadBalancerFullName ist genau der Wert, den die CloudWatch-Dimension LoadBalancer erwartet.
  • Innerhalb von !Sub liest CloudFormation jedes ${…} als eigene Variable. Schreib eine dynamische CloudWatch-Beschriftung wie ${LAST} als ${!LAST}.
  • Dashboards sind global, aber jedes Widget gibt seine Region an. ${AWS::Region} verwendet die Region des Stacks.

Eine aws_cloudwatch_dashboard-Ressource nimmt das JSON als String entgegen. Schreibst du es in HCL und schließt es in jsonencode ein, kannst du Referenzen, Variablen und for-Ausdrücke verwenden, statt IDs einzufügen:

Terraform
resource "aws_lb" "checkout" {
  name    = "checkout-api"
  subnets = ["subnet-11111111", "subnet-22222222"]
}

locals {
  alb    = aws_lb.checkout.arn_suffix # the LoadBalancer dimension: app/checkout-api/…
  region = "us-east-1"                # where the load balancer is
}

resource "aws_cloudwatch_dashboard" "checkout_api" {
  dashboard_name = "Checkout-API"
  dashboard_body = jsonencode({
    start = "-PT3H"
    widgets = [
      {
        type = "metric", x = 0, y = 0, width = 6, height = 6
        properties = {
          title     = "5xx error rate"
          view      = "singleValue"
          region    = local.region
          period    = 300
          sparkline = true
          metrics = [
            [{ expression = "100 * FILL(m2, 0) / m1", label = "Errors (%)", id = "e1" }],
            ["AWS/ApplicationELB", "RequestCount", "LoadBalancer", local.alb, { stat = "Sum", id = "m1", visible = false }],
            [".", "HTTPCode_Target_5XX_Count", ".", ".", { stat = "Sum", id = "m2", visible = false }],
          ]
        }
      },
      {
        type = "metric", x = 6, y = 0, width = 6, height = 6
        properties = {
          title  = "Latency p99"
          view   = "gauge"
          region = local.region
          stat   = "p99"
          period = 300
          yAxis  = { left = { min = 0, max = 2 } }
          metrics = [
            ["AWS/ApplicationELB", "TargetResponseTime", "LoadBalancer", local.alb, { label = "p99 (s)" }],
          ]
        }
      },
      {
        type = "metric", x = 12, y = 0, width = 12, height = 6
        properties = {
          title  = "Requests and errors"
          view   = "timeSeries"
          region = local.region
          stat   = "Sum"
          period = 300
          metrics = [
            ["AWS/ApplicationELB", "RequestCount", "LoadBalancer", local.alb, { label = "Requests" }],
            [".", "HTTPCode_Target_5XX_Count", ".", ".", { label = "5xx", yAxis = "right", color = "#d62728" }],
          ]
        }
      },
    ]
  })
}
  • arn_suffix einer aws_lb-Ressource ist genau der Wert, den die CloudWatch-Dimension LoadBalancer erwartet.
  • Terraform liest ${…} in einem String als Interpolation. Schreib eine dynamische CloudWatch-Beschriftung wie ${LAST} als $${LAST}.
  • Willst du das JSON lieber als Datei behalten? dashboard_body = file("api-health.json") funktioniert auch, oder templatefile(), um Werte einzusetzen.
  • Um ein Dashboard, das du in der Konsole erstellt hast, unter die Verwaltung von Terraform zu bringen, füge einen import-Block mit seinem Namen als id hinzu oder führe terraform import aws_cloudwatch_dashboard.checkout_api Checkout-API aus.

Das AWS CDK, Pulumi und andere Tools funktionieren genauso: Alles, was den Inhalt eines Dashboards festlegen kann, kann bestimmen, was CloudPeek anzeigt.

Wie Änderungen auf dein Smartphone kommen

  • Jedes Mal, wenn ein angeheftetes Widget von AWS aktualisiert wird, liest CloudPeek das Dashboard neu. Eine Änderung, die du in der Konsole speicherst oder per Code bereitstellst, erscheint also beim nächsten Aktualisieren. Um sie sofort zu sehen, tippe im Widget auf die Schaltfläche zum Aktualisieren.
  • Widgets in CloudPeek folgen ihrem Dashboard-Widget, wenn du es verschiebst oder seine Größe, seinen Titel oder seine Metriken änderst. Kann CloudPeek nicht erkennen, welches Widget es war, zeigt es weiter die zuletzt gefundene Version.
  • Ein Titel oder eine Region, die du ihm in der Vorschau von Widget erstellen gegeben hast, und ein Titel, eine Region oder ein Zeitbereich, den du in CloudPeek mit Bearbeiten gewählt hast, bleiben erhalten und werden auf den jeweiligen Stand des Dashboards angewendet (siehe Widget bearbeiten).
  • Wenn du das Dashboard löschst oder umbenennst, behält das Widget seine letzten Daten und zeigt Dashboard gelöscht.
  • Fügst du dasselbe Widget erneut hinzu, werden alle Home-Bildschirm-Widgets, die es gezeigt haben, wieder verbunden (siehe Dasselbe Widget erneut hinzufügen).