Voir au-delà
de la surface.

Observez ce que font vos programmes sous Linux, du processeur au disque.
Gardez la preuve à côté de chaque chiffre.

UN SEUL OUTIL / UN VOCABULAIRE COMMUN

Mesurer le système.
Garder le sens.

Suivez un programme depuis l’activité du noyau jusqu’au temps qu’il passe à attendre. Profils, compteurs et événements partagent un même modèle, et leurs limites restent visibles.

Partir d’une question.
Lancez une enquête avec omn cpu, omn mem ou omn latency. Nommez une source quand vous voulez un contrôle précis.
Voir ce qui est disponible ici.
omn list sonde cette machine. Droits manquants, matériel non pris en charge et collecteurs absents sont expliqués clairement.
Emporter la preuve.
Exportez résultats et profils. Gardez la méthode utilisée, l’état de la machine et le coût de l’observation à côté des chiffres.

NEUF FAMILLES / DES QUESTIONS LIÉES

Chaque couche a
une histoire à raconter.

Choisissez la partie du système que vous voulez comprendre. Ouvrez une famille pour lire son histoire : la question, ses sources, une vraie exécution et ses limites.

SUIVRE LE SIGNAL / LE SCÉNARIO SUZANNE

Une requête.
Chaque couche en vue.

Demandez à un moteur de dessiner Suzanne en 3D et d’enregistrer l’image. Suivez chaque passage de relais à travers la machine.

Scénario de capture prévu sous Linux · cette séquence est une illustration. Une seule machine ; l’attribution côté carte graphique dépend du moteur et du pilote. L’écriture d’un fichier et son enregistrement durable sur le disque sont deux choses distinctes.

CONÇU POUR LA PREUVE

Voir, c’est bien.
Savoir pourquoi, c’est mieux.

Un chiffre plausible ne suffit pas. Sachez ce qui l’a produit, ce qui a été perdu et ce qui justifie son attribution.

IDENTITÉCLÉRÉVEILTEMPS

Des liens, avec leurs preuves.

Une identité transmise et deux événements proches dans le temps ne sont pas le même genre de preuve. Omniscient vous dit lequel justifie le lien.

Comprendre les preuves
[ kernel ]
↓
[ omn ]

Direct par principe.

eBPF, perf_event_open, procfs, sysfs et netlink. Sans perf, bpftrace ni bcc en dessous.

◴ → ◷

Enregistrer. Revoir.

Enregistrez une exécution et rejouez-la dans le terminal. Changez de vue, gardez le contexte.

scope: package
target: process
↳ request refused

Des limites honnêtes.

Si une source ne peut pas répondre à une question, le validateur explique pourquoi — au lieu de répondre à une autre question.

VOTRE TERMINAL / PLUS DE DIMENSIONS

La même exécution.
Un autre point de vue.

Choisissez une requête et gardez-la en vue d’une vue à l’autre. Examinez les fils d’exécution ou les piles d’appels du processeur — le tout tiré d’une seule exécution enregistrée.

● ● ●omn top / request120 × 40
omn top │ fixture many-requests │ 15.8s                           view: snapshot │ collectors ≥5.21% │ target 0.35% cpu 
 1 system  2 flame  3 ledger  4 request  5 timebar  6 heatmap  7 lanes  8 wake  9 flows  0 process                      
┌ request -- what one request costs ───────────────────────────────────────────────────────────────────────────────────┐
│300 requests served by server (pid 2619831) · slowest a0d7 5.49ms · median 2.18ms · in order of arrival  168 late degr│
│                                                                                                                      │
│  req      span  its life by state, to one scale: the slowest is 5.49ms             mostly                            │
│▶ a001    159µs  ░█                                                                 net in 75.5% · on cpu 24.5%       │
│  a002   2.33ms  ░█▓▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                                       lock/sleep 89.0%                  │
│  a003   5.00ms  ██▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄        disk 96.2%                        │
│  a004   2.21ms  ░░░░░░░░░░░░░░░░░░░░░░░░░░                                         net in 98.7%                      │
│  a005   56.8µs  ░                                                                  net in 50.5% · on cpu 49.5%       │
│  a006   2.31ms  ░▓▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                                        lock/sleep 90.6%                  │
│  a007   4.99ms  ░█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄        disk 95.3%                        │
│  a008   2.17ms  ░░░░░░░░░░░░░░░░░░░░░░░░░░                                         net in 98.7%                      │
│  a009    123µs  ░                                                                  net in 77.7% · on cpu 22.3%       │
│  a00a   2.21ms  █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                                         lock/sleep 94.6%                  │
│  a00b   5.00ms  ░█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄        disk 95.3%  +289 more ↓           │
│  ░░ net in   ██ on cpu   ▓▓ run queue   ▀▀ lock/sleep   ▄▄ disk   ░░ net out                                         │
│                                                                                                                      │
│── a001 · 159µs from its first byte in to its last byte out · thread 2619831 ─────────────────────────────────────────│
│            ┊0                  ┊50.0µs              ┊100µs                                                           │
│  net in    ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░                  120µs before start                    │
│  serving                                                    █████████████████  39.0µs from start to done             │
│  on device                                                                     no block request                      │
│  net out                                                                       gone when done                        │
│  inside `serving` the states are drawn by share: net.request sums them, it does not keep their order                 │
│                                                                                                                      │
│  where its 159µs went               evidence                       its share of each resource                        │
│  ░ net in        120µs   75.5% ░░░           by socket 160254      cpu        39.0µs: 0.07% of the 55.9ms server took│
│  █ on cpu       39.0µs   24.5% █                                              off cpu 0 times, preempted 0           │
│  ▓ run queue         ·                                             disk       no block request issued                │
│  ▀ lock/sleep        ·                                             network    in 120µs · out 0ns                     │
│  ▄ disk              ·                                                        51B read · 59B queued                  │
│  ░ net out           ·                                                                                               │
│  no decomposition in this run: the evidence is not graded                                                            │
│                                                                                                                      │
│                                                                                                                      │
│  what sets it apart from the other 299 requests: ░ net in +93.3µs (theirs 26.6µs)                                    │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
q quit  ←/→ tab view  1-9 jump  f clear focus  ? help  ↑/↓ request  s sort  enter focus it, then its lanes  l its thread

Une requête au premier plan — ce qu’elle coûte, de son arrivée à la réponse. Gardez son contexte dans les autres vues.

Captures du jeu de test many-requests de la galerie des vues, dessinées en 120×40 et vérifiées par tests/view_snapshots.rs. Couleurs adaptées à la palette de cette page. Les écrans du programme restent en anglais.

DES ENQUÊTES REPRODUCTIBLES

La mesure, écrite comme du code.

Essayez une mesure dans le terminal, puis gardez-la dans un fichier de session. YAML, JSON et TOML décrivent les mêmes requêtes. Le programme fait partie de la requête : le lancer en fait à la fois la cible et l’horloge.

Parcourir les sessions
# omn -f examples/mem-rss-run.yml
name: resident memory of a launched program
requests:
  - label: rss
    source: mem.rss
    target:
      launch: [python3, -c, "..."]
    mode: poll@100ms
    emit: [timeline, summary]
    keys: [task, cgroup]

EN PRATIQUE / LES PREUVES

Un problème.
Ce qui a changé.

Choisissez une cible pour lire ce qui s’est passé : le problème, la découverte et le résultat. Chaque histoire cite ses preuves et l’étendue de sa validation.

Charge de validation contrôlée

Une requête lente, remontée jusqu’au verrou et à qui le tenait.

Problème
Une requête peut attendre dans l’application, dans l’ordonnanceur ou dans la couche des disques. Une durée totale ne dit pas quelle partie l’a retardée.
Découverte
Un serveur local déclarait l’identité de ses requêtes par USDT et la transmettait au travail qui en découlait. Un délai de verrou injecté volontairement est apparu sur la ligne de la requête elle-même : 40,06 ms, avec le nom du thread qui tenait le verrou.
Résultat
La mesure a attribué l’attente grâce à l’identité transmise. Le délai injecté donnait une valeur connue pour vérifier le résultat.

Un scénario de serveur contrôlé : ce n’est ni un incident de production, ni l’intégration de rendu Suzanne prévue.

Omniscient · STATE.md, cas vertical · docs/briefs/wave-9-vertical.md

TESTÉ AVEC DISTROPROOF / OCTOBRE 2026

Des noyaux différents.
Des limites explicites.

Les versions installées ont été testées sur 17 images de distributions et 5 variantes, 3 images arm64 et 8 conteneurs sans root, de Linux 4.15 à 7.2, avec glibc et musl. Le même binaire a trouvé 36 sources utilisables sur Ubuntu 18.04 et 96 sur Fedora — avec une raison pour chaque refus.

La disponibilité confrontée à la réalité.

La campagne a trouvé 27 défauts : 13 dans l’outil et 14 dans ses tests. Au départ, 158 exécutions de sources étaient annoncées utilisables mais refusées au démarrage. Après les corrections, plus aucune. Chaque raison de refus concordait avec la lecture indépendante d’envprobe sur la même machine, sur les 21 cibles.

Voir l’étude de cas de distroproof →

Des fonctionnalités, pas des numéros de version.

De vraies sondes repèrent la politique perf de Debian, les tables BPF comptées dans memlock sur 5.10, les restrictions du lockdown et l’absence de traceur de fonctions sur Alpine. Les rétroportages de RHEL sont détectés comme des fonctionnalités au lieu d’être écartés à cause de l’âge du noyau.

Deux archives publiées.

L’archive glibc vise glibc 2.17 et plus. Alpine a une archive musl native, avec un moteur statique et un petit module de préchargement musl. Les sources NVIDIA ne sont pas disponibles dans la version statique, car elles ont besoin de charger des bibliothèques dynamiques.

Ce qui reste ouvert.

Les paires de référence face à perf, bpftrace, bcc et aux autres outils témoins des distributions tournent sur la chaîne devutils : neuf cibles, toutes les vérifications tiennent dans les dernières exécutions. Une paire est ignorée, avec sa raison, quand une distribution n’a pas l’outil témoin ou que celui-ci ne se charge pas. Les images arm64 sont émulées sur une machine x86_64.

Voir les dernières exécutions de la chaîne → Lire les constats et les preuves →

OPEN SOURCE / CONÇU POUR LINUX

Posez à votre machine
une meilleure question.

Choisissez l’archive adaptée à votre bibliothèque C, ou compilez depuis les sources. Lancez omn list pour voir ce que cette machine peut fournir ; les sources eBPF demandent des droits et des réglages du noyau adaptés.

Installer Omniscient Commencer à observer
omn top -- ./your-program
Archives x86_64 : glibc 2.17+ ou musl · Rust 1.82+ pour compiler · la disponibilité est sondée source par source