Files
Schulcloud-MCP/scripts/keepalive-status.sh
MechaCat02 bf2e542182 Add keepalive-status, a log-only session health check
Summarises the running container's keepalive: extension count, latest
budget, transient failures, rejections, restarts.

It deliberately makes no API call. Any authenticated request slides the
session TTL, so a checker that talked to Schulcloud would be sustaining
the session itself and could not report on whether the keepalive is
doing it — the same confound that made the first endurance test
ambiguous. Reading container logs observes without participating.

Warns when the reported budget drops below 7000s, which is the early
signal that extensions have stopped taking effect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 16:39:50 +02:00

57 lines
2.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Reports on the running container's keepalive from its logs alone.
#
# Deliberately makes no API call: any authenticated request slides the session
# TTL, so a checker that talked to Schulcloud would be keeping the session
# alive itself and could not tell you whether the keepalive is working.
set -uo pipefail
CONTAINER="${1:-schulcloud-mcp}"
if ! docker inspect "$CONTAINER" >/dev/null 2>&1; then
echo "container '$CONTAINER' does not exist"
exit 1
fi
state=$(docker inspect -f '{{.State.Status}}' "$CONTAINER")
health=$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' "$CONTAINER")
started=$(docker inspect -f '{{.State.StartedAt}}' "$CONTAINER")
restarts=$(docker inspect -f '{{.RestartCount}}' "$CONTAINER")
echo "container : $CONTAINER state=$state health=$health restarts=$restarts"
echo "started : $started"
logs=$(docker logs -t "$CONTAINER" 2>&1)
ok=$(grep -c 'session extended' <<<"$logs" || true)
fail=$(grep -c 'token rejected (401)' <<<"$logs" || true)
retry=$(grep -c 'ping failed' <<<"$logs" || true)
echo "keepalive : ${ok} successful extension(s), ${retry} transient failure(s), ${fail} rejection(s)"
first=$(grep 'session extended' <<<"$logs" | head -1 | awk '{print $1}')
last_line=$(grep 'session extended' <<<"$logs" | tail -1)
[ -n "$first" ] && echo "first ok : $first"
if [ -n "$last_line" ]; then
echo "latest ok : $(awk '{print $1}' <<<"$last_line")"
echo " $(sed 's/^[^ ]* *//' <<<"$last_line")"
# A budget below the instance's 7200s ceiling means extensions are not taking.
budget=$(grep -oE 'extended, [0-9]+s' <<<"$last_line" | grep -oE '[0-9]+')
if [ -n "$budget" ] && [ "$budget" -lt 7000 ]; then
echo "WARNING : budget ${budget}s is below the 7200s ceiling — extensions may not be taking effect"
fi
fi
if [ "$fail" -gt 0 ]; then
echo
echo "SESSION LOST:"
grep 'token rejected (401)' <<<"$logs" | tail -2
echo "=> paste a fresh jwt cookie into .env and restart (docs/AUTH.md)."
exit 2
fi
if [ "$ok" -gt 0 ]; then
echo
echo "OK — session held across ${ok} extension(s) with no rejection."
fi