Files
watchdog-discord-route/scripts/check_openclaw_state.sh

69 lines
1.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Watchdog B MVP tri-state checker for OpenClaw main runtime.
# Output (stdout): exactly one token: running | stalled | idle
#
# Heuristic (MVP):
# - If openclaw.pid exists and process is alive => running unless logs are stale.
# - If process alive but log file hasn't changed for STALL_AFTER_SECONDS => stalled.
# - Otherwise => idle.
#
# Future extension point:
# - Replace/augment log-freshness with real main-agent session/ledger signals.
PID_FILE_DEFAULT="${OPENCLAW_PID_FILE:-/home/chchang/.openclaw/workspace/host-runtime/openclaw.pid}"
LOG_FILE_DEFAULT="${OPENCLAW_LOG_FILE:-/home/chchang/.openclaw/workspace/logs/openclaw.log}"
STALL_AFTER_SECONDS="${STALL_AFTER_SECONDS:-1200}" # 20 minutes default
NOW_EPOCH="$(date +%s)"
pid_file="$PID_FILE_DEFAULT"
log_file="$LOG_FILE_DEFAULT"
get_mtime_epoch() {
# GNU stat: %Y; BSD stat: -f %m
local path="$1"
if stat -c %Y "$path" >/dev/null 2>&1; then
stat -c %Y "$path"
else
stat -f %m "$path"
fi
}
proc_alive() {
local pid="$1"
[[ -n "$pid" ]] || return 1
[[ "$pid" =~ ^[0-9]+$ ]] || return 1
kill -0 "$pid" >/dev/null 2>&1
}
# No pid file => idle
if [[ ! -f "$pid_file" ]]; then
echo "idle"
exit 0
fi
pid="$(tr -d ' \t\n\r' < "$pid_file" || true)"
# PID file exists but process not alive => idle
if ! proc_alive "$pid"; then
echo "idle"
exit 0
fi
# Process alive. If no log file, assume running (can't assess stall)
if [[ ! -f "$log_file" ]]; then
echo "running"
exit 0
fi
log_mtime="$(get_mtime_epoch "$log_file")"
age=$(( NOW_EPOCH - log_mtime ))
if (( age > STALL_AFTER_SECONDS )); then
echo "stalled"
else
echo "running"
fi