Files
LWLT-AIBOT/infra/diagnose-server.sh
2026-08-30 16:01:42 +08:00

98 lines
2.7 KiB
Bash
Executable File

#!/usr/bin/env sh
set -eu
since=30m
tail_lines=1000
match=
all_services=false
usage() {
printf '%s\n' 'Usage: sh infra/diagnose-server.sh [--since 30m] [--tail 1000] [--match VALUE] [--all-services]'
printf '%s\n' 'Filters are literal and can be a request ID, TASK-* ID, AgentBus frame/conversation/channel ID, diagnostic event, or error code.'
}
while [ "$#" -gt 0 ]; do
case "$1" in
--since)
[ "$#" -ge 2 ] || { usage >&2; exit 2; }
since=$2
shift 2
;;
--tail)
[ "$#" -ge 2 ] || { usage >&2; exit 2; }
tail_lines=$2
shift 2
;;
--match)
[ "$#" -ge 2 ] || { usage >&2; exit 2; }
match=$2
shift 2
;;
--all-services)
all_services=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
usage >&2
exit 2
;;
esac
done
if ! printf '%s' "$since" | grep -Eq '^[0-9]+[smhd]$'; then
printf '%s\n' 'diagnose-server: --since must use a bounded value such as 30m, 2h, or 1d.' >&2
exit 2
fi
case "$tail_lines" in
*[!0-9]*|'')
printf '%s\n' 'diagnose-server: --tail must be a positive integer.' >&2
exit 2
;;
esac
if [ "$tail_lines" -lt 1 ] || [ "$tail_lines" -gt 50000 ]; then
printf '%s\n' 'diagnose-server: --tail must be between 1 and 50000.' >&2
exit 2
fi
cd "$(dirname "$0")/.."
compose() {
if [ -f .env.production ]; then
docker compose --env-file .env.production "$@"
else
docker compose "$@"
fi
}
command -v docker >/dev/null 2>&1 || {
printf '%s\n' 'diagnose-server: docker is not installed or not on PATH.' >&2
exit 1
}
printf '%s\n' 'Container state:'
compose ps
printf '%s\n' 'Control-plane readiness:'
if ! compose exec -T control-plane node -e "fetch('http://127.0.0.1:8786/health/ready').then(async response => { const body = await response.json(); console.log(JSON.stringify({ status: response.status, body })); process.exit(response.ok ? 0 : 1); }).catch(error => { console.error(JSON.stringify({ status: 0, error_code: error && error.code ? String(error.code) : 'health_request_failed' })); process.exit(1); });"; then
printf '%s\n' 'diagnose-server: readiness is unhealthy; recent logs follow.' >&2
fi
printf 'Recent logs (since=%s, tail=%s):\n' "$since" "$tail_lines"
if [ "$all_services" = true ]; then
if [ -n "$match" ]; then
compose logs --no-color --timestamps --since "$since" --tail "$tail_lines" \
| grep -F -- "$match" || true
else
compose logs --no-color --timestamps --since "$since" --tail "$tail_lines"
fi
elif [ -n "$match" ]; then
compose logs --no-color --timestamps --since "$since" --tail "$tail_lines" control-plane \
| grep -F -- "$match" || true
else
compose logs --no-color --timestamps --since "$since" --tail "$tail_lines" control-plane
fi