FEAT: Télémétrie agent — inventaire mémoire & disque (RAM machine, swap, capacité disques, type) #83

Closed
opened 2026-08-12 10:16:25 +02:00 by nonobis · 1 comment
Owner

🎯 Contexte

Aujourd'hui MemoryUsageBytes = WorkingSet64 du process .NET (pas la RAM de la machine !) et DiskUsagePercent ne regarde que la racine du conteneur. Pour piloter des agents (et savoir si un site peut prendre plus de caméras/GPU), il faut la RAM machine totale/utilisée/swap et les disques réels avec capacité et type.

📚 Référence spec / décision

Décision : deux niveaux de métriques — machine (host) et process/conteneur — remontés distinctement.

  • Mémoire host : /proc/meminfo → MemTotal, MemAvailable, MemFree, SwapTotal, SwapFree, Buffers/Cached (Linux) ; sysctl hw.memsize + vm.swapusage (macOS)
  • Mémoire process : WorkingSet64/PagedMemorySize64 conservés mais étiquetés process
  • Docker : les limites mémoire cgroup (/sys/fs/cgroup/memory.max v2, memory.current) exposées comme ContainerMemoryLimit — le conteneur peut avoir 4 Go alors que le host en a 64
  • Disques : df//proc/mounts → par point de montage : capacité, libre, usage %, filesystem, type SSD/HDD/NVMe (via /sys/block/*/queue/rotation + modèle via /sys/block/*/device/model)

🔍 État actuel (vérifié dans le code)

SystemMetricsProvider : MemoryUsageBytes = Process.GetCurrentProcess().WorkingSet64 (process), GetTotalMemory lit MemTotal (host), GetDiskUsage = DriveInfo de AppContext.BaseDirectory (racine du conteneur). Agent : MemoryMb (long, mis une fois via UpdateCapabilities) + MemoryUsageBytes live. Pas de swap, pas de disques multiples, pas de type SSD/HDD.

🧩 À faire

  • Refonte SystemMetricsProvider : séparer host vs process (record SystemMetrics enrichi : MemTotalBytes, MemAvailableBytes, SwapTotalBytes, SwapFreeBytes, ProcessMemoryBytes, ContainerMemoryLimitBytes?)
  • Collecteur disques : DiskInventoryProvider — énumérer les montages (/proc/mounts), capacité/libre/type (SSD/HDD via queue/rotation), filesystem
  • Détection limites cgroup mémoire (v2) + exposition ContainerMemoryLimitBytes
  • Entité Agent + migration (AddAgentMemoryDiskInventory) : MemTotalBytes, SwapTotalBytes, liste disques (JSON ou table liée)
  • Heartbeat : transporter l'inventaire (refresh périodique, pas à chaque tick)
  • UI Admin : section mémoire (barre host + process + swap) et disques (par montage) sur la page agent
  • Tests : parsing meminfo, montages, type SSD/HDD

🧪 Critères d'acceptation

  • L'UI distingue RAM machine (ex. 64 Go) vs RAM process du conteneur (ex. 1,2 Go) vs limite cgroup (ex. 4 Go)
  • Swap total/libre remonté
  • Les disques apparaissent par point de montage avec type (SSD/HDD/NVMe) et usage
  • make test vert

📁 Fichiers concernés

src/Heimdall.Agent/Services/SystemMetricsProvider.cs, src/Heimdall.Agent/Services/DiskInventoryProvider.cs (nouveau), src/Heimdall.Domain/Entities/Agent.cs, src/Heimdall.Infrastructure/Data/Migrations/, src/Heimdall.Web/Pages/Agents/AgentDetail.razor, tests/

⚠️ Impact

⚠️ MemoryUsageBytes change de sens (process → machine) : mettre à jour les vues UI/jauge existantes qui l'affichent (Dashboard, AllAgents, MonitoringHub).

📝 Notes

Corrige une ambiguïté existante : la « RAM utilisée » affichée est aujourd'hui celle du process, pas de la machine.


Maquette

Ce ticket est couvert par la maquette du ticket #86 — UI Admin — page inventaire matériel agent (pièce maîtresse du lot télémétrie) : la section « Inventaire » de #86 maquette l'affichage des métriques et specs correspondantes (voir #86, section Maquette).

  • Maquette de référence : #86 (PNG + README attachés)
  • Application Penpot : différée (plugin MCP non connecté)
## 🎯 Contexte Aujourd'hui `MemoryUsageBytes` = **WorkingSet64 du process .NET** (pas la RAM de la machine !) et `DiskUsagePercent` ne regarde que la racine du conteneur. Pour piloter des agents (et savoir si un site peut prendre plus de caméras/GPU), il faut la RAM **machine** totale/utilisée/swap et les disques réels avec capacité et type. ## 📚 Référence spec / décision Décision : deux niveaux de métriques — **machine (host)** et **process/conteneur** — remontés distinctement. - Mémoire host : `/proc/meminfo` → MemTotal, MemAvailable, MemFree, SwapTotal, SwapFree, Buffers/Cached (Linux) ; sysctl `hw.memsize` + `vm.swapusage` (macOS) - Mémoire process : WorkingSet64/PagedMemorySize64 conservés mais étiquetés `process` - **Docker** : les limites mémoire cgroup (`/sys/fs/cgroup/memory.max` v2, `memory.current`) exposées comme `ContainerMemoryLimit` — le conteneur peut avoir 4 Go alors que le host en a 64 - Disques : `df`/`/proc/mounts` → par point de montage : capacité, libre, usage %, filesystem, **type SSD/HDD/NVMe** (via `/sys/block/*/queue/rotation` + modèle via `/sys/block/*/device/model`) ## 🔍 État actuel (vérifié dans le code) `SystemMetricsProvider` : `MemoryUsageBytes = Process.GetCurrentProcess().WorkingSet64` (process), `GetTotalMemory` lit MemTotal (host), `GetDiskUsage` = DriveInfo de `AppContext.BaseDirectory` (racine du conteneur). `Agent` : `MemoryMb` (long, mis une fois via UpdateCapabilities) + MemoryUsageBytes live. Pas de swap, pas de disques multiples, pas de type SSD/HDD. ## 🧩 À faire - [ ] Refonte `SystemMetricsProvider` : séparer host vs process (record `SystemMetrics` enrichi : MemTotalBytes, MemAvailableBytes, SwapTotalBytes, SwapFreeBytes, ProcessMemoryBytes, ContainerMemoryLimitBytes?) - [ ] Collecteur disques : `DiskInventoryProvider` — énumérer les montages (`/proc/mounts`), capacité/libre/type (SSD/HDD via `queue/rotation`), filesystem - [ ] Détection limites cgroup mémoire (v2) + exposition `ContainerMemoryLimitBytes` - [ ] Entité `Agent` + migration (`AddAgentMemoryDiskInventory`) : MemTotalBytes, SwapTotalBytes, liste disques (JSON ou table liée) - [ ] Heartbeat : transporter l'inventaire (refresh périodique, pas à chaque tick) - [ ] UI Admin : section mémoire (barre host + process + swap) et disques (par montage) sur la page agent - [ ] Tests : parsing meminfo, montages, type SSD/HDD ## 🧪 Critères d'acceptation - [ ] L'UI distingue RAM machine (ex. 64 Go) vs RAM process du conteneur (ex. 1,2 Go) vs limite cgroup (ex. 4 Go) - [ ] Swap total/libre remonté - [ ] Les disques apparaissent par point de montage avec type (SSD/HDD/NVMe) et usage - [ ] `make test` vert ## 📁 Fichiers concernés src/Heimdall.Agent/Services/SystemMetricsProvider.cs, src/Heimdall.Agent/Services/DiskInventoryProvider.cs (nouveau), src/Heimdall.Domain/Entities/Agent.cs, src/Heimdall.Infrastructure/Data/Migrations/, src/Heimdall.Web/Pages/Agents/AgentDetail.razor, tests/ ## ⚠️ Impact ⚠️ `MemoryUsageBytes` change de sens (process → machine) : mettre à jour les vues UI/jauge existantes qui l'affichent (Dashboard, AllAgents, MonitoringHub). ## 📝 Notes Corrige une ambiguïté existante : la « RAM utilisée » affichée est aujourd'hui celle du process, pas de la machine. --- ## Maquette Ce ticket est couvert par la maquette du ticket **#86 — UI Admin — page inventaire matériel agent** (pièce maîtresse du lot télémétrie) : la section « Inventaire » de #86 maquette l'affichage des métriques et specs correspondantes (voir #86, section Maquette). - Maquette de référence : #86 (PNG + README attachés) - Application Penpot : différée (plugin MCP non connecté)
Author
Owner

Maquette : couverte par le ticket #86 (inventaire matériel agent) — section ## Maquette ajoutée au corps.

Maquette : couverte par le ticket #86 (inventaire matériel agent) — section ## Maquette ajoutée au corps.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
nonobis/Heimdall#83
No description provided.