時刻のずれと欠落を考慮したタイムライン
ws8の時計が5秒進んでいた例を補正し、同時刻に見える別端末の活動や収集停止期間を確認します。確実な関係を残しつつ、順序を決められない部分を表現する方法を学びます。
説明
複数端末の時系列を再構成するときは、時計のずれと測定誤差を考慮します。補正後の時刻が近い行でも、因果関係があるとは限りません。直接の関係を示す資料と時間上の近さを分けます。
ws8の時計が5秒進んでいた例を補正し、同時刻に見える別端末の活動や収集停止期間を確認します。確実な関係を残しつつ、順序を決められない部分を表現する方法を学びます。
1端末の時計差を確認する
offsetは基準時刻に対する進み、uncertaintyは補正後の誤差幅です。単位は秒です。
from oplab import *
db=connect(8)
show(db, 'SELECT端末の時計差を確認する * FROM clocks ORDER BY host')ws8は5秒進み、ws9の誤差幅は3秒です。補正値があっても完全な時刻精度が得られるわけではありません。
2補正した時刻で並べる
記録時刻から進みの分を引きます。
show(db, 'SELECT補正した時刻で並べる r.id,r.host,r.t,c.offset,r.t-c.offset AS corrected FROM records r JOIN clocks c USING(host) ORDER BY corrected,r.id')e2とe4は補正後102ですが、同じ活動とは限りません。異なる主体の同時活動が同じ時間軸に現れています。
3誤差を含む範囲を表示する
補正時刻の前後にuncertaintyを加減します。
show(db, 'SELECT誤差を含む範囲を表示する r.id,r.t-c.offset-c.uncertainty AS earliest,r.t-c.offset+c.uncertainty AS latest FROM records r JOIN clocks c USING(host) ORDER BY earliest,r.id')e4の範囲は99〜105秒です。近い時刻の行に厳密な前後関係を付けるには、時刻以外の根拠が必要です。
4直接結ばれた経路を確認する
記録の順番とは独立に、コピーとファイルオープンの証拠を読みます。
show(db, 'SELECT直接結ばれた経路を確認する e.source,e.target,e.evidence FROM edges e ORDER BY source')e1→e2→e3は証拠に対応します。e4を途中に挿入する根拠はありません。
5収集停止の範囲を確認する
gapsの時刻は端末側の未補正の値です。時計表を使って同じ基準へ直します。
show(db, 'SELECT収集停止の範囲を確認する g.host,g.start-c.offset AS start_utc,g.end-c.offset AS end_utc,g.reason FROM gaps g JOIN clocks c USING(host)')ws8のプロセス収集は基準98〜103秒が欠落しています。ファイル記録があることから、別のプロセス記録も完全だとは言えません。
6関係が未確認の活動を抽出する
証拠付きの辺を持たない行を、無理に主経路へ結ばず残します。
show(db, 'SELECT関係が未確認の活動を抽出する r.id,r.host,r.kind FROM records r WHERE NOT EXISTS (SELECT 1 FROM edges e WHERE e.source=r.id OR e.target=r.id)')e4は他の活動との関係が未確認です。独立した活動として記録し、対応する証拠を残します。
まとめ
e4は他の活動との関係が未確認です。独立した活動として記録し、対応する証拠を残します。
表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。
操作履歴と解説を振り返れます。
Python 3.15 / SQLite・固定の調査記録
from oplab import *
db=connect(8)
show(db, 'SELECT * FROM clocks ORDER BY host')host | offset | uncertainty ws7 | 0 | 1 ws8 | 5 | 1 ws9 | 0 | 3
show(db, 'SELECT r.id,r.host,r.t,c.offset,r.t-c.offset AS corrected FROM records r JOIN clocks c USING(host) ORDER BY corrected,r.id')id | host | t | offset | corrected e1 | ws7 | 100 | 0 | 100 e2 | ws8 | 107 | 5 | 102 e4 | ws9 | 102 | 0 | 102 e3 | ws8 | 109 | 5 | 104
show(db, 'SELECT r.id,r.t-c.offset-c.uncertainty AS earliest,r.t-c.offset+c.uncertainty AS latest FROM records r JOIN clocks c USING(host) ORDER BY earliest,r.id')id | earliest | latest e1 | 99 | 101 e4 | 99 | 105 e2 | 101 | 103 e3 | 103 | 105
show(db, 'SELECT e.source,e.target,e.evidence FROM edges e ORDER BY source')source | target | evidence e1 | e2 | x1 e2 | e3 | file-open record o1
show(db, 'SELECT g.host,g.start-c.offset AS start_utc,g.end-c.offset AS end_utc,g.reason FROM gaps g JOIN clocks c USING(host)')host | start_utc | end_utc | reason ws8 | 98 | 103 | process collector stopped
show(db, 'SELECT r.id,r.host,r.kind FROM records r WHERE NOT EXISTS (SELECT 1 FROM edges e WHERE e.source=r.id OR e.target=r.id)')id | host | kind e4 | ws9 | process
演習完了