Tableaux de bord

Concevoir des tableaux de bord

Quand les préréglages et les widgets IA ne suffisent pas, un tableau de bord CloudWatch vous permet de choisir vos métriques sur un grand écran, avec le sélecteur de métriques, les calculs et les seuils de CloudWatch, et de les gérer dans CloudFormation ou Terraform.

Mis à jour le 19 octobre 2026

Pourquoi un tableau de bord ?

Vous n’avez pas besoin de tableau de bord pour utiliser CloudPeek : les préréglages et les widgets IA fonctionnent sans. Un tableau de bord en vaut la peine quand vous voulez choisir exactement quelles métriques surveiller : vos propres métriques personnalisées, des ressources particulières, des calculs de métriques, des seuils ou les alarmes de votre choix. Trouver le bon espace de noms et les bonnes dimensions, écrire des calculs de métriques et définir des seuils est bien plus simple avec un clavier et un grand écran, et CloudWatch dispose déjà de l’outil pour cela.

Un tableau de bord CloudWatch devient alors tout simplement votre liste de ce qu’il faut surveiller :

  • Chaque widget est un élément que vous pouvez épingler. Un widget regroupe une ou plusieurs métriques : le CPU de trois instances sur un graphique linéaire, vos cinq plus gros coûts sur un graphique à barres, un taux d’erreur calculé à partir de deux métriques dans un nombre.
  • Chaque tableau de bord est un ensemble de widgets qui vont ensemble. Un par service, un pour les dépenses, un pour l’astreinte. Vous pouvez épingler depuis autant de tableaux de bord et de comptes que vous le souhaitez.
  • Un tableau de bord n’est que du JSON : il peut donc être défini dans CloudFormation, Terraform, l’AWS CDK ou tout autre outil capable d’écrire une chaîne de caractères, et déployé avec les services qu’il surveille.

Vous avez déjà des tableaux de bord ? Épinglez directement à partir de ceux-ci. Ou créez-en un petit uniquement pour votre téléphone, avec seulement les widgets que vous voulez voir en un coup d’œil.

Le concevoir dans la console AWS

  1. Ouvrez la console CloudWatch, choisissez Tableaux de bord › Créer un tableau de bord et nommez-le.
  2. Choisissez un type de widget : Ligne, Aires empilées, Nombre, Jauge, Barres, Secteurs, Tableau, Texte ou État des alarmes. Ils fonctionnent tous dans CloudPeek (consultez la référence des widgets).
  3. Dans l’onglet Parcourir, choisissez un espace de noms, comme ApplicationELB ou l’un des vôtres, puis cochez les métriques que vous voulez sur ce widget.
  4. Dans l’onglet Métriques représentées graphiquement, définissez la statistique, la période et le libellé de chaque métrique. Choisissez Ajouter une expression mathématique pour une expression comme un taux d’erreur, et décochez les entrées que vous ne voulez pas tracer.
  5. Dans l’onglet Options, ajoutez des annotations horizontales pour les seuils et définissez les limites de l’axe Y. Une jauge a besoin à la fois d’un minimum et d’un maximum.
  6. Choisissez Créer un widget, donnez-lui un titre court, puis enregistrez le tableau de bord avec Enregistrer.

Ouvrez le tableau de bord dans CloudPeek : chaque widget y est dessiné tel qu’il apparaîtra sur votre écran d’accueil. Épinglez ceux que vous voulez, ou ajoutez-les avec Créer un widget › Depuis un tableau de bord (voir Créer un widget).

Le rendre lisible sur un téléphone

Sur votre écran d’accueil, un widget ne mesure que quelques centimètres. Quelques habitudes le rendent bien plus lisible :

  • Une question par widget. « L’API est-elle en bonne santé ? » se lit mieux avec un nombre pour le taux d’erreur et une jauge pour la latence qu’avec un seul graphique à huit lignes.
  • Peu de séries par graphique. Sur les widgets moyens et grands, la légende liste jusqu’à quatre séries, puis « +N de plus ». Un petit widget n’a pas de légende du tout.
  • Des titres courts. Sur iPhone et iPad, le widget en ligne de l’écran verrouillé garde environ 18 caractères du titre, et le widget circulaire environ 8.
  • Choisissez la vue adaptée au coup d’œil. Un nombre avec "sparkline": true affiche la dernière valeur et sa tendance ; une jauge la situe dans une plage que vous définissez ; un graphique à barres établit un classement. Voyez à quoi ressemble chaque type.
  • Définissez la plage qui vous intéresse. Le start propre à un widget remplace celui du tableau de bord, et sans l’un ni l’autre, CloudPeek affiche les 3 dernières heures. Chaque widget indique la période qu’il couvre.
  • Des libellés plutôt que des ID. Donnez un label aux métriques, pour que la légende affiche « Checkout API » plutôt que « app/checkout-api/50dc6c495c0c9188 ». Un libellé dynamique comme ${PROP('Dim.ServiceName')} nomme chaque série d’après la valeur d’une dimension.

Exemple : un tableau de bord de santé d’une API

Trois widgets pour un Application Load Balancer : le taux d’erreur sous forme de nombre, la latence p99 sous forme de jauge, et les requêtes face aux erreurs sur un graphique linéaire. Dans CloudPeek, ils se présentent ainsi :

Le taux d’erreur est calculé à partir de deux métriques masquées ; la ligne des 5xx a sa propre échelle, à droite.
api-health.jsonTélécharger
{
  "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" } ]
        ]
      }
    }
  ]
}
  • Taux d’erreur : l’expression 100 * FILL(m2, 0) / m1 divise les réponses 5xx par les requêtes. FILL compte une période sans erreur comme zéro au lieu de laisser un trou. Les deux entrées ont "visible": false, si bien que seul le taux est affiché.
  • Latence : une jauge prend le min et le max de l’axe Y comme plage (de 0 à 2 secondes ici). Sans eux, CloudPeek suppose une plage de 0 à 100.
  • Requêtes et erreurs : "yAxis": "right" donne au nombre de 5xx sa propre échelle, pour qu’une poignée d’erreurs ne soit pas écrasée par des milliers de requêtes. "." reprend la valeur placée au même endroit sur la ligne précédente.
  • Remplacez app/checkout-api/50dc6c495c0c9188 par le nom de votre équilibreur de charge, tel qu’il figure dans son ARN après loadbalancer/, ou laissez CloudFormation ou Terraform le renseigner, comme ci-dessous.

Le gérer en tant que code

Concevez un tableau de bord dans la console jusqu’à ce qu’il vous convienne, puis copiez son JSON depuis Actions › Afficher/modifier la source dans votre code d’infrastructure. Dès lors, il est relu, versionné et déployé avec les services qu’il surveille, et il est identique dans chaque compte et chaque région où vous le déployez.

Rien ne vous oblige à mettre vos tableaux de bord dans du code. Un tableau de bord que vous modifiez dans la console est tout aussi bien pris en compte par CloudPeek à sa prochaine actualisation.

Si un tableau de bord est géré par CloudFormation ou Terraform, considérez la console comme un brouillon : les modifications que vous y enregistrez sont écrasées au déploiement suivant. Essayez une idée dans la console, puis recopiez la source dans votre code (Actions › Afficher/modifier la source).

Conservez le JSON dans votre gestionnaire de versions et déployez-le avec put-dashboard. Pour partir d’un tableau de bord conçu dans la console :

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 remplace tout le tableau de bord, si bien que le fichier en est toujours la description complète.

Une ressource AWS::CloudWatch::Dashboard prend le JSON sous forme de chaîne. Enveloppez-le dans !Sub et vous pourrez y insérer des valeurs de la même pile, comme la dimension de l’équilibreur de charge, au lieu de coller des ID :

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 est la ressource AWS::ElasticLoadBalancingV2::LoadBalancer du même modèle ; son LoadBalancerFullName est exactement la valeur qu’attend la dimension LoadBalancer de CloudWatch.
  • Dans !Sub, CloudFormation lit chaque ${…} comme l’une de ses propres variables. Écrivez un libellé dynamique CloudWatch comme ${LAST} sous la forme ${!LAST}.
  • Les tableaux de bord sont globaux, mais chaque widget indique sa région. ${AWS::Region} reprend celle de la pile.

Une ressource aws_cloudwatch_dashboard prend le JSON sous forme de chaîne. Écrivez-le en HCL dans un jsonencode, et vous pourrez utiliser des références, des variables et des expressions for au lieu de coller des ID :

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" }],
          ]
        }
      },
    ]
  })
}
  • L’attribut arn_suffix d’un aws_lb est exactement la valeur qu’attend la dimension LoadBalancer de CloudWatch.
  • Terraform lit ${…} dans une chaîne comme une interpolation. Écrivez un libellé dynamique CloudWatch comme ${LAST} sous la forme $${LAST}.
  • Vous préférez garder le JSON dans un fichier ? dashboard_body = file("api-health.json") fonctionne aussi, ou templatefile() pour y insérer des valeurs.
  • Pour faire gérer par Terraform un tableau de bord créé dans la console, ajoutez un bloc import avec son nom comme id, ou exécutez terraform import aws_cloudwatch_dashboard.checkout_api Checkout-API.

L’AWS CDK, Pulumi et d’autres outils fonctionnent de la même façon : tout ce qui peut définir le corps d’un tableau de bord peut définir ce qu’affiche CloudPeek.

Comment les modifications arrivent sur votre téléphone

  • Chaque fois qu’un widget épinglé s’actualise depuis AWS, CloudPeek relit le tableau de bord : une modification enregistrée dans la console ou déployée depuis votre code apparaît donc à l’actualisation suivante. Pour la voir tout de suite, touchez le bouton d’actualisation du widget.
  • Les widgets de CloudPeek suivent leur widget de tableau de bord quand vous le déplacez, le redimensionnez, le renommez ou modifiez ses métriques. Si CloudPeek ne parvient pas à savoir de quel widget il s’agissait, il continue d’afficher la dernière version trouvée.
  • Un titre ou une région que vous lui avez donnés dans l’aperçu de Créer un widget, ainsi qu’un titre, une région ou une plage de temps choisis avec Modifier dans CloudPeek, sont conservés et appliqués à ce que contient le tableau de bord (voir Modifier un widget).
  • Si vous supprimez ou renommez le tableau de bord, le widget conserve ses dernières données et affiche Tableau de bord supprimé.
  • Ajouter à nouveau le même widget reconnecte les widgets de l’écran d’accueil qui l’affichaient (voir Ajouter à nouveau le même widget).