Files
oc-datacenter/infrastructure/monitor/PROMETHEUS_ANALYSIS.md

6.7 KiB

Analyse de infrastructure/prometheus.go

Ce que fait le fichier

Ce fichier implémente un service de monitoring qui interroge une instance Prometheus pour collecter des métriques de conteneurs Kubernetes associés à une réservation (Booking).

Structures de données

Struct Role
MetricsSnapshot Snapshot de métriques associé à une origine (source). Note : cette struct locale est déclarée mais jamais utilisée — le code utilise en réalité models.MetricsSnapshot de oc-lib.
Metric Paire nom/valeur d'une métrique. Même remarque — le code utilise models.Metric.
PrometheusResponse Mapping de la réponse JSON de l'API Prometheus /api/v1/query.

Métriques collectées (queriesMetrics)

# Requête PromQL Mesure
1 rate(container_cpu_usage_seconds_total{namespace}[1m]) * 100 Utilisation CPU (%)
2 container_memory_usage_bytes{namespace} Mémoire utilisée (bytes)
3 container_fs_usage_bytes / container_fs_limit_bytes * 100 Utilisation disque (%)
4 DCGM_FI_DEV_GPU_UTIL{namespace} Utilisation GPU (NVIDIA DCGM)
5 rate(container_fs_reads_bytes_total[1m]) Débit lecture disque (bytes/s)
6 rate(container_fs_writes_bytes_total[1m]) Débit écriture disque (bytes/s)
7 rate(container_network_receive_bytes_total[1m]) Bande passante réseau entrante (bytes/s)
8 rate(container_network_transmit_bytes_total[1m]) Bande passante réseau sortante (bytes/s)
9 rate(http_requests_total[1m]) Requêtes HTTP/s
10 rate(http_requests_total{status=~"5.."}[1m]) / rate(http_requests_total[1m]) * 100 Taux d'erreur HTTP 5xx (%)

Métriques commentées (non actives) : system_load_average, system_network_latency_ms, app_mean_time_to_repair_seconds, app_mean_time_between_failure_seconds.

Méthodes

queryPrometheus(promURL, expr, namespace) Metric

  • Construit une requête GET vers /api/v1/query de Prometheus.
  • Injecte le namespace dans l'expression PromQL via fmt.Sprintf.
  • Parse la réponse JSON et extrait la première valeur du premier résultat.
  • Retourne -1 si aucun résultat.

Call(book, user, peerID, groups) (Booking, map[string]MetricsSnapshot)

  • Charge la ressource de calcul (ComputeResource) liée au booking.
  • Pour chaque instance de la ressource, cherche le LiveDatacenter correspondant.
  • Lance en goroutine (parallèle) l'exécution de toutes les requêtes PromQL pour chaque datacenter ayant un MonitorPath.
  • Attend toutes les goroutines (sync.WaitGroup), puis retourne les métriques groupées par instance.

Stream(bookingID, interval, user, peerID, groups, websocket)

  • Boucle de monitoring en continu jusqu'à ExpectedEndDate du booking ou signal de kill.
  • A chaque tick (interval), appelle Call() dans une goroutine.
  • Envoie les métriques en temps réel via WebSocket.
  • Accumule les métriques en mémoire et les persiste dans le booking tous les max (100) cycles.
  • Supporte un mécanisme de kill via la variable globale Kill.

Problemes et points d'attention

Bugs potentiels

  1. Race condition dans Stream — Les variables mets, bookIDS, book sont partagées entre la boucle principale et les goroutines lancées à chaque tick, sans synchronisation (pas de mutex). Si interval est court, plusieurs goroutines peuvent écrire simultanément dans mets et bookIDS.

  2. Race condition sur Kill — La variable globale Kill est lue dans la boucle sans verrouiller LockKill. Le mutex n'est utilisé que pour l'écriture.

  3. Structs locales inutiliséesMetricsSnapshot et Metric (lignes 22-31) sont déclarées localement mais le code utilise models.MetricsSnapshot et models.Metric. Code mort à nettoyer.

  4. Requête PromQL avec double placeholder — La requête filesystem (ligne 47) contient deux %s mais queryPrometheus ne fait qu'un seul fmt.Sprintf(expr, namespace). Cela provoque un %!s(MISSING) dans la requête. Il faut passer le namespace deux fois ou réécrire la fonction.

  5. Pas de timeout HTTPhttp.Get() utilise le client par défaut sans timeout. Un Prometheus lent peut bloquer indéfiniment.

  6. Pas de gestion d'erreur sur WriteJSON — Si le WebSocket est fermé côté client, l'écriture échoue silencieusement.

Améliorations possibles

Fiabilité

  • Ajouter un context.Context à queryPrometheus et Call pour supporter les timeouts et l'annulation.
  • Utiliser un http.Client avec timeout au lieu de http.Get.
  • Protéger les accès concurrents dans Stream avec un sync.Mutex sur mets/bookIDS.
  • Remplacer la variable globale Kill par un context.WithCancel ou un channel, plus idiomatique en Go.

Métriques supplémentaires envisageables

  • container_cpu_cfs_throttled_seconds_total — Throttling CPU (le container est bridé).
  • kube_pod_container_status_restarts_total — Nombre de restarts (instabilité).
  • container_memory_working_set_bytes — Mémoire réelle utilisée (exclut le cache, plus précis que memory_usage_bytes).
  • kube_pod_status_phase — Phase du pod (Running, Pending, Failed...).
  • container_oom_events_total ou kube_pod_container_status_last_terminated_reason — Détection des OOM kills.
  • kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes — Utilisation des PVC.
  • DCGM_FI_DEV_MEM_COPY_UTIL — Utilisation mémoire GPU.
  • DCGM_FI_DEV_GPU_TEMP — Température GPU.
  • node_cpu_seconds_total / node_memory_MemAvailable_bytes — Métriques au niveau du noeud (vue globale).

Architecture

  • Range queries (/api/v1/query_range) — Actuellement seul l'instant query est utilisé. Pour le streaming sur une période, query_range permettrait de récupérer des séries temporelles complètes et de calculer des moyennes/percentiles.
  • Labels dans les résultats — Actuellement seule la première série est lue (Result[0]). On perd l'information si plusieurs pods/containers matchent. Agréger ou renvoyer toutes les séries.
  • Noms de métriques lisibles — Mapper les expressions PromQL vers des noms humains (cpu_usage_percent, memory_bytes, etc.) au lieu de stocker l'expression brute comme nom.
  • Health check Prometheus — Ajouter une méthode pour vérifier que Prometheus est accessible (/-/healthy).

Résumé

Le fichier est fonctionnel pour un cas d'usage basique (collecte one-shot + streaming WebSocket), mais présente des race conditions dans Stream, un bug sur la requête filesystem (double %s), et du code mort. Les améliorations prioritaires sont la correction des accès concurrents et l'ajout de timeouts HTTP.