46 lines
1.6 KiB
Bash
46 lines
1.6 KiB
Bash
|
|
#!/usr/bin/env bash
|
||
|
|
# retention-rotate-chat-history.sh — retention piece 1 (board bug b67084660385).
|
||
|
|
# Rotates logs/chat-history.jsonl when it exceeds 10MB or is older than 7 days.
|
||
|
|
#
|
||
|
|
# Live-writer safety: the harvester (bin/response-harvester.py) opens the file
|
||
|
|
# in append mode per write and closes it immediately, so an atomic `mv` of the
|
||
|
|
# live file is safe — the next write recreates a fresh file. We also `touch`
|
||
|
|
# the new live file for tidiness and to keep ownership/visibility stable.
|
||
|
|
#
|
||
|
|
# Archives land in logs/archive/chat-history-YYYYMMDD-HHMMSS.jsonl.gz with a
|
||
|
|
# sha256 sidecar. Nothing is ever deleted by this script.
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
ROOT="${NETVM_ROOT:-/home/super/Projects/NetVM}"
|
||
|
|
LIVE="$ROOT/logs/chat-history.jsonl"
|
||
|
|
ARCHIVE_DIR="$ROOT/logs/archive"
|
||
|
|
SIZE_LIMIT=$((10 * 1024 * 1024)) # 10MB
|
||
|
|
AGE_LIMIT_DAYS=7
|
||
|
|
TS="$(date -u +%Y%m%d-%H%M%S)"
|
||
|
|
|
||
|
|
mkdir -p "$ARCHIVE_DIR"
|
||
|
|
|
||
|
|
if [ ! -f "$LIVE" ]; then
|
||
|
|
echo "SKIP chat-history: no live file at $LIVE"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
size="$(stat -c %s "$LIVE")"
|
||
|
|
age_days=$(( ( $(date +%s) - $(stat -c %Y "$LIVE") ) / 86400 ))
|
||
|
|
|
||
|
|
if [ "$size" -lt "$SIZE_LIMIT" ] && [ "$age_days" -lt "$AGE_LIMIT_DAYS" ]; then
|
||
|
|
echo "SKIP chat-history: ${size}B, ${age_days}d old (limits ${SIZE_LIMIT}B / ${AGE_LIMIT_DAYS}d)"
|
||
|
|
exit 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
lines="$(wc -l < "$LIVE")"
|
||
|
|
base="chat-history-$TS"
|
||
|
|
echo "ROTATE chat-history: ${size}B / ${lines} lines (${age_days}d old) -> $ARCHIVE_DIR/$base.jsonl.gz"
|
||
|
|
|
||
|
|
mv "$LIVE" "$ARCHIVE_DIR/$base.jsonl"
|
||
|
|
gzip -9 "$ARCHIVE_DIR/$base.jsonl"
|
||
|
|
( cd "$ARCHIVE_DIR" && sha256sum "$base.jsonl.gz" > "$base.jsonl.gz.sha256" )
|
||
|
|
touch "$LIVE"
|
||
|
|
|
||
|
|
echo "OK chat-history: archived $base.jsonl.gz, live file recreated empty"
|