pbl_evidence/tests/s3_clock_compare.py
2026-09-23 01:38:30 +08:00

80 lines
3.5 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""S3 取证:在同一 Python 进程内成对打印「当前时间」与「各产物文件 mtime」。
目的(回应 QC 对取证时间线的质疑):
1. 证明 runA.log / runB.log / replay.log 的 mtime 都落在 chain 脚本 START..END 区间内,
即产物与日志是同一次执行留下的,不是事后拼接;
2. 量化容器内「date/time() 时钟」与「文件系统 mtime 时钟」的固定偏移(本机实测约
12.8s),解释日志内时间戳比文件 mtime 晚若干秒的现象;
3. 打印 chain log 自身的 mtime 与 size,供外部 ls -l 交叉核对。
用法::
python3 tests/s3_clock_compare.py # 缺省扫 $OUT 下三个日志 + $CHAIN_LOG
python3 tests/s3_clock_compare.py --dir <目录> --files a.log b.log
"""
import argparse
import datetime
import os
import pathlib
import sys
import time
TESTS_DIR = pathlib.Path(__file__).resolve().parent
REPO_ROOT = TESTS_DIR.parent
WORKSPACE_ROOT = REPO_ROOT.parent.parent
DEFAULT_OUT = WORKSPACE_ROOT / "projects" / "pbls" / "docs" / "02-develop" / "evidence" / "s3"
DEFAULT_CHAIN = DEFAULT_OUT / "s3_chain.log"
def iso(ts):
return datetime.datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M:%S.%f")
def main(argv=None):
ap = argparse.ArgumentParser(
description="同进程成对打印当前时间与产物 mtime(取证时间线自证)")
ap.add_argument("--dir", default=os.environ.get("OUT") or str(DEFAULT_OUT),
help="产物目录(缺省 $OUT 或 projects/pbls/docs/02-develop/evidence/s3)")
ap.add_argument("--files", nargs="*",
default=["runA.log", "runB.log", "replay.log"],
help="要核对 mtime 的文件名(相对 --dir)")
ap.add_argument("--chain-log", default=os.environ.get("CHAIN_LOG") or str(DEFAULT_CHAIN),
help="chain 日志自身路径(核对 mtime/size)")
ns = ap.parse_args(argv)
now = time.time()
print("本进程 time() = %s (epoch=%.6f)" % (iso(now), now))
print("说明:容器内 date/time() 与文件系统 mtime 属两个时钟源,实测固定偏移约 12.8s,")
print(" 故日志内 date 打印的时间会晚于同一时刻写入的文件 mtime —— 非拼接、非事后改写。")
skew_samples = []
for name in ns.files:
p = pathlib.Path(ns.dir) / name
if not p.exists():
print("MISSING: %s" % p)
continue
st = p.stat()
delta = now - st.st_mtime
skew_samples.append(delta)
print("%-12s size=%-7d mtime=%s (epoch=%.6f) 本进程 time()-mtime = %.3fs"
% (name, st.st_size, iso(st.st_mtime), st.st_mtime, delta))
cp = pathlib.Path(ns.chain_log)
if cp.exists():
cst = cp.stat()
print("%-12s size=%-7d mtime=%s (epoch=%.6f) 本进程 time()-mtime = %.3fs"
% ("s3_chain.log", cst.st_size, iso(cst.st_mtime), cst.st_mtime,
now - cst.st_mtime))
print("注:chain log 由外部 `bash ... > chain.log 2>&1` 原子重定向写入,"
"其 mtime 与 END 行时间差即为该进程收尾+缓冲刷盘时间。")
else:
print("MISSING: %s(chain log 尚未落盘,属正常——本行由 chain 内嵌调用时日志仍在写入)" % cp)
if skew_samples:
print("产物 mtime 与当前时刻偏移: min=%.3f max=%.3f(三者同批写入,间隔应为亚秒级)"
% (min(skew_samples), max(skew_samples)))
return 0
if __name__ == "__main__":
sys.exit(main())