FEAT: Télémétrie agent — inventaire CPU complet (marque, modèle, cœurs physiques/logiques, fréquence, flags) #82

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

🎯 Contexte

Objectif : maximum d'informations sur les machines des agents, même dockerisées. Le CPU est la première chose à connaître : marque, modèle exact, nombre de cœurs physiques vs logiques, threads, fréquence, architecture, cache, jeux d'instructions (AVX/AVX2/FMA — importants pour les perfs ONNX Runtime). L'entité Agent ne stocke qu'un CpuCores (int) et le SystemMetricsProvider n'expose pas la topologie.

📚 Référence spec / décision

Décision : inventaire capturé au démarrage de l'agent (et rafraîchi périodiquement), remonté au central, persisté sur l'entité Agent.

  • Sources Linux : /proc/cpuinfo (model name, vendor, physical id, core id, cpu cores, siblings, flags, cpu MHz), /sys/devices/system/cpu/ (topologie), lscpu si dispo
  • Docker : /proc/cpuinfo reflète le host par défaut, MAIS avec --cpuset-cpus seuls les CPUs alloués sont visibles → détecter la limite cgroup (/sys/fs/cgroup/cpu.max v2, cpuset.cpus) et l'exposer séparément des specs host
  • CpuCores (int) → structuré : CpuVendor, CpuModel, CpuArchitecture, PhysicalCores, LogicalCores, ThreadsPerCore, CpuFrequencyMhz, CpuFlags (AVX/AVX2/FMA/AVX512), CpuCacheBytes

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

Agent entity : CpuCores (int, mis via UpdateCapabilities) — aucune marque/modèle/fréquence. SystemMetricsProvider.GetCpuCount() compte les lignes cpuN de /proc/stat (logiques), GetCpuUsage utilise ce compte (correct depuis le fix #22). Pas de lecture de /proc/cpuinfo, pas de distinction physique/logique, pas de conscience cgroup/cpuset.

🧩 À faire

  • Collecteur CpuInfoProvider : parse /proc/cpuinfo (vendor, model name, physical id/core id → cœurs physiques vs logiques, flags, MHz), topologie /sys/devices/system/cpu/
  • Détection conteneur : lire /proc/self/cgroup (v2) + /sys/fs/cgroup/cpuset.cpus et cpu.max → exposer ContainerCpuLimit séparé du host
  • Extension entité Agent + migration EF (AddAgentCpuInventory) : champs structurés CPU (voir spec)
  • Heartbeat : transporter l'inventaire CPU (au register + refresh périodique 5 min, pas à chaque tick)
  • UI Admin : afficher marque/modèle/fréquence/cœurs sur la page agent (badge compact + section détail)
  • Tests : parsing cpuinfo (fixture multi-socket, hyperthreading), cgroup v2, fallback non-Linux

🧪 Critères d'acceptation

  • Un agent Intel i5-10600K déclare : vendor GenuineIntel, modèle exact « Intel(R) Core(TM) i5-10600K CPU @ 4.10GHz », 6 physiques / 12 logiques, AVX2 présent
  • En conteneur avec --cpuset-cpus=0-1 : specs host complètes + limite conteneur 2 CPUs exposée distinctement
  • Migration EF appliquée sans casser les agents existants (champs nullable)
  • make test vert

📁 Fichiers concernés

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

⚠️ Impact

Migration EF + évolution du contrat register/heartbeat (rétrocompatible : champs optionnels).

📝 Notes

Base de la télémétrie : les tickets mémoire/disque/GPU/OS/UI s'appuient sur la même architecture de collecte + remontée + persistance.

## 🎯 Contexte Objectif : **maximum d'informations sur les machines des agents**, même dockerisées. Le CPU est la première chose à connaître : marque, modèle exact, nombre de cœurs **physiques** vs **logiques**, threads, fréquence, architecture, cache, jeux d'instructions (AVX/AVX2/FMA — importants pour les perfs ONNX Runtime). L'entité `Agent` ne stocke qu'un `CpuCores` (int) et le `SystemMetricsProvider` n'expose pas la topologie. ## 📚 Référence spec / décision Décision : inventaire capturé au démarrage de l'agent (et rafraîchi périodiquement), remonté au central, persisté sur l'entité Agent. - Sources Linux : `/proc/cpuinfo` (model name, vendor, physical id, core id, cpu cores, siblings, flags, cpu MHz), `/sys/devices/system/cpu/` (topologie), `lscpu` si dispo - **Docker** : `/proc/cpuinfo` reflète le host par défaut, MAIS avec `--cpuset-cpus` seuls les CPUs alloués sont visibles → détecter la limite cgroup (`/sys/fs/cgroup/cpu.max` v2, `cpuset.cpus`) et l'exposer séparément des specs host - `CpuCores` (int) → structuré : `CpuVendor`, `CpuModel`, `CpuArchitecture`, `PhysicalCores`, `LogicalCores`, `ThreadsPerCore`, `CpuFrequencyMhz`, `CpuFlags` (AVX/AVX2/FMA/AVX512), `CpuCacheBytes` ## 🔍 État actuel (vérifié dans le code) `Agent` entity : `CpuCores` (int, mis via `UpdateCapabilities`) — aucune marque/modèle/fréquence. `SystemMetricsProvider.GetCpuCount()` compte les lignes `cpuN` de `/proc/stat` (logiques), `GetCpuUsage` utilise ce compte (correct depuis le fix #22). Pas de lecture de `/proc/cpuinfo`, pas de distinction physique/logique, pas de conscience cgroup/cpuset. ## 🧩 À faire - [ ] Collecteur `CpuInfoProvider` : parse `/proc/cpuinfo` (vendor, model name, physical id/core id → cœurs physiques vs logiques, flags, MHz), topologie `/sys/devices/system/cpu/` - [ ] Détection conteneur : lire `/proc/self/cgroup` (v2) + `/sys/fs/cgroup/cpuset.cpus` et `cpu.max` → exposer `ContainerCpuLimit` séparé du host - [ ] Extension entité `Agent` + migration EF (`AddAgentCpuInventory`) : champs structurés CPU (voir spec) - [ ] Heartbeat : transporter l'inventaire CPU (au register + refresh périodique 5 min, pas à chaque tick) - [ ] UI Admin : afficher marque/modèle/fréquence/cœurs sur la page agent (badge compact + section détail) - [ ] Tests : parsing cpuinfo (fixture multi-socket, hyperthreading), cgroup v2, fallback non-Linux ## 🧪 Critères d'acceptation - [ ] Un agent Intel i5-10600K déclare : vendor GenuineIntel, modèle exact « Intel(R) Core(TM) i5-10600K CPU @ 4.10GHz », 6 physiques / 12 logiques, AVX2 présent - [ ] En conteneur avec `--cpuset-cpus=0-1` : specs host complètes + limite conteneur 2 CPUs exposée distinctement - [ ] Migration EF appliquée sans casser les agents existants (champs nullable) - [ ] `make test` vert ## 📁 Fichiers concernés src/Heimdall.Agent/Services/CpuInfoProvider.cs (nouveau), src/Heimdall.Agent/Services/SystemMetricsProvider.cs, src/Heimdall.Agent/Services/AgentRegistrationService.cs (register payload), src/Heimdall.Domain/Entities/Agent.cs, src/Heimdall.Infrastructure/Data/Migrations/, src/Heimdall.Web/Pages/Agents/AgentDetail.razor, tests/ ## ⚠️ Impact Migration EF + évolution du contrat register/heartbeat (rétrocompatible : champs optionnels). ## 📝 Notes Base de la télémétrie : les tickets mémoire/disque/GPU/OS/UI s'appuient sur la même architecture de collecte + remontée + persistance.
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#82
No description provided.