一覧OP-04-3 · Linuxの認証・実行・変更の記録

journalの時刻補正と並べ替え

時計が10秒戻った記録を、実時刻順と起動区間内の順序で並べ直します。シェル履歴も確認し、入力履歴と実行結果の証拠が持つ違いを学びます。

説明

端末の実時刻は同期処理などで前後に動くことがあります。journalの起動IDと起動後の単調時刻を使うと、同じ起動区間の順序を追えます。単調時刻は再起動をまたいでそのまま比較できません。

時計が10秒戻った記録を、実時刻順と起動区間内の順序で並べ直します。シェル履歴も確認し、入力履歴と実行結果の証拠が持つ違いを学びます。

1実時刻だけで並べる

realtimeは比較用の秒値、monoは起動後の単調時刻です。

from oplab import * db=connect(4) show(db, 'SELECT実時刻だけで並べる * FROM journal ORDER BY realtime,id')

時計変更のj2が、セッション開始j1より前に見えます。実時刻の並びだけでは因果を逆に説明してしまうことがあります。

2同じ起動内の順序を確認する

boot=b1の中ではmonoを使って順に読みます。

show(db, 'SELECT同じ起動内の順序を確認する id,boot,mono,realtime,message FROM journal WHERE boot="b1" ORDER BY mono')

j1、j2、j3の順です。時計が戻っても、同じ起動内の単調時刻は経過の把握に役立ちます。

3前の行からの変化量を計算する

LAGで同じ起動区間の直前の値を取り出します。

show(db, 'SELECT前の行からの変化量を計算する id,mono-LAG(mono) OVER(PARTITION BY boot ORDER BY mono) AS mono_delta,realtime-LAG(realtime) OVER(PARTITION BY boot ORDER BY mono) AS wall_delta FROM journal ORDER BY boot,mono')

j2は経過10秒に対して実時刻が-10秒です。外部ログとの照合では、この時計変動を補正条件として残します。

4再起動後を別に扱う

起動IDごとに開始と終了の単調時刻を集計します。

show(db, 'SELECT再起動後を別に扱う boot,MIN(mono),MAX(mono),COUNT(*) FROM journal GROUP BY boot ORDER BY boot')

b2の5秒をb1の100秒より前に並べてはいけません。起動間の関係には実時刻や外部の観測を使います。

5シェル履歴の情報量を確認する

historyのtは取得できた時刻で、NULLは不明を表します。

show(db, 'SELECTシェル履歴の情報量を確認する * FROM history ORDER BY id')

入力された文字列はありますが、時刻と終了状態がありません。履歴行だけでは成功した読み出しや出力内容まで確定しません。

6時刻不明の履歴を数える

既知の時間軸へ無理に配置できない行を明示します。

show(db, 'SELECT時刻不明の履歴を数える COUNT(*) AS commands_without_time FROM history WHERE t IS NULL')

2行とも発生時刻を配置できません。journalの時系列と履歴の内容は、分かる範囲の違う資料として残します。

まとめ

2行とも発生時刻を配置できません。journalの時系列と履歴の内容は、分かる範囲の違う資料として残します。

表示された証拠IDと検索条件を残すと、調査結果を元の記録までたどれます。

操作履歴と解説を振り返れます。

Python 3.15 / SQLite・固定の調査記録

1
from oplab import * db=connect(4) show(db, 'SELECT * FROM journal ORDER BY realtime,id')
id | boot | mono | realtime | message
j2 | b1 | 110 | 990 | clock changed
j1 | b1 | 100 | 1000 | session opened
j3 | b1 | 120 | 1000 | report started
j4 | b2 | 5 | 1010 | boot complete
2
show(db, 'SELECT id,boot,mono,realtime,message FROM journal WHERE boot="b1" ORDER BY mono')
id | boot | mono | realtime | message
j1 | b1 | 100 | 1000 | session opened
j2 | b1 | 110 | 990 | clock changed
j3 | b1 | 120 | 1000 | report started
3
show(db, 'SELECT id,mono-LAG(mono) OVER(PARTITION BY boot ORDER BY mono) AS mono_delta,realtime-LAG(realtime) OVER(PARTITION BY boot ORDER BY mono) AS wall_delta FROM journal ORDER BY boot,mono')
id | mono_delta | wall_delta
j1 | NULL | NULL
j2 | 10 | -10
j3 | 10 | 10
j4 | NULL | NULL
4
show(db, 'SELECT boot,MIN(mono),MAX(mono),COUNT(*) FROM journal GROUP BY boot ORDER BY boot')
boot | MIN(mono) | MAX(mono) | COUNT(*)
b1 | 100 | 120 | 3
b2 | 5 | 5 | 1
5
show(db, 'SELECT * FROM history ORDER BY id')
id | user | command | t
h1 | alice | id | NULL
h2 | alice | cat report.txt | NULL
6
show(db, 'SELECT COUNT(*) AS commands_without_time FROM history WHERE t IS NULL')
commands_without_time
2

演習完了