fix: 完成商务迁移复核与接口优化并清理历史资料
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
"""只读请求商务接口,记录耗时、完整数据摘要及 SQL;敏感内容必须存放仓库外。"""
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import statistics
|
||||
import time
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def log_offsets(directory):
|
||||
return {p: p.stat().st_size for p in directory.rglob("*.log")}
|
||||
|
||||
|
||||
def read_queries(directory, offsets):
|
||||
queries = []
|
||||
files = list(directory.rglob("*.log"))
|
||||
files = [file for file in files if file.parent.name == "sql"] or files
|
||||
for file in files:
|
||||
with file.open("rb") as stream:
|
||||
stream.seek(offsets.get(file, 0))
|
||||
for line in stream:
|
||||
try:
|
||||
row = json.loads(line)
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
continue
|
||||
if row.get("gorm_logger") and "sql" in row:
|
||||
queries.append(row)
|
||||
return queries
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--runtime", type=Path, required=True)
|
||||
parser.add_argument("--base-url", default="http://127.0.0.1:19004")
|
||||
parser.add_argument("--phase", required=True)
|
||||
parser.add_argument("--repeat", type=int, default=2)
|
||||
parser.add_argument("--cases", type=Path)
|
||||
args = parser.parse_args()
|
||||
if args.runtime.resolve().is_relative_to(Path(__file__).resolve().parents[1]):
|
||||
raise ValueError("完整接口响应和 SQL 必须留在仓库外")
|
||||
output = args.runtime / args.phase
|
||||
output.mkdir(exist_ok=True)
|
||||
cases = json.loads((args.cases or args.runtime / "cases.json").read_text(encoding="utf-8"))
|
||||
token = (args.runtime / "new-admin.token").read_text(encoding="utf-8").strip()
|
||||
report = []
|
||||
for case in cases:
|
||||
elapsed = []
|
||||
for round_number in range(args.repeat):
|
||||
offsets = log_offsets(args.runtime / "sql-logs")
|
||||
url = args.base_url + case["path"] + "?" + urllib.parse.urlencode(case["params"], doseq=True)
|
||||
request = urllib.request.Request(url, headers={"x-token": token, "X-Request-Id": f"perf-{args.phase}-{case['name']}-{round_number}"})
|
||||
started = time.monotonic()
|
||||
with urllib.request.urlopen(request, timeout=300) as response:
|
||||
body = json.load(response)
|
||||
elapsed.append(round((time.monotonic() - started) * 1000, 2))
|
||||
if body.get("code") != 0:
|
||||
raise RuntimeError("请求失败:" + case["name"])
|
||||
queries = read_queries(args.runtime / "sql-logs", offsets)
|
||||
data = body["data"]
|
||||
capture = {"case": case, "data": data, "elapsedMs": elapsed[-1], "queries": queries}
|
||||
(output / f"{case['name']}-{round_number}.json").write_text(json.dumps(capture, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||
digest = hashlib.sha256(json.dumps(data, sort_keys=True, ensure_ascii=False).encode()).hexdigest()
|
||||
slow = sorted(queries, key=lambda row: row.get("elapsed_ms", 0), reverse=True)[:5]
|
||||
item = {"case": case["name"], "round": round_number, "elapsedMs": elapsed[-1], "dataSha256": digest, "queryCount": len(queries), "slowQueries": [{"elapsedMs": q.get("elapsed_ms"), "rows": q.get("rows"), "tables": list(dict.fromkeys(re.findall(r"(?:FROM|JOIN)\s+`?([\w.]+)", q["sql"], re.I)))} for q in slow]}
|
||||
report.append(item)
|
||||
(output / "report.json").write_text(json.dumps(report, indent=2) + "\n", encoding="utf-8")
|
||||
print(json.dumps(item), flush=True)
|
||||
print(json.dumps({"case": case["name"], "medianMs": statistics.median(elapsed)}), flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user