Dater les enregistrements FSEvents sans horodatage
Les enregistrements FSEvents n'ont pas d'heure. Construire des fenêtres fiables à partir des mtimes des journaux .fseventsd, de l'uuid et des chemins datés.
En bref. Un enregistrement a été écrit dans son fichier journal entre la date de modification du fichier précédent et la date de modification de son propre fichier. Cette fenêtre, ajoutée à l'ordre donné par les identifiants d'événement, est tout ce que FSEvents peut vous dire sur le temps. Tout le reste (un chemin daté, un horodatage APFS, une entrée des Unified Logs) relève de la corrélation. Présentez des plages et nommez votre point d'ancrage.
Pourquoi il n'y a pas d'horodatage
Chaque enregistrement contient un chemin, un identifiant d'événement, des flags et (dans les versions récentes) un node ID. L'identifiant d'événement est un compteur, pas une horloge. Les seules dates disponibles sont les métadonnées du système de fichiers des fichiers journaux eux-mêmes et de fseventsd-uuid.
La méthode des fenêtres
fseventsd met les événements en mémoire tampon et les ajoute au fichier journal courant, en commençant un nouveau fichier de temps à autre. Ainsi, pour les fichiers journaux d'un volume, triés par identifiant d'événement :
- la date de modification d'un fichier correspond au moment où ses derniers enregistrements ont été écrits : c'est une borne supérieure pour tous ses enregistrements ;
- la date de modification du fichier précédent correspond à peu près au début de ce fichier : c'est une borne inférieure ;
- pour le fichier le plus ancien, la date de modification de fseventsd-uuid (début de cet historique) est la seule borne inférieure, et elle peut remonter à plusieurs mois.
Exemple tiré de l'échantillon fourni avec le FSEvents Parser :
| Fichier journal | mtime (UTC) | Fenêtre de ses enregistrements |
|---|---|---|
…12a4439d | 09:58:40 | 09:31:07 → 09:58:40 |
…12a444cf | 10:09:55 | 09:58:40 → 10:09:55 |
…12a44759 | 10:23:18 | 10:09:55 → 10:23:18 |
Un LaunchAgent créé dans le troisième fichier a été écrit entre 10:09:55 et 10:23:18 UTC. C'est ce qu'il faut affirmer, et non « 10:23:18 ».
Resserrer la fenêtre
- L'ordre des événements. Au sein d'une fenêtre, les enregistrements sont ordonnés. Si l'enregistrement du LaunchAgent vient après une modification des préférences de Terminal et avant une écriture dans TCC.db, et que l'un de ces événements peut être daté par ailleurs, la fenêtre se réduit.
- Les chemins datés. Les journaux en rotation, rapports de diagnostic et instantanés portent souvent une date dans leur nom (
…-2026-09-14-091214.ips). Lorsqu'un tel chemin estCreated, il sert de point d'ancrage aux identifiants d'événement voisins. FSEventsParser utilise un ensemble de chemins connus pour sa colonne de date approximative ; le FSEvents Parser liste, pour chaque fichier journal, les dates repérées dans les chemins créés, à titre d'indices. - Les autres artefacts. Les dates de création et de modification APFS de l'élément s'il existe encore, les événements de quarantaine pour les téléchargements, les Unified Logs pour les chargements launchd, les lignes de TCC.db avec leurs propres horodatages.
Quand la méthode échoue
- Copie sans les dates. Un glisser-déposer dans le Finder vers certaines destinations, AirDrop, l'e-mail ou un envoi négligent attribue à chaque fichier l'heure de la copie. Symptôme : tous les fichiers journaux partagent à peu près la même mtime. Le parseur le signale et les fenêtres doivent alors être ignorées ; l'ordre reste valable.
- Mtimes dans le désordre. Un fichier dont la mtime est antérieure à celle du fichier précédent (changement d'horloge, fichiers « touchés », outils qui réécrivent les fichiers). Ce fichier n'a alors pas de borne inférieure.
- Heures locales des ZIP. Le format ZIP stocke les dates sans fuseau horaire, sauf s'il contient le champ d'horodatage étendu ; une collecte zippée dans un fuseau et lue dans un autre décale chaque fenêtre de l'écart. Préférez
tar.gz. - Longues périodes d'inactivité. Sur une machine en veille pendant des jours, une fenêtre peut couvrir plusieurs jours ; la borne supérieure reste fiable.
- Le journal courant. Le fichier le plus récent peut être encore ouvert lors de la collecte ; sa mtime est alors l'heure de la collecte ou celle de la dernière écriture.
Filtrer par date
Deux questions appellent deux filtres différents, que la plage temporelle du parseur propose sous forme de champ temporel :
- Fenêtre approximative (chevauchement) : un enregistrement est conservé si sa fenêtre chevauche la plage. Rien de ce qui pourrait se trouver dans la plage n'est manqué ; certains enregistrements extérieurs peuvent être inclus.
- Écriture du fichier journal (borne supérieure) : un enregistrement est conservé si la mtime de son fichier se trouve dans la plage. C'est plus précis, mais un enregistrement écrit juste avant une écriture du journal tombant hors de la plage sera manqué.
Utilisez le premier pour être exhaustif, le second pour cibler. Dans les deux cas, la plage s'applique à chaque vue, compteur, constat et export, et elle est conservée dans l'URL (#from=…&to=…) : un lien partagé rouvre donc la même fenêtre.
FAQ
Quelle est la précision d'une fenêtre temporelle FSEvents ?
Elle correspond à l'intervalle entre deux écritures de fichiers journaux : généralement de quelques minutes à quelques heures sur un Mac actif, beaucoup plus sur un Mac inactif. C'est toujours une plage, jamais un instant.
Et si tous les fichiers journaux FSEvents ont la même date de modification ?
Ils ont presque certainement été copiés sans préserver les dates. L'ordre des enregistrements reste valable, mais les fenêtres n'ont plus de sens ; refaites la collecte avec tar, ditto ou UAC, comme décrit dans le guide de collecte.