# Fichier: aws_cheats/cheatsheets/cloudwatch.txt
# Cheatsheet AWS CloudWatch - Guide Complet pour Débutants

═══════════════════════════════════════════════════════════════════════════════
[OK] CLOUDWATCH - MONITORING, LOGS & ALARMES
═══════════════════════════════════════════════════════════════════════════════

CloudWatch = Service AWS de monitoring et observabilité
- Collecter des métriques (CPU, RAM, réseau, custom...)
- Stocker et analyser des logs
- Créer des alarmes et notifications
- Créer des dashboards de visualisation

═══════════════════════════════════════════════════════════════════════════════
[OK] MÉTRIQUES - COLLECTER & CONSULTER
═══════════════════════════════════════════════════════════════════════════════

# === LISTER LES MÉTRIQUES DISPONIBLES ===

# Lister toutes les métriques EC2
aws cloudwatch list-metrics --namespace AWS/EC2

# Lister toutes les métriques d'un service spécifique
aws cloudwatch list-metrics --namespace AWS/RDS
aws cloudwatch list-metrics --namespace AWS/Lambda
aws cloudwatch list-metrics --namespace AWS/S3
aws cloudwatch list-metrics --namespace AWS/ELB

# Namespaces AWS courants:
# AWS/EC2          - Instances EC2
# AWS/RDS          - Bases de données
# AWS/Lambda       - Fonctions serverless
# AWS/S3           - Stockage objet
# AWS/ELB          - Load balancers
# AWS/DynamoDB     - Base NoSQL
# AWS/Billing      - Facturation
# Custom/MyApp     - Vos métriques personnalisées

# Lister une métrique spécifique
aws cloudwatch list-metrics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization

# Lister métriques avec dimension spécifique
aws cloudwatch list-metrics \
  --namespace AWS/EC2 \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0

# Lister avec filtre sur nom de métrique
aws cloudwatch list-metrics \
  --namespace AWS/EC2 \
  --metric-name NetworkIn

# Lister récemment utilisées
aws cloudwatch list-metrics \
  --recently-active PT3H    # Dernières 3 heures


# === CONSULTER LES STATISTIQUES ===

# Obtenir CPU moyen des 5 dernières minutes
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time 2024-01-15T10:00:00Z \
  --end-time 2024-01-15T10:05:00Z \
  --period 300 \
  --statistics Average

# Statistiques disponibles:
# Average      - Moyenne
# Sum          - Somme
# Minimum      - Valeur minimale
# Maximum      - Valeur maximale
# SampleCount  - Nombre d'échantillons

# Obtenir plusieurs statistiques en même temps
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time 2024-01-15T10:00:00Z \
  --end-time 2024-01-15T10:05:00Z \
  --period 300 \
  --statistics Average Maximum Minimum

# Périodes courantes:
# 60 secondes   - 1 minute
# 300 secondes  - 5 minutes (période par défaut EC2)
# 3600 secondes - 1 heure
# 86400 secondes - 1 jour

# Utiliser dates relatives (avec GNU date)
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 300 \
  --statistics Average

# Obtenir mémoire disponible (avec CloudWatch Agent)
aws cloudwatch get-metric-statistics \
  --namespace CWAgent \
  --metric-name mem_used_percent \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 300 \
  --statistics Average

# Obtenir trafic réseau
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name NetworkIn \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time $(date -u -d '1 day ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 3600 \
  --statistics Sum \
  --unit Bytes


# === PUBLIER DES MÉTRIQUES PERSONNALISÉES ===

# Publier une métrique simple
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name RequestCount \
  --value 10 \
  --unit Count

# Unités disponibles:
# Count        - Compteur
# Bytes        - Octets
# Seconds      - Temps en secondes
# Milliseconds - Temps en millisecondes
# Percent      - Pourcentage
# None         - Sans unité

# Publier avec timestamp personnalisé
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name RequestCount \
  --value 10 \
  --timestamp 2024-01-15T10:00:00Z \
  --unit Count

# Publier avec dimensions (pour filtrer/grouper)
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name ResponseTime \
  --value 250 \
  --unit Milliseconds \
  --dimensions Environment=Production,Server=web-01

# Publier avec plusieurs dimensions
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name APILatency \
  --value 125 \
  --unit Milliseconds \
  --dimensions Environment=Production,Region=us-east-1,Endpoint=/api/users

# Publier plusieurs métriques en une seule commande
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-data \
    MetricName=RequestCount,Value=100,Unit=Count \
    MetricName=ErrorCount,Value=5,Unit=Count

# Publier des statistiques pré-agrégées (optimisé)
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name ResponseTime \
  --statistic-values Sum=1250,Minimum=100,Maximum=500,SampleCount=10 \
  --unit Milliseconds

# Exemples de métriques custom utiles:
# - Nombre de connexions actives
# - Temps de réponse API
# - Nombre d'erreurs applicatives
# - Taille de file d'attente
# - Nombre de transactions
# - Utilisation mémoire applicative


═══════════════════════════════════════════════════════════════════════════════
[OK] ALARMES - CRÉER & GÉRER
═══════════════════════════════════════════════════════════════════════════════

# === CRÉER DES ALARMES ===

# Alarme simple: CPU > 80%
aws cloudwatch put-metric-alarm \
  --alarm-name high-cpu-alarm \
  --alarm-description "Alert when CPU exceeds 80%" \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold

# Opérateurs de comparaison disponibles:
# GreaterThanThreshold           - Supérieur à
# GreaterThanOrEqualToThreshold  - Supérieur ou égal à
# LessThanThreshold              - Inférieur à
# LessThanOrEqualToThreshold     - Inférieur ou égal à

# Alarme avec action SNS (envoi email/SMS)
aws cloudwatch put-metric-alarm \
  --alarm-name high-cpu-alarm \
  --alarm-description "Alert when CPU exceeds 80%" \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:my-topic

# Créer SNS topic d'abord:
aws sns create-topic --name my-cloudwatch-alerts
aws sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:123456789012:my-cloudwatch-alerts \
  --protocol email \
  --notification-endpoint your-email@example.com

# Alarme avec plusieurs actions
aws cloudwatch put-metric-alarm \
  --alarm-name critical-cpu-alarm \
  --alarm-description "Critical CPU usage" \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 90 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions \
    arn:aws:sns:us-east-1:123456789012:critical-alerts \
    arn:aws:autoscaling:us-east-1:123456789012:scalingPolicy:xxx \
  --ok-actions arn:aws:sns:us-east-1:123456789012:resolved-alerts

# Actions disponibles:
# --alarm-actions        - Quand alarme se déclenche (état ALARM)
# --ok-actions          - Quand alarme se résout (état OK)
# --insufficient-data-actions - Quand données insuffisantes

# Alarme sur métrique de billing
aws cloudwatch put-metric-alarm \
  --alarm-name billing-alarm \
  --alarm-description "Alert when bill exceeds $100" \
  --namespace AWS/Billing \
  --metric-name EstimatedCharges \
  --dimensions Name=Currency,Value=USD \
  --statistic Maximum \
  --period 21600 \
  --evaluation-periods 1 \
  --threshold 100 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:billing-alerts

# Note: Activer les alertes de billing dans la console AWS d'abord
# Console > Billing > Billing preferences > Receive Billing Alerts

# Alarme sur métrique custom
aws cloudwatch put-metric-alarm \
  --alarm-name high-error-rate \
  --alarm-description "Alert on high error rate" \
  --namespace MyApp \
  --metric-name ErrorRate \
  --dimensions Environment=Production \
  --statistic Average \
  --period 60 \
  --evaluation-periods 3 \
  --threshold 5 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:app-alerts

# Alarme avec traitement de données manquantes
aws cloudwatch put-metric-alarm \
  --alarm-name disk-space-alarm \
  --alarm-description "Disk space low" \
  --namespace CWAgent \
  --metric-name disk_used_percent \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0,Name=path,Value=/ \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --treat-missing-data notBreaching

# Options treat-missing-data:
# notBreaching  - Considérer comme OK (recommandé)
# breaching     - Considérer comme en alarme
# ignore        - Maintenir l'état actuel
# missing       - Considérer comme données insuffisantes

# Alarme composite (combine plusieurs alarmes)
aws cloudwatch put-composite-alarm \
  --alarm-name app-health-alarm \
  --alarm-description "App unhealthy if CPU high AND errors high" \
  --alarm-rule "ALARM(high-cpu-alarm) AND ALARM(high-error-rate)" \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:critical-alerts

# Règles composites possibles:
# AND  - Toutes les alarmes doivent être en ALARM
# OR   - Au moins une alarme en ALARM
# NOT  - Inverser l'état


# === CONSULTER LES ALARMES ===

# Lister toutes les alarmes
aws cloudwatch describe-alarms

# Lister alarmes par état
aws cloudwatch describe-alarms --state-value ALARM
aws cloudwatch describe-alarms --state-value OK
aws cloudwatch describe-alarms --state-value INSUFFICIENT_DATA

# États possibles:
# OK                 - Métrique en dessous du seuil
# ALARM              - Métrique au-dessus du seuil
# INSUFFICIENT_DATA  - Pas assez de données

# Lister alarmes spécifiques
aws cloudwatch describe-alarms \
  --alarm-names high-cpu-alarm billing-alarm

# Lister alarmes avec préfixe
aws cloudwatch describe-alarms --alarm-name-prefix prod-

# Lister alarmes pour une action spécifique
aws cloudwatch describe-alarms \
  --action-prefix arn:aws:sns:us-east-1:123456789012:my-topic

# Obtenir historique d'une alarme
aws cloudwatch describe-alarm-history \
  --alarm-name high-cpu-alarm

# Historique sur période spécifique
aws cloudwatch describe-alarm-history \
  --alarm-name high-cpu-alarm \
  --start-date 2024-01-15T00:00:00Z \
  --end-date 2024-01-16T00:00:00Z

# Historique par type d'événement
aws cloudwatch describe-alarm-history \
  --alarm-name high-cpu-alarm \
  --history-item-type StateUpdate    # ConfigurationUpdate, Action


# === GÉRER LES ALARMES ===

# Désactiver alarme (ne se déclenche plus)
aws cloudwatch disable-alarm-actions --alarm-names high-cpu-alarm

# Activer alarme
aws cloudwatch enable-alarm-actions --alarm-names high-cpu-alarm

# Désactiver plusieurs alarmes
aws cloudwatch disable-alarm-actions \
  --alarm-names alarm1 alarm2 alarm3

# Définir manuellement l'état (pour tests)
aws cloudwatch set-alarm-state \
  --alarm-name high-cpu-alarm \
  --state-value ALARM \
  --state-reason "Testing alarm notification"

# Supprimer alarme
aws cloudwatch delete-alarms --alarm-names high-cpu-alarm

# Supprimer plusieurs alarmes
aws cloudwatch delete-alarms \
  --alarm-names alarm1 alarm2 alarm3

# Supprimer toutes les alarmes d'un préfixe (ATTENTION!)
aws cloudwatch describe-alarms --alarm-name-prefix test- \
  --query 'MetricAlarms[*].AlarmName' \
  --output text | xargs aws cloudwatch delete-alarms --alarm-names


═══════════════════════════════════════════════════════════════════════════════
[OK] LOGS - COLLECTER & ANALYSER
═══════════════════════════════════════════════════════════════════════════════

# === CRÉER LOG GROUPS & STREAMS ===

# Créer log group
aws logs create-log-group --log-group-name /aws/myapp

# Conventions de nommage:
# /aws/lambda/function-name    - Lambda
# /aws/ec2/instance-name       - EC2
# /aws/rds/instance-name       - RDS
# /aws/ecs/cluster/service     - ECS
# /custom/myapp                - Custom

# Créer log group avec tags
aws logs create-log-group \
  --log-group-name /aws/myapp \
  --tags Environment=Production,Application=MyApp

# Créer log stream
aws logs create-log-stream \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-01

# Créer plusieurs log streams
aws logs create-log-stream \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-01

aws logs create-log-stream \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-02


# === ENVOYER DES LOGS ===

# Envoyer un log event simple
aws logs put-log-events \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-01 \
  --log-events timestamp=$(date +%s000),message="Application started"

# Timestamp en millisecondes depuis epoch
# $(date +%s000) = timestamp actuel

# Envoyer plusieurs events
aws logs put-log-events \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-01 \
  --log-events \
    timestamp=1705320000000,message="User login: john@example.com" \
    timestamp=1705320001000,message="Request processed successfully"

# Envoyer avec sequence token (requis après premier envoi)
# Obtenir le token:
NEXT_TOKEN=$(aws logs describe-log-streams \
  --log-group-name /aws/myapp \
  --log-stream-name-prefix app-server-01 \
  --query 'logStreams[0].uploadSequenceToken' \
  --output text)

aws logs put-log-events \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-01 \
  --sequence-token $NEXT_TOKEN \
  --log-events timestamp=$(date +%s000),message="New log entry"

# Note: En pratique, utiliser CloudWatch Agent ou SDK pour envoyer logs


# === LISTER & CONSULTER ===

# Lister tous les log groups
aws logs describe-log-groups

# Lister avec filtre sur nom
aws logs describe-log-groups --log-group-name-prefix /aws/

# Lister avec limite
aws logs describe-log-groups --limit 10

# Obtenir info sur log group spécifique
aws logs describe-log-groups --log-group-name /aws/myapp

# Lister log streams d'un group
aws logs describe-log-streams --log-group-name /aws/myapp

# Lister log streams triés par dernière activité
aws logs describe-log-streams \
  --log-group-name /aws/myapp \
  --order-by LastEventTime \
  --descending

# Lister avec préfixe
aws logs describe-log-streams \
  --log-group-name /aws/myapp \
  --log-stream-name-prefix app-server


# === CONSULTER LES LOGS ===

# Voir logs en temps réel (tail -f)
aws logs tail /aws/myapp --follow

# Tail avec filtre
aws logs tail /aws/myapp --follow --filter-pattern ERROR

# Tail depuis un moment donné
aws logs tail /aws/myapp --since 1h
aws logs tail /aws/myapp --since 30m
aws logs tail /aws/myapp --since 2024-01-15T10:00:00

# Tail d'un stream spécifique
aws logs tail /aws/myapp/app-server-01 --follow

# Filtrer logs entre deux dates
aws logs filter-log-events \
  --log-group-name /aws/myapp \
  --start-time $(date -d '1 hour ago' +%s000) \
  --end-time $(date +%s000)

# Filtrer avec pattern
aws logs filter-log-events \
  --log-group-name /aws/myapp \
  --filter-pattern "ERROR"

# Patterns de filtrage courants:
# "ERROR"                    - Contient ERROR
# "?ERROR ?WARN"            - ERROR OU WARN
# "[ERROR]"                 - Terme exact ERROR
# "{ $.level = \"ERROR\" }" - JSON avec level=ERROR
# "[time, request_id, level = ERROR]" - Format spécifique

# Filtrer logs JSON
aws logs filter-log-events \
  --log-group-name /aws/myapp \
  --filter-pattern '{ $.statusCode = 500 }'

# Filtrer par log stream
aws logs filter-log-events \
  --log-group-name /aws/myapp \
  --log-stream-names app-server-01 app-server-02 \
  --filter-pattern "ERROR"

# Obtenir événements spécifiques
aws logs get-log-events \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-01 \
  --limit 100

# Obtenir dans l'ordre inverse (plus récents d'abord)
aws logs get-log-events \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-01 \
  --limit 100 \
  --start-from-head false


# === LOGS INSIGHTS (REQUÊTES AVANCÉES) ===

# Requête simple
aws logs start-query \
  --log-group-name /aws/myapp \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string 'fields @timestamp, @message | sort @timestamp desc | limit 20'

# Sauvegarder query ID pour récupérer résultats
QUERY_ID=$(aws logs start-query \
  --log-group-name /aws/myapp \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string 'fields @timestamp, @message | limit 20' \
  --query 'queryId' --output text)

# Attendre et obtenir résultats
sleep 5
aws logs get-query-results --query-id $QUERY_ID

# Requête avec filtrage
aws logs start-query \
  --log-group-name /aws/myapp \
  --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 20'

# Requête avec agrégation
aws logs start-query \
  --log-group-name /aws/myapp \
  --start-time $(date -d '1 day ago' +%s) \
  --end-time $(date +%s) \
  --query-string 'stats count() by bin(5m)'

# Requête sur logs JSON
aws logs start-query \
  --log-group-name /aws/myapp \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string 'fields @timestamp, level, message | filter level = "ERROR" | sort @timestamp desc'

# Requête avec calculs
aws logs start-query \
  --log-group-name /aws/myapp \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string 'stats avg(responseTime), max(responseTime), min(responseTime) by bin(5m)'

# Exemples de requêtes Logs Insights utiles:
# - Top 10 erreurs:
#   fields @message | filter @message like /ERROR/ | stats count() by @message | sort count desc | limit 10
# 
# - Latence moyenne par endpoint:
#   stats avg(duration) by endpoint
#
# - Nombre de requêtes par heure:
#   stats count() by bin(1h)
#
# - Erreurs 500:
#   filter statusCode = 500 | fields @timestamp, @message


# === GÉRER LES LOGS ===

# Définir période de rétention
aws logs put-retention-policy \
  --log-group-name /aws/myapp \
  --retention-in-days 7

# Périodes de rétention disponibles (jours):
# 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1096, 1827, 2192, 2557, 2922, 3288, 3653

# Rétention recommandée par type:
# Logs dev/test: 7 jours
# Logs production: 30-90 jours
# Logs compliance/audit: 365+ jours

# Supprimer politique de rétention (garde indéfiniment)
aws logs delete-retention-policy --log-group-name /aws/myapp

# Supprimer log stream
aws logs delete-log-stream \
  --log-group-name /aws/myapp \
  --log-stream-name app-server-01

# Supprimer log group (ATTENTION: supprime tous les logs!)
aws logs delete-log-group --log-group-name /aws/myapp

# Tagger log group
aws logs tag-log-group \
  --log-group-name /aws/myapp \
  --tags Environment=Production,Team=Backend

# Supprimer tags
aws logs untag-log-group \
  --log-group-name /aws/myapp \
  --tags Environment Team


# === EXPORTER LES LOGS ===

# Créer export task vers S3
aws logs create-export-task \
  --log-group-name /aws/myapp \
  --from $(date -d '1 day ago' +%s000) \
  --to $(date +%s000) \
  --destination my-logs-bucket \
  --destination-prefix logs/myapp/

# Note: Créer bucket S3 et policy d'abord
# Policy exemple: permettre CloudWatch Logs d'écrire

# Vérifier statut export
aws logs describe-export-tasks

# Vérifier export spécifique
aws logs describe-export-tasks --task-id <TASK_ID>


# === SUBSCRIPTION FILTERS ===

# Créer filtre pour streamer vers Lambda
aws logs put-subscription-filter \
  --log-group-name /aws/myapp \
  --filter-name error-processor \
  --filter-pattern "ERROR" \
  --destination-arn arn:aws:lambda:us-east-1:123456789012:function:ProcessErrors

# Créer filtre vers Kinesis
aws logs put-subscription-filter \
  --log-group-name /aws/myapp \
  --filter-name log-stream \
  --filter-pattern "" \
  --destination-arn arn:aws:kinesis:us-east-1:123456789012:stream/LogStream

# Lister subscription filters
aws logs describe-subscription-filters \
  --log-group-name /aws/myapp

# Supprimer subscription filter
aws logs delete-subscription-filter \
  --log-group-name /aws/myapp \
  --filter-name error-processor


═══════════════════════════════════════════════════════════════════════════════
[OK] DASHBOARDS - VISUALISATION
═══════════════════════════════════════════════════════════════════════════════

# === CRÉER DASHBOARD ===

# Créer fichier JSON de dashboard
# dashboard.json
{
  "widgets": [
    {
      "type": "metric",
      "x": 0,
      "y": 0,
      "width": 12,
      "height": 6,
      "properties": {
        "metrics": [
          [ "AWS/EC2", "CPUUtilization", { "stat": "Average" } ]
        ],
        "period": 300,
        "stat": "Average",
        "region": "us-east-1",
        "title": "Recent Errors"
      }
    }
  ]
}


# === GÉRER DASHBOARDS ===

# Lister tous les dashboards
aws cloudwatch list-dashboards

# Lister avec préfixe
aws cloudwatch list-dashboards --dashboard-name-prefix prod-

# Obtenir dashboard spécifique
aws cloudwatch get-dashboard --dashboard-name MyDashboard

# Mettre à jour dashboard (écrase l'ancien)
aws cloudwatch put-dashboard \
  --dashboard-name MyDashboard \
  --dashboard-body file://dashboard-updated.json

# Supprimer dashboard
aws cloudwatch delete-dashboards --dashboard-names MyDashboard

# Supprimer plusieurs dashboards
aws cloudwatch delete-dashboards \
  --dashboard-names Dashboard1 Dashboard2 Dashboard3


# === EXEMPLES DE DASHBOARDS COMPLETS ===

# Dashboard application complète
{
  "widgets": [
    {
      "type": "metric",
      "x": 0,
      "y": 0,
      "width": 12,
      "height": 6,
      "properties": {
        "title": "Requests per Minute",
        "metrics": [
          [ "MyApp", "RequestCount", { "stat": "Sum" } ]
        ],
        "period": 60,
        "stat": "Sum",
        "region": "us-east-1"
      }
    },
    {
      "type": "metric",
      "x": 12,
      "y": 0,
      "width": 12,
      "height": 6,
      "properties": {
        "title": "Error Rate",
        "metrics": [
          [ "MyApp", "ErrorCount", { "stat": "Sum" } ]
        ],
        "period": 60,
        "stat": "Sum",
        "region": "us-east-1"
      }
    },
    {
      "type": "metric",
      "x": 0,
      "y": 6,
      "width": 24,
      "height": 6,
      "properties": {
        "title": "Response Time (ms)",
        "metrics": [
          [ "MyApp", "ResponseTime", { "stat": "Average", "label": "Avg" } ],
          [ "...", { "stat": "Maximum", "label": "Max" } ],
          [ "...", { "stat": "p95", "label": "p95" } ]
        ],
        "period": 300,
        "region": "us-east-1",
        "yAxis": {
          "left": {
            "min": 0
          }
        }
      }
    }
  ]
}

# Créer dashboard depuis fichier
aws cloudwatch put-dashboard \
  --dashboard-name MyDashboard \
  --dashboard-body file://dashboard.json

# Dashboard multi-métriques
{
  "widgets": [
    {
      "type": "metric",
      "properties": {
        "metrics": [
          [ "AWS/EC2", "CPUUtilization", { "label": "CPU", "stat": "Average" } ],
          [ "CWAgent", "mem_used_percent", { "label": "Memory", "stat": "Average" } ],
          [ "AWS/EC2", "disk_used_percent", { "label": "Disk", "stat": "Average" } ]
        ],
        "period": 300,
        "stat": "Average",
        "region": "us-east-1",
        "title": "System Resources",
        "yAxis": {
          "left": {
            "min": 0,
            "max": 100
          }
        }
      }
    }
  ]
}

# Widget de logs
{
  "widgets": [
    {
      "type": "log",
      "properties": {
        "query": "SOURCE '/aws/myapp' | fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc | limit 20",
        "region": "us-east-1",
        "title": "EC2 CPU Utilization"
      }
    },
    {
      "type": "metric",
      "x": 12,
      "y": 0,
      "width": 12,
      "height": 6,
      "properties": {
        "metrics": [
          [ "AWS/EC2", "NetworkIn" ],
          [ ".", "NetworkOut" ]
        ],
        "period": 300,
        "stat": "Average",
        "region": "us-east-1",
        "title": "Network Traffic"
      }
    }
  ]
}


═══════════════════════════════════════════════════════════════════════════════
[OK] CLOUDWATCH AGENT - MÉTRIQUES AVANCÉES
═══════════════════════════════════════════════════════════════════════════════

# Le CloudWatch Agent permet de collecter:
# - Métriques système avancées (RAM, disk, processes...)
# - Logs applicatifs
# - Métriques custom

# === INSTALLATION ===

# Télécharger agent (Amazon Linux 2 / RHEL / CentOS)
wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
sudo rpm -U ./amazon-cloudwatch-agent.rpm

# Ubuntu / Debian
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i -E ./amazon-cloudwatch-agent.deb

# Windows (PowerShell en admin)
Invoke-WebRequest -Uri https://s3.amazonaws.com/amazoncloudwatch-agent/windows/amd64/latest/amazon-cloudwatch-agent.msi -OutFile amazon-cloudwatch-agent.msi
msiexec /i amazon-cloudwatch-agent.msi


# === CONFIGURATION ===

# Créer fichier de configuration
# /opt/aws/amazon-cloudwatch-agent/etc/config.json

{
  "agent": {
    "metrics_collection_interval": 60,
    "run_as_user": "cwagent"
  },
  "metrics": {
    "namespace": "CWAgent",
    "metrics_collected": {
      "cpu": {
        "measurement": [
          {
            "name": "cpu_usage_idle",
            "rename": "CPU_IDLE",
            "unit": "Percent"
          },
          "cpu_usage_iowait"
        ],
        "metrics_collection_interval": 60,
        "totalcpu": false
      },
      "disk": {
        "measurement": [
          {
            "name": "used_percent",
            "rename": "DISK_USED",
            "unit": "Percent"
          }
        ],
        "metrics_collection_interval": 60,
        "resources": [
          "*"
        ]
      },
      "mem": {
        "measurement": [
          {
            "name": "mem_used_percent",
            "rename": "MEM_USED",
            "unit": "Percent"
          }
        ],
        "metrics_collection_interval": 60
      }
    }
  },
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/var/log/myapp/app.log",
            "log_group_name": "/aws/myapp",
            "log_stream_name": "{instance_id}/app.log"
          }
        ]
      }
    }
  }
}

# Démarrer agent avec configuration
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config \
  -m ec2 \
  -s \
  -c file:/opt/aws/amazon-cloudwatch-agent/etc/config.json

# Vérifier statut
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a query \
  -m ec2 \
  -s

# Arrêter agent
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a stop \
  -m ec2 \
  -s


═══════════════════════════════════════════════════════════════════════════════
[OK] BONNES PRATIQUES
═══════════════════════════════════════════════════════════════════════════════

# === ORGANISATION DES LOGS ===

# 1. Utiliser une hiérarchie claire
/aws/service/environment/application
/aws/lambda/prod/user-service
/aws/ec2/staging/web-server

# 2. Définir des rétentions appropriées
# Dev/Test: 7 jours
aws logs put-retention-policy \
  --log-group-name /aws/dev/myapp \
  --retention-in-days 7

# Production: 30-90 jours
aws logs put-retention-policy \
  --log-group-name /aws/prod/myapp \
  --retention-in-days 90

# Compliance/Audit: 1+ an
aws logs put-retention-policy \
  --log-group-name /aws/audit/myapp \
  --retention-in-days 365

# 3. Utiliser des tags pour organisation
aws logs tag-log-group \
  --log-group-name /aws/myapp \
  --tags \
    Environment=Production \
    Team=Backend \
    CostCenter=Engineering \
    Application=MyApp


# === ALARMES INTELLIGENTES ===

# 1. Utiliser des périodes d'évaluation multiples
# Évite les faux positifs
aws cloudwatch put-metric-alarm \
  --alarm-name cpu-sustained-high \
  --evaluation-periods 3 \
  --period 300 \
  --threshold 80
# = Alarme si CPU > 80% pendant 15 minutes (3 x 5min)

# 2. Créer des alarmes en cascade
# Alarme WARNING (70%)
aws cloudwatch put-metric-alarm \
  --alarm-name cpu-warning \
  --threshold 70 \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:warnings

# Alarme CRITICAL (90%)
aws cloudwatch put-metric-alarm \
  --alarm-name cpu-critical \
  --threshold 90 \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:critical

# 3. Alarme sur données manquantes
aws cloudwatch put-metric-alarm \
  --alarm-name app-heartbeat \
  --metric-name Heartbeat \
  --namespace MyApp \
  --statistic Sum \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 1 \
  --comparison-operator LessThanThreshold \
  --treat-missing-data breaching
# = Alarme si pas de heartbeat


# === MÉTRIQUES CUSTOM UTILES ===

# 1. Application health check
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name HealthCheck \
  --value 1 \
  --unit Count

# 2. Business metrics
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name OrdersCompleted \
  --value 42 \
  --unit Count \
  --dimensions Environment=Production

# 3. Queue depth
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name QueueDepth \
  --value 1250 \
  --unit Count

# 4. Cache hit rate
aws cloudwatch put-metric-data \
  --namespace MyApp \
  --metric-name CacheHitRate \
  --value 87.5 \
  --unit Percent


# === DASHBOARDS EFFICACES ===

# 1. Dashboard par service
# - CPU, Memory, Disk
# - Network In/Out
# - Requests, Errors
# - Response time

# 2. Dashboard par environnement
# - Production overview
# - Staging overview
# - Dev overview

# 3. Dashboard SLA/Business
# - Uptime percentage
# - Error rate
# - Response time p99
# - Business KPIs


# === OPTIMISATION COÛTS ===

# 1. Limiter rétention des logs
# Coût: $0.50/GB ingestion + $0.03/GB storage/mois
aws logs put-retention-policy \
  --log-group-name /aws/dev/myapp \
  --retention-in-days 7

# 2. Filtrer les logs avant envoi
# Dans CloudWatch Agent config, filtrer logs peu utiles

# 3. Utiliser S3 pour archivage long terme
# Exporter logs anciens vers S3 (moins cher)
aws logs create-export-task \
  --log-group-name /aws/myapp \
  --from $(date -d '30 days ago' +%s000) \
  --to $(date -d '7 days ago' +%s000) \
  --destination my-archive-bucket

# 4. Supprimer log groups inutilisés
# Lister log groups sans activité récente
aws logs describe-log-groups \
  --query 'logGroups[?!contains(logGroupName, `prod`)].logGroupName' \
  --output text

# 5. Métriques custom: publier en batch
# Plus efficace que multiples appels individuels


# === SÉCURITÉ ===

# 1. Chiffrer log groups
aws logs create-log-group \
  --log-group-name /aws/myapp \
  --kms-key-id arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012

# 2. Restreindre accès avec IAM
# Policy exemple: lecture seule logs production
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams",
        "logs:GetLogEvents",
        "logs:FilterLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:log-group:/aws/prod/*"
    }
  ]
}

# 3. Masquer données sensibles avant envoi
# Configurer dans application, pas dans CloudWatch


═══════════════════════════════════════════════════════════════════════════════
[OK] DÉPANNAGE & ERREURS COURANTES
═══════════════════════════════════════════════════════════════════════════════

# === ERREUR: ResourceNotFoundException ===
# Log group ou stream n'existe pas

# Solution: Créer d'abord
aws logs create-log-group --log-group-name /aws/myapp
aws logs create-log-stream \
  --log-group-name /aws/myapp \
  --log-stream-name mystream


# === ERREUR: InvalidSequenceTokenException ===
# Sequence token invalide lors d'envoi logs

# Solution: Obtenir le token actuel
NEXT_TOKEN=$(aws logs describe-log-streams \
  --log-group-name /aws/myapp \
  --log-stream-name-prefix mystream \
  --query 'logStreams[0].uploadSequenceToken' \
  --output text)

aws logs put-log-events \
  --log-group-name /aws/myapp \
  --log-stream-name mystream \
  --sequence-token $NEXT_TOKEN \
  --log-events timestamp=$(date +%s000),message="Test"


# === ERREUR: DataAlreadyAcceptedException ===
# Événement déjà envoyé (timestamp dupliqué)

# Solution: Utiliser timestamps uniques (millisecondes)
TIMESTAMP=$(($(date +%s) * 1000 + RANDOM % 1000))


# === ERREUR: InvalidParameterException (timestamp) ===
# Timestamp trop vieux ou dans le futur

# Solution: CloudWatch accepte logs de -14 jours à +2 heures
# Vérifier timestamp est en millisecondes
date +%s000  # Correct
date +%s     # INCORRECT (manque millisecondes)


# === PROBLÈME: Logs n'apparaissent pas ===

# 1. Vérifier IAM permissions
# EC2 doit avoir rôle avec CloudWatchAgentServerPolicy

# 2. Vérifier agent est démarré
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a query -m ec2 -s

# 3. Vérifier configuration agent
cat /opt/aws/amazon-cloudwatch-agent/etc/config.json

# 4. Vérifier logs agent
sudo tail -f /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log


# === PROBLÈME: Alarme ne se déclenche pas ===

# 1. Vérifier état alarme
aws cloudwatch describe-alarms --alarm-names my-alarm

# 2. Vérifier données métriques disponibles
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-xxx \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 300 \
  --statistics Average

# 3. Vérifier actions SNS sont configurées
aws cloudwatch describe-alarms \
  --alarm-names my-alarm \
  --query 'MetricAlarms[0].AlarmActions'

# 4. Tester manuellement
aws cloudwatch set-alarm-state \
  --alarm-name my-alarm \
  --state-value ALARM \
  --state-reason "Manual test"


# === PROBLÈME: Coûts élevés ===

# 1. Identifier log groups volumineux
aws logs describe-log-groups \
  --query 'sort_by(logGroups, &storedBytes)[-10:].{Name:logGroupName,Size:storedBytes}' \
  --output table

# 2. Vérifier rétention
aws logs describe-log-groups \
  --query 'logGroups[?retentionInDays==`null`].logGroupName'

# 3. Calculer coût estimé par log group
# Ingestion: $0.50/GB
# Storage: $0.03/GB/mois
# Exemple: 100 GB ingestion/mois + 500 GB stockés
# = (100 * $0.50) + (500 * $0.03) = $50 + $15 = $65/mois


═══════════════════════════════════════════════════════════════════════════════
[OK] SCRIPTS UTILES
═══════════════════════════════════════════════════════════════════════════════

# === Script: Nettoyer vieux log groups ===

#!/bin/bash
# cleanup-old-logs.sh
# Supprime log groups sans activité depuis 30 jours

CUTOFF_DATE=$(date -d '30 days ago' +%s000)

aws logs describe-log-groups --query 'logGroups[*].logGroupName' --output text | \
while read LOG_GROUP; do
  LAST_EVENT=$(aws logs describe-log-streams \
    --log-group-name "$LOG_GROUP" \
    --order-by LastEventTime \
    --descending \
    --max-items 1 \
    --query 'logStreams[0].lastEventTimestamp' \
    --output text)
  
  if [ "$LAST_EVENT" != "None" ] && [ "$LAST_EVENT" -lt "$CUTOFF_DATE" ]; then
    echo "Deleting inactive log group: $LOG_GROUP"
    aws logs delete-log-group --log-group-name "$LOG_GROUP"
  fi
done


# === Script: Définir rétention pour tous les log groups ===

#!/bin/bash
# set-retention.sh
# Définit rétention 7 jours pour tous les log groups dev/test

aws logs describe-log-groups \
  --query 'logGroups[?contains(logGroupName, `dev`) || contains(logGroupName, `test`)].logGroupName' \
  --output text | \
while read LOG_GROUP; do
  echo "Setting 7-day retention for: $LOG_GROUP"
  aws logs put-retention-policy \
    --log-group-name "$LOG_GROUP" \
    --retention-in-days 7
done


# === Script: Surveiller coûts CloudWatch ===

#!/bin/bash
# monitor-cloudwatch-costs.sh
# Calcule taille totale des logs

TOTAL_SIZE=0

aws logs describe-log-groups --query 'logGroups[*].[logGroupName,storedBytes]' --output text | \
while read LOG_GROUP SIZE; do
  TOTAL_SIZE=$((TOTAL_SIZE + SIZE))
  SIZE_GB=$(echo "scale=2; $SIZE / 1024 / 1024 / 1024" | bc)
  echo "$LOG_GROUP: ${SIZE_GB} GB"
done

TOTAL_GB=$(echo "scale=2; $TOTAL_SIZE / 1024 / 1024 / 1024" | bc)
MONTHLY_COST=$(echo "scale=2; $TOTAL_GB * 0.03" | bc)

echo "---"
echo "Total: ${TOTAL_GB} GB"
echo "Estimated monthly storage cost: \${MONTHLY_COST}"


# === Script: Exporter logs vers S3 (batch) ===

#!/bin/bash
# export-logs-to-s3.sh
# Exporte tous les logs du mois dernier vers S3

LOG_GROUP="/aws/myapp"
BUCKET="my-logs-archive"
YEAR=$(date -d 'last month' +%Y)
MONTH=$(date -d 'last month' +%m)

START_TIME=$(date -d "${YEAR}-${MONTH}-01" +%s000)
END_TIME=$(date -d "${YEAR}-${MONTH}-01 +1 month" +%s000)

aws logs create-export-task \
  --log-group-name "$LOG_GROUP" \
  --from "$START_TIME" \
  --to "$END_TIME" \
  --destination "$BUCKET" \
  --destination-prefix "logs/${YEAR}/${MONTH}/"


# === Script: Créer alarmes standard pour instance EC2 ===

#!/bin/bash
# create-ec2-alarms.sh INSTANCE_ID SNS_TOPIC_ARN

INSTANCE_ID=$1
SNS_TOPIC=$2

if [ -z "$INSTANCE_ID" ] || [ -z "$SNS_TOPIC" ]; then
  echo "Usage: $0 INSTANCE_ID SNS_TOPIC_ARN"
  exit 1
fi

# CPU > 80%
aws cloudwatch put-metric-alarm \
  --alarm-name "${INSTANCE_ID}-high-cpu" \
  --alarm-description "CPU exceeds 80%" \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=$INSTANCE_ID \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions $SNS_TOPIC

# Disk > 85%
aws cloudwatch put-metric-alarm \
  --alarm-name "${INSTANCE_ID}-high-disk" \
  --alarm-description "Disk usage exceeds 85%" \
  --namespace CWAgent \
  --metric-name disk_used_percent \
  --dimensions Name=InstanceId,Value=$INSTANCE_ID,Name=path,Value=/ \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 85 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions $SNS_TOPIC

# Memory > 80%
aws cloudwatch put-metric-alarm \
  --alarm-name "${INSTANCE_ID}-high-memory" \
  --alarm-description "Memory exceeds 80%" \
  --namespace CWAgent \
  --metric-name mem_used_percent \
  --dimensions Name=InstanceId,Value=$INSTANCE_ID \
  --statistic Average \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions $SNS_TOPIC

echo "Alarmes créées pour instance $INSTANCE_ID"


# === Script: Query logs avec retry ===

#!/bin/bash
# query-logs.sh
# Lance query Logs Insights et attend résultats

LOG_GROUP="/aws/myapp"
QUERY='fields @timestamp, @message | filter @message like /ERROR/ | sort @timestamp desc | limit 20'
START_TIME=$(date -d '1 hour ago' +%s)
END_TIME=$(date +%s)

# Lancer query
QUERY_ID=$(aws logs start-query \
  --log-group-name "$LOG_GROUP" \
  --start-time $START_TIME \
  --end-time $END_TIME \
  --query-string "$QUERY" \
  --query 'queryId' \
  --output text)

echo "Query lancée: $QUERY_ID"

# Attendre résultats
MAX_ATTEMPTS=30
ATTEMPT=0

while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
  STATUS=$(aws logs get-query-results \
    --query-id "$QUERY_ID" \
    --query 'status' \
    --output text)
  
  if [ "$STATUS" = "Complete" ]; then
    echo "Query terminée!"
    aws logs get-query-results --query-id "$QUERY_ID"
    exit 0
  elif [ "$STATUS" = "Failed" ] || [ "$STATUS" = "Cancelled" ]; then
    echo "Query échouée: $STATUS"
    exit 1
  fi
  
  echo "Attente... ($STATUS)"
  sleep 2
  ATTEMPT=$((ATTEMPT + 1))
done

echo "Timeout: query trop longue"
exit 1


═══════════════════════════════════════════════════════════════════════════════
[OK] PATTERNS AVANCÉS
═══════════════════════════════════════════════════════════════════════════════

# === Logs structurés JSON ===

# Application envoie logs JSON
{
  "timestamp": "2024-01-15T10:30:00Z",
  "level": "ERROR",
  "service": "user-service",
  "endpoint": "/api/users",
  "statusCode": 500,
  "message": "Database connection failed",
  "duration": 250
}

# Query Logs Insights pour analyser
aws logs start-query \
  --log-group-name /aws/myapp \
  --start-time $(date -d '1 hour ago' +%s) \
  --end-time $(date +%s) \
  --query-string '
    fields @timestamp, level, service, endpoint, statusCode, duration
    | filter level = "ERROR"
    | stats count() by endpoint, statusCode
    | sort count desc
  '

# Alarme sur taux d'erreur calculé
aws cloudwatch put-metric-alarm \
  --alarm-name high-error-rate \
  --metrics '[
    {
      "Id": "errors",
      "MetricStat": {
        "Metric": {
          "Namespace": "MyApp",
          "MetricName": "ErrorCount"
        },
        "Period": 300,
        "Stat": "Sum"
      }
    },
    {
      "Id": "requests",
      "MetricStat": {
        "Metric": {
          "Namespace": "MyApp",
          "MetricName": "RequestCount"
        },
        "Period": 300,
        "Stat": "Sum"
      }
    },
    {
      "Id": "error_rate",
      "Expression": "(errors / requests) * 100"
    }
  ]' \
  --threshold 5 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 2


# === Métriques composites ===

# Créer alarme basée sur math entre métriques
# Exemple: Alarme si (errors / requests) > 5%

# Fichier: composite-alarm.json
{
  "AlarmName": "high-error-rate",
  "ComparisonOperator": "GreaterThanThreshold",
  "EvaluationPeriods": 2,
  "Threshold": 5,
  "Metrics": [
    {
      "Id": "m1",
      "ReturnData": false,
      "MetricStat": {
        "Metric": {
          "Namespace": "MyApp",
          "MetricName": "ErrorCount"
        },
        "Period": 300,
        "Stat": "Sum"
      }
    },
    {
      "Id": "m2",
      "ReturnData": false,
      "MetricStat": {
        "Metric": {
          "Namespace": "MyApp",
          "MetricName": "RequestCount"
        },
        "Period": 300,
        "Stat": "Sum"
      }
    },
    {
      "Id": "e1",
      "Expression": "(m1/m2)*100"
    }
  ]
}


═══════════════════════════════════════════════════════════════════════════════
[OK] RESSOURCES & DOCUMENTATION
═══════════════════════════════════════════════════════════════════════════════

# Documentation officielle AWS:
# CloudWatch: https://docs.aws.amazon.com/cloudwatch/
# CloudWatch Logs: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/
# CloudWatch Agent: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html
# Logs Insights: https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html

# Tarification:
# https://aws.amazon.com/cloudwatch/pricing/
# Logs: $0.50/GB ingestion, $0.03/GB/mois storage
# Métriques custom: $0.30/métrique/mois
# Alarmes: $0.10/alarme/mois
# Dashboards: $3/dashboard/mois

# Limites de service:
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/cloudwatch_limits_cwl.html
# - 10,000 log groups par région par compte
# - 1 MB/s max put-log-events par log stream
# - 5 requests/seconde par log stream

# Outils tiers utiles:
# - Datadog: Alternative monitoring avec plus de features
# - Grafana: Visualisation avancée (peut utiliser CloudWatch)
# - awslogs: CLI tool pour tail logs facilement
#   pip install awslogs
#   awslogs get /aws/myapp --watch

# CloudWatch Logs Insights exemples:
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax-examples.html


═══════════════════════════════════════════════════════════════════════════════
[OK] CHECKLIST PRODUCTION
═══════════════════════════════════════════════════════════════════════════════

# Avant mise en production:

# [ ] CloudWatch Agent installé et configuré
# [ ] Logs applicatifs envoyés vers CloudWatch
# [ ] Rétention définie sur tous les log groups (pas "Never expire")
# [ ] Alarmes créées pour métriques critiques:
#     - CPU, Memory, Disk > seuils
#     - Erreurs applicatives
#     - Latence API
#     - Health check failures
# [ ] SNS topics configurés avec emails/SMS
# [ ] Dashboards créés pour monitoring temps réel
# [ ] Tags appliqués sur log groups (Environment, Application, Team)
# [ ] IAM roles configurés (CloudWatchAgentServerPolicy pour EC2)
# [ ] Budget alertes activées (CloudWatch coûts)
# [ ] Logs sensibles masqués avant envoi
# [ ] KMS encryption activée si données sensibles
# [ ] Subscription filters configurés si besoin (Lambda, Kinesis)
# [ ] Export S3 automatisé pour archivage long terme
# [ ] Documentation runbook pour alarmes courantes

# Surveillance continue:
# [ ] Review logs quotidien
# [ ] Review alarmes hebdomadaire
# [ ] Audit coûts CloudWatch mensuel
# [ ] Cleanup log groups inutilisés trimestriel


═══════════════════════════════════════════════════════════════════════════════
FIN DU GUIDE CLOUDWATCH
═══════════════════════════════════════════════════════════════════════════════
