mirror of
https://github.com/rookiestar28/ComfyUI-OpenClaw.git
synced 2026-08-14 08:52:45 +00:00
65 lines
1.8 KiB
Python
65 lines
1.8 KiB
Python
"""
|
|
Safe log tail helper for observability.
|
|
Reads last N lines of a log file without loading entire file into memory.
|
|
"""
|
|
|
|
import os
|
|
from typing import List
|
|
|
|
|
|
def tail_log(path: str, lines: int = 200) -> List[str]:
|
|
"""
|
|
Return last `lines` lines from the log file at `path`.
|
|
|
|
Args:
|
|
path: Absolute path to log file.
|
|
lines: Number of lines to return (clamped 1-2000).
|
|
|
|
Returns:
|
|
List of log lines (most recent last).
|
|
"""
|
|
# Clamp lines
|
|
lines = max(1, min(2000, lines))
|
|
|
|
if not os.path.isfile(path):
|
|
return []
|
|
|
|
try:
|
|
# Read file in reverse efficiently
|
|
# For simplicity, read entire file if small, otherwise use seek
|
|
file_size = os.path.getsize(path)
|
|
|
|
if file_size == 0:
|
|
return []
|
|
|
|
# For files under 1MB, just read all and take last N
|
|
if file_size < 1024 * 1024:
|
|
with open(path, "r", encoding="utf-8", errors="replace") as f:
|
|
all_lines = f.readlines()
|
|
return [line.rstrip("\n\r") for line in all_lines[-lines:]]
|
|
|
|
# For larger files, read from end
|
|
# Estimate bytes to read (assume avg 200 bytes per line)
|
|
estimated_bytes = lines * 200
|
|
|
|
with open(path, "rb") as f:
|
|
# Seek to near end
|
|
seek_pos = max(0, file_size - estimated_bytes)
|
|
f.seek(seek_pos)
|
|
|
|
# Read to end
|
|
data = f.read()
|
|
|
|
# Decode and split
|
|
text = data.decode("utf-8", errors="replace")
|
|
all_lines = text.splitlines()
|
|
|
|
# If we didn't start at beginning, first line may be partial
|
|
if seek_pos > 0 and len(all_lines) > 0:
|
|
all_lines = all_lines[1:] # Drop partial first line
|
|
|
|
return all_lines[-lines:]
|
|
|
|
except Exception:
|
|
return []
|