#!/bin/bash # # Helper to tail logs from the active Eagle instance. # Reads the active instance from /opt/eagle0/.active-instance (set by deploy-blue-green.sh). # # Usage: # eagle-logs # Show existing logs and keep following # eagle-logs -n 100 # Show the last 100 lines and keep following # eagle-logs --no-follow -n 50 # Show the last 50 lines and exit # # To create an alias, add to ~/.bashrc: # alias eagle-logs='/opt/eagle0/scripts/eagle-logs.sh' # set -uo pipefail APP_DIR="${APP_DIR:-/opt/eagle0}" ACTIVE_FILE="${APP_DIR}/.active-instance" RETRY_INTERVAL_SECONDS="${EAGLE_LOGS_RETRY_INTERVAL_SECONDS:-2}" trap 'exit 130' INT trap 'exit 143' TERM FOLLOW=true DOCKER_LOG_ARGS=() for arg in "$@"; do case "$arg" in --no-follow) FOLLOW=false ;; -f | --follow) FOLLOW=true ;; *) DOCKER_LOG_ARGS+=("$arg") ;; esac done container_is_running() { [ "$(docker inspect --format='{{.State.Running}}' "$1" 2>/dev/null)" = "true" ] } resolve_active_instance() { local recorded_active="" if [ -f "$ACTIVE_FILE" ]; then IFS= read -r recorded_active < "$ACTIVE_FILE" || true fi if [ -n "$recorded_active" ] && container_is_running "$recorded_active"; then printf '%s\n' "$recorded_active" elif container_is_running eagle-blue; then printf '%s\n' "eagle-blue" elif container_is_running eagle-green; then printf '%s\n' "eagle-green" else return 1 fi } print_disconnect_marker() { local stopped_instance=${1:-unknown} printf '\n' >&2 printf '%s\n' '================================================================================' >&2 printf '%s\n' '==================== EAGLE LOG STREAM DISCONNECTED ============================' >&2 printf ' Server unavailable at %s (last instance: %s)\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$stopped_instance" >&2 printf '%s\n' ' Waiting for the deployment or server restart; log following will resume.' >&2 printf '%s\n' '================================================================================' >&2 } print_resume_marker() { local active_instance=$1 printf '\n' >&2 printf '%s\n' '================================================================================' >&2 printf '%s\n' '======================= EAGLE LOG STREAM RESUMED ==============================' >&2 printf ' Attached to %s at %s\n' "$active_instance" "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" >&2 printf '%s\n' '================================================================================' >&2 } if [ "$FOLLOW" = false ]; then if ! ACTIVE=$(resolve_active_instance); then echo "Error: No active Eagle instance found" >&2 exit 1 fi exec docker logs "${DOCKER_LOG_ARGS[@]}" "$ACTIVE" fi ACTIVE="" DISCONNECTED=false RECONNECT_SINCE="" while true; do if NEXT_ACTIVE=$(resolve_active_instance); then if [ "$DISCONNECTED" = true ]; then print_resume_marker "$NEXT_ACTIVE" fi ACTIVE="$NEXT_ACTIVE" DISCONNECTED=false if [ -n "$RECONNECT_SINCE" ]; then docker logs --follow "${DOCKER_LOG_ARGS[@]}" --since "$RECONNECT_SINCE" "$ACTIVE" || true else docker logs --follow "${DOCKER_LOG_ARGS[@]}" "$ACTIVE" || true fi RECONNECT_SINCE=$(date +%s) fi if [ "$DISCONNECTED" = false ]; then print_disconnect_marker "$ACTIVE" DISCONNECTED=true fi sleep "$RETRY_INTERVAL_SECONDS" done