diff --git a/systemd/obs-index-sync.service b/systemd/obs-index-sync.service new file mode 100644 index 0000000..1c7703a --- /dev/null +++ b/systemd/obs-index-sync.service @@ -0,0 +1,10 @@ +[Unit] +Description=Observabilidade — indexer sessões + sync EasyPanel +After=network-online.target + +[Service] +Type=oneshot +ExecStart=/home/ealmeida/.local/bin/obs-index-sync.sh +Environment="PATH=/home/ealmeida/.nvm/versions/node/v22.22.2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" +StandardOutput=append:/home/ealmeida/.logs/observability/indexer.log +StandardError=append:/home/ealmeida/.logs/observability/indexer.log diff --git a/systemd/obs-index-sync.sh b/systemd/obs-index-sync.sh new file mode 100644 index 0000000..fc7617b --- /dev/null +++ b/systemd/obs-index-sync.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# obs-index-sync.sh — indexa sessões Claude/Hermes/OpenCode e sincroniza sessions.db para o volume EasyPanel. +# CANÓNICO: este ficheiro vive NO REPO (systemd/obs-index-sync.sh) e é instalado por systemd/install-indexer.sh. +# Lição 05-2026: a cópia única em ~/.local/bin perdeu-se e ninguém deu conta durante semanas (F0.5 Pipeline QT #2401). +set -uo pipefail +DASH_DIR="/media/ealmeida/Dados/Dev/DashDescomplicar" +DB_LOCAL="$HOME/.claude-work/sessions.db" +REMOTE_HOST="root@5.9.90.70" +REMOTE_PATH="/root/data/dashboard-descomplicar/sessions.db" +LOG="$HOME/.logs/observability/indexer.log" +NODE="/home/ealmeida/.nvm/versions/node/v22.22.2/bin/node" +NPX="/home/ealmeida/.nvm/versions/node/v22.22.2/bin/npx" +mkdir -p "$(dirname "$LOG")" +echo "[$(date -Iseconds)] Inicio" >> "$LOG" +# Indexar +cd "$DASH_DIR" +OBSERVABILIDADE_DB="$DB_LOCAL" "$NPX" tsx api/scripts/sessions-indexer.ts --full >> "$LOG" 2>&1 || true +# Checkpoint DB e forcar journal_mode=DELETE para evitar WAL inconsistente +python3 -c " +import sqlite3, os +path = os.path.expanduser(\"$DB_LOCAL\") +db = sqlite3.connect(path) +db.execute(\"PRAGMA wal_checkpoint(TRUNCATE)\") +db.execute(\"PRAGMA journal_mode=DELETE\") +db.close() +" 2>/dev/null || true +# Sincronizar para EasyPanel +rsync -az --checksum "$DB_LOCAL" "$REMOTE_HOST:$REMOTE_PATH" >> "$LOG" 2>&1 +# Limpar WAL/SHM no host EasyPanel e reiniciar servico Swarm +ssh "$REMOTE_HOST" "rm -f /root/data/dashboard-descomplicar/sessions.db-shm /root/data/dashboard-descomplicar/sessions.db-wal && docker service update --detach=true --force descomplicar_dashboard_descomplicar 1>/dev/null 2>&1" >> "$LOG" 2>&1 || true +echo "[$(date -Iseconds)] Concluido - $(du -sh "$DB_LOCAL" | cut -f1)" >> "$LOG" diff --git a/systemd/obs-index-sync.timer b/systemd/obs-index-sync.timer new file mode 100644 index 0000000..8c4bff0 --- /dev/null +++ b/systemd/obs-index-sync.timer @@ -0,0 +1,10 @@ +[Unit] +Description=Observabilidade — timer 15min + +[Timer] +# OnCalendar absoluto: imune a daemon-reload (ver nota em monitor-alerts.timer). +OnCalendar=*:0/15 +Persistent=true + +[Install] +WantedBy=timers.target diff --git a/systemd/observabilidade-indexer.service b/systemd/observabilidade-indexer.service index 53f3b3a..9b5c93a 100644 --- a/systemd/observabilidade-indexer.service +++ b/systemd/observabilidade-indexer.service @@ -5,7 +5,8 @@ After=default.target [Service] Type=simple WorkingDirectory=/media/ealmeida/Dados/Dev/DashDescomplicar -ExecStart=/home/ealmeida/.nvm/versions/node/v22.22.2/bin/npx tsx api/scripts/sessions-indexer.ts --watch +# NUNCA --watch: incidente 110% CPU (i7-7500U) — decisão v2.7.2: timer 15min --full (ver obs-index-sync.timer) +ExecStart=/home/ealmeida/.nvm/versions/node/v22.22.2/bin/npx tsx api/scripts/sessions-indexer.ts --full Restart=on-failure RestartSec=5 KillMode=mixed