Files
HartOMat/backend/app/services/render_log.py
T
2026-03-05 22:12:38 +01:00

73 lines
1.8 KiB
Python

"""Redis-backed live render log for streaming task progress.
Each order line gets a Redis list keyed by render:log:{order_line_id}.
Entries are JSON objects with timestamp, level, and message.
Lists auto-expire after 1 hour.
"""
import json
import time
import logging
import redis
from app.config import settings
logger = logging.getLogger(__name__)
_LOG_TTL = 3600 # 1 hour
_MAX_ENTRIES = 500
def _redis() -> redis.Redis:
return redis.from_url(settings.redis_url, decode_responses=True)
def _key(order_line_id: str) -> str:
return f"render:log:{order_line_id}"
def emit(order_line_id: str, message: str, level: str = "info") -> None:
"""Push a log entry for a render job."""
entry = json.dumps({
"ts": time.time(),
"t": time.strftime("%H:%M:%S", time.gmtime()),
"level": level,
"msg": message,
})
try:
r = _redis()
key = _key(order_line_id)
r.rpush(key, entry)
r.ltrim(key, -_MAX_ENTRIES, -1)
r.expire(key, _LOG_TTL)
except Exception as exc:
logger.debug(f"render_log emit failed: {exc}")
def get_entries(order_line_id: str, after_index: int = 0) -> list[dict]:
"""Get log entries starting from after_index."""
try:
r = _redis()
raw = r.lrange(_key(order_line_id), after_index, -1)
return [json.loads(e) for e in raw]
except Exception:
return []
def count(order_line_id: str) -> int:
"""Get the number of log entries."""
try:
r = _redis()
return r.llen(_key(order_line_id))
except Exception:
return 0
def clear(order_line_id: str) -> None:
"""Clear log entries for a render job."""
try:
r = _redis()
r.delete(_key(order_line_id))
except Exception:
pass