mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-26 23:49:02 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Slice the client's Player.log by wall-clock window and summarise it.
|
||||
|
||||
The Unity log is one flat file per launch whose lines start with
|
||||
`[HH:MM:SS] [frame] [seconds] [Level] [Tag] ...`; anything that matters after a
|
||||
test is usually a handful of error lines inside a one-minute window.
|
||||
|
||||
Usage:
|
||||
python tools/player-log-window.py --from 14:21 --to 14:23 [--errors]
|
||||
python tools/player-log-window.py --grep "studio|rrs" --from 14:22:30
|
||||
python tools/player-log-window.py --log <path> --from ... --to ... --show
|
||||
|
||||
Options:
|
||||
--errors dedupe and count Error/Warning/Exception lines instead of printing all
|
||||
--show print every matching line (default when a --grep matches)
|
||||
--tail N additionally print the last N raw lines of the file
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
DEFAULT_LOG = os.path.join(
|
||||
os.environ.get("LOCALAPPDATA", ""), "..", "LocalLow",
|
||||
"Against Gravity", "Rec Room", "Player.log")
|
||||
|
||||
LINE_RE = re.compile(r"^\[(\d\d:\d\d:\d\d(?:\.\d+)?)\]")
|
||||
|
||||
|
||||
def pad(value, tail):
|
||||
"""`14:22` means the whole minute, `14:22:30` the whole second."""
|
||||
if not value:
|
||||
return None
|
||||
return value if value.count(":") == 2 else value + tail
|
||||
|
||||
|
||||
def in_window(stamp, start, stop):
|
||||
if start and stamp < start:
|
||||
return False
|
||||
if stop and stamp > stop:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main(argv):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--log", default=os.path.normpath(DEFAULT_LOG))
|
||||
parser.add_argument("--from", dest="start")
|
||||
parser.add_argument("--to", dest="stop")
|
||||
parser.add_argument("--grep")
|
||||
parser.add_argument("--errors", action="store_true")
|
||||
parser.add_argument("--show", action="store_true")
|
||||
parser.add_argument("--tail", type=int, default=0)
|
||||
args = parser.parse_args(argv[1:])
|
||||
|
||||
with open(args.log, "rb") as handle:
|
||||
blob = handle.read().decode("utf-8", "replace")
|
||||
lines = blob.split("\n")
|
||||
print(f"{args.log}: {len(lines)} lines, {len(blob)} bytes")
|
||||
|
||||
pattern = re.compile(args.grep, re.I) if args.grep else None
|
||||
selected = []
|
||||
for text in lines:
|
||||
match = LINE_RE.match(text)
|
||||
if not match:
|
||||
continue
|
||||
if not in_window(match.group(1), pad(args.start, ":00"), pad(args.stop, ":59")):
|
||||
continue
|
||||
if pattern and not pattern.search(text):
|
||||
continue
|
||||
if args.errors and not re.search(r"\[(Error|Warning)\]|Exception:|Error:", text):
|
||||
continue
|
||||
selected.append(text.rstrip())
|
||||
|
||||
if args.errors or not (args.show or pattern):
|
||||
counts = {}
|
||||
order = []
|
||||
for text in selected:
|
||||
key = re.sub(r"\d+", "#", text[:220])
|
||||
if key not in counts:
|
||||
counts[key] = 0
|
||||
order.append(key)
|
||||
counts[key] += 1
|
||||
for key in order:
|
||||
print(f" x{counts[key]:<4} {key}")
|
||||
else:
|
||||
for text in selected:
|
||||
print(" " + text[:300])
|
||||
print(f"--- {len(selected)} selected line(s)")
|
||||
|
||||
if args.tail:
|
||||
print(f"--- last {args.tail} lines ---")
|
||||
for text in [t for t in lines if t.strip()][-args.tail:]:
|
||||
print(" " + text[:300])
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
||||
Reference in New Issue
Block a user