platform-tooling/scripts/database/status-databases.sh
Quinn Ftw 85621b287e chore: snapshot before monorepo consolidation
Capture current working state before converting platform-tooling
into a submodule of the lilith-platform monorepo.
2026-01-29 07:04:39 -08:00

358 lines
9.8 KiB
Bash
Executable file

#!/bin/bash
set -euo pipefail
#
# Database Status Check Script - lilith-platform
#
# Checks the status of all database services and provides health information
#
# Usage:
# ./status-databases.sh [OPTIONS]
#
# Options:
# --json Output in JSON format
# --watch Continuously monitor status (refresh every 5s)
# --detailed Show detailed container information
# --help Show this help message
#
# =============================================================================
# INITIALIZATION
# =============================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export SCRIPT_LIB_DIR="${SCRIPT_DIR}/../lib"
# Load shared libraries
source "${SCRIPT_LIB_DIR}/colors.sh"
source "${SCRIPT_LIB_DIR}/logger.sh"
source "${SCRIPT_DIR}/database-config.sh"
# Initialize logging
log_init "DB-STATUS"
# Parse command line arguments
OUTPUT_JSON=false
WATCH_MODE=false
DETAILED=false
while [[ $# -gt 0 ]]; do
case $1 in
--json)
OUTPUT_JSON=true
shift
;;
--watch)
WATCH_MODE=true
shift
;;
--detailed)
DETAILED=true
shift
;;
--help|-h)
grep '^#' "$0" | grep -v '#!/bin/bash' | sed 's/^# \?//'
exit 0
;;
*)
log_error "Unknown option: $1"
exit 1
;;
esac
done
# =============================================================================
# STATUS CHECK FUNCTIONS
# =============================================================================
check_container_status() {
local container_name="$1"
if docker inspect "$container_name" &>/dev/null; then
local status
status=$(docker inspect --format='{{.State.Status}}' "$container_name")
echo "$status"
else
echo "not-found"
fi
}
check_container_health() {
local container_name="$1"
if docker inspect "$container_name" &>/dev/null; then
local health
health=$(docker inspect --format='{{.State.Health.Status}}' "$container_name" 2>/dev/null || echo "none")
if [ "$health" = "<no value>" ] || [ -z "$health" ]; then
health="none"
fi
echo "$health"
else
echo "unknown"
fi
}
get_container_uptime() {
local container_name="$1"
if docker inspect "$container_name" &>/dev/null; then
local started_at
started_at=$(docker inspect --format='{{.State.StartedAt}}' "$container_name")
if [ -n "$started_at" ] && [ "$started_at" != "0001-01-01T00:00:00Z" ]; then
local start_epoch
start_epoch=$(date -d "$started_at" +%s 2>/dev/null || echo "0")
if [ "$start_epoch" != "0" ]; then
local now_epoch
now_epoch=$(date +%s)
local uptime_seconds=$((now_epoch - start_epoch))
local days=$((uptime_seconds / 86400))
local hours=$(( (uptime_seconds % 86400) / 3600 ))
local minutes=$(( (uptime_seconds % 3600) / 60 ))
if [ $days -gt 0 ]; then
echo "${days}d ${hours}h ${minutes}m"
elif [ $hours -gt 0 ]; then
echo "${hours}h ${minutes}m"
else
echo "${minutes}m"
fi
return
fi
fi
fi
echo "unknown"
}
get_container_memory() {
local container_name="$1"
if docker stats --no-stream --format "{{.MemUsage}}" "$container_name" 2>/dev/null; then
return 0
else
echo "N/A"
fi
}
test_postgres_connection() {
if docker exec lilith-db-postgres pg_isready -U "$POSTGRES_USER" &>/dev/null; then
echo "ok"
else
echo "failed"
fi
}
test_redis_connection() {
if docker exec lilith-db-redis redis-cli ping 2>/dev/null | grep -q PONG; then
echo "ok"
else
echo "failed"
fi
}
get_postgres_stats() {
local stats
stats=$(docker exec lilith-db-postgres psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -t -c \
"SELECT count(*) FROM pg_stat_activity WHERE state = 'active';" 2>/dev/null | tr -d ' ')
echo "${stats:-0}"
}
get_redis_stats() {
local stats
stats=$(docker exec lilith-db-redis redis-cli info stats 2>/dev/null | grep "total_connections_received" | cut -d: -f2 | tr -d '\r')
echo "${stats:-0}"
}
# =============================================================================
# DISPLAY FUNCTIONS
# =============================================================================
display_status_text() {
log_banner "Database Services Status"
# PostgreSQL Status
echo ""
log_section "PostgreSQL"
local pg_status
pg_status=$(check_container_status "lilith-db-postgres")
local pg_health
pg_health=$(check_container_health "lilith-db-postgres")
local pg_uptime
pg_uptime=$(get_container_uptime "lilith-db-postgres")
echo -n " Container Status: "
if [ "$pg_status" = "running" ]; then
echo -e "${COLOR_SUCCESS}$pg_status${COLOR_NC}"
else
echo -e "${COLOR_ERROR}$pg_status${COLOR_NC}"
fi
echo -n " Health Check: "
case "$pg_health" in
healthy)
echo -e "${COLOR_SUCCESS}$pg_health${COLOR_NC}"
;;
unhealthy)
echo -e "${COLOR_ERROR}$pg_health${COLOR_NC}"
;;
*)
echo -e "${COLOR_WARNING}$pg_health${COLOR_NC}"
;;
esac
echo " Uptime: $pg_uptime"
if [ "$pg_status" = "running" ]; then
local pg_conn
pg_conn=$(test_postgres_connection)
echo -n " Connection Test: "
if [ "$pg_conn" = "ok" ]; then
echo -e "${COLOR_SUCCESS}OK${COLOR_NC}"
else
echo -e "${COLOR_ERROR}FAILED${COLOR_NC}"
fi
if [ "$DETAILED" = true ]; then
local active_conns
active_conns=$(get_postgres_stats)
echo " Active Connections: $active_conns"
echo " Port: $POSTGRES_PORT"
echo " Data Directory: $POSTGRES_DATA_DIR"
fi
fi
# Redis Status
echo ""
log_section "Redis"
local redis_status
redis_status=$(check_container_status "lilith-db-redis")
local redis_health
redis_health=$(check_container_health "lilith-db-redis")
local redis_uptime
redis_uptime=$(get_container_uptime "lilith-db-redis")
echo -n " Container Status: "
if [ "$redis_status" = "running" ]; then
echo -e "${COLOR_SUCCESS}$redis_status${COLOR_NC}"
else
echo -e "${COLOR_ERROR}$redis_status${COLOR_NC}"
fi
echo -n " Health Check: "
case "$redis_health" in
healthy)
echo -e "${COLOR_SUCCESS}$redis_health${COLOR_NC}"
;;
unhealthy)
echo -e "${COLOR_ERROR}$redis_health${COLOR_NC}"
;;
*)
echo -e "${COLOR_WARNING}$redis_health${COLOR_NC}"
;;
esac
echo " Uptime: $redis_uptime"
if [ "$redis_status" = "running" ]; then
local redis_conn
redis_conn=$(test_redis_connection)
echo -n " Connection Test: "
if [ "$redis_conn" = "ok" ]; then
echo -e "${COLOR_SUCCESS}OK${COLOR_NC}"
else
echo -e "${COLOR_ERROR}FAILED${COLOR_NC}"
fi
if [ "$DETAILED" = true ]; then
echo " Port: $REDIS_PORT"
echo " Data Directory: $REDIS_DATA_DIR"
echo " Max Memory: $REDIS_MAXMEMORY"
fi
fi
# Overall Status
echo ""
log_section "Overall Status"
local all_healthy=true
if [ "$pg_status" != "running" ] || [ "$pg_health" = "unhealthy" ]; then
all_healthy=false
fi
if [ "$redis_status" != "running" ] || [ "$redis_health" = "unhealthy" ]; then
all_healthy=false
fi
echo -n " Status: "
if [ "$all_healthy" = true ]; then
echo -e "${COLOR_SUCCESS}All services healthy ✅${COLOR_NC}"
else
echo -e "${COLOR_ERROR}Some services unhealthy ❌${COLOR_NC}"
fi
echo ""
}
display_status_json() {
local pg_status
pg_status=$(check_container_status "lilith-db-postgres")
local pg_health
pg_health=$(check_container_health "lilith-db-postgres")
local pg_conn
pg_conn=$(test_postgres_connection)
local redis_status
redis_status=$(check_container_status "lilith-db-redis")
local redis_health
redis_health=$(check_container_health "lilith-db-redis")
local redis_conn
redis_conn=$(test_redis_connection)
cat <<EOF
{
"timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"services": {
"postgres": {
"container_status": "$pg_status",
"health_status": "$pg_health",
"connection_test": "$pg_conn",
"port": $POSTGRES_PORT,
"host": "$DB_HOST_IP"
},
"redis": {
"container_status": "$redis_status",
"health_status": "$redis_health",
"connection_test": "$redis_conn",
"port": $REDIS_PORT,
"host": "$DB_HOST_IP"
}
},
"overall_healthy": $([ "$pg_status" = "running" ] && [ "$redis_status" = "running" ] && [ "$pg_conn" = "ok" ] && [ "$redis_conn" = "ok" ] && echo "true" || echo "false")
}
EOF
}
# =============================================================================
# MAIN
# =============================================================================
main() {
if [ "$WATCH_MODE" = true ]; then
while true; do
clear
display_status_text
echo ""
log_info "Refreshing in 5 seconds... (Ctrl+C to exit)"
sleep 5
done
elif [ "$OUTPUT_JSON" = true ]; then
display_status_json
else
display_status_text
fi
}
main "$@"