#!/bin/bash # File: /var/www/nebuleair_pro_4g/services/check_services.sh # Purpose: Check status of all NebuleAir services and logs # Version with fixed color handling for proper table display # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' BOLD='\033[1m' DIM='\033[2m' NC='\033[0m' # No Color # Service list SERVICES=("npm" "envea" "sara" "bme280" "mppt" "db-cleanup" "noise") # Function to print header print_header() { local text="$1" echo "" echo -e "${BLUE}${BOLD}=== $text ===${NC}" echo -e "${BLUE}$(printf '%.0s=' {1..70})${NC}" } # Function to print section print_section() { local text="$1" echo "" echo -e "${CYAN}${BOLD}--- $text ---${NC}" } # Function to print a separator line print_separator() { echo "+--------------------------+-----------+-----------+-------------+-------------+-------------------------+" } # Clear screen for clean output clear # Main header print_header "NebuleAir Services Status Report" echo -e "Generated on: $(date '+%Y-%m-%d %H:%M:%S')" # Timer Schedule print_section "Active Timers Schedule" echo "" systemctl list-timers --no-pager | head -n 1 systemctl list-timers --no-pager | grep nebuleair || echo "No active nebuleair timers found" # Service Status Overview with fixed color handling print_section "Service Status Overview" echo "" print_separator printf "| %-24s | %-9s | %-9s | %-11s | %-11s | %-23s |\n" "Service" "Svc State" "Svc Boot" "Timer State" "Timer Boot" "Health Status" print_separator for service in "${SERVICES[@]}"; do # Check the actual service and timer names (with -data suffix) full_service_name="nebuleair-${service}-data" # Get raw status values service_status=$(systemctl is-active ${full_service_name}.service 2>/dev/null | tr -d '\n' || echo "not-found") service_enabled=$(systemctl is-enabled ${full_service_name}.service 2>/dev/null | tr -d '\n' || echo "not-found") timer_status=$(systemctl is-active ${full_service_name}.timer 2>/dev/null | tr -d '\n' || echo "not-found") timer_enabled=$(systemctl is-enabled ${full_service_name}.timer 2>/dev/null | tr -d '\n' || echo "not-found") # Check if files exist and override if not found if ! systemctl list-unit-files | grep -q "^${full_service_name}.service" &>/dev/null; then service_status="not-found" service_enabled="not-found" fi if ! systemctl list-unit-files | grep -q "^${full_service_name}.timer" &>/dev/null; then timer_status="not-found" timer_enabled="not-found" fi # Create display strings without embedded colors for table cells case $service_status in "active") svc_st_display="active"; svc_st_color="${GREEN}" ;; "inactive") svc_st_display="inactive"; svc_st_color="${DIM}" ;; "activating") svc_st_display="starting"; svc_st_color="${YELLOW}" ;; "not-found") svc_st_display="missing"; svc_st_color="${RED}" ;; *) svc_st_display="$service_status"; svc_st_color="${RED}" ;; esac case $service_enabled in "enabled"|"static") svc_en_display="enabled"; svc_en_color="${GREEN}" ;; "disabled") svc_en_display="disabled"; svc_en_color="${YELLOW}" ;; "not-found") svc_en_display="missing"; svc_en_color="${RED}" ;; *) svc_en_display="$service_enabled"; svc_en_color="${YELLOW}" ;; esac case $timer_status in "active") tim_st_display="active"; tim_st_color="${GREEN}" ;; "inactive") tim_st_display="inactive"; tim_st_color="${RED}" ;; "not-found") tim_st_display="missing"; tim_st_color="${RED}" ;; *) tim_st_display="$timer_status"; tim_st_color="${RED}" ;; esac case $timer_enabled in "enabled"|"static") tim_en_display="enabled"; tim_en_color="${GREEN}" ;; "disabled") tim_en_display="disabled"; tim_en_color="${YELLOW}" ;; "not-found") tim_en_display="missing"; tim_en_color="${RED}" ;; *) tim_en_display="$timer_enabled"; tim_en_color="${YELLOW}" ;; esac # Determine health status if [[ "$timer_status" == "active" ]]; then if [[ "$timer_enabled" == "enabled" || "$timer_enabled" == "static" ]]; then health_display="✓ OK" health_color="${GREEN}" else health_display="⚠ Boot disabled" health_color="${YELLOW}" fi elif [[ "$timer_status" == "inactive" ]]; then health_display="✗ Timer stopped" health_color="${RED}" else health_display="✗ Timer missing" health_color="${RED}" fi # Print row with colors applied outside of printf formatting printf "| %-24s | " "$full_service_name" printf "${svc_st_color}%-9s${NC} | " "$svc_st_display" printf "${svc_en_color}%-9s${NC} | " "$svc_en_display" printf "${tim_st_color}%-11s${NC} | " "$tim_st_display" printf "${tim_en_color}%-11s${NC} | " "$tim_en_display" printf "${health_color}%-23s${NC} |\n" "$health_display" done print_separator # Understanding the table echo "" echo -e "${DIM}Note: For timer-based services, it's normal for the service to be 'inactive' and 'disabled'.${NC}" echo -e "${DIM} What matters is that the timer is 'active' and 'enabled'.${NC}" # Configuration Issues print_section "Configuration Issues" echo "" issues_found=false for service in "${SERVICES[@]}"; do full_service_name="nebuleair-${service}-data" timer_status=$(systemctl is-active ${full_service_name}.timer 2>/dev/null | tr -d '\n' || echo "not-found") timer_enabled=$(systemctl is-enabled ${full_service_name}.timer 2>/dev/null | tr -d '\n' || echo "not-found") # Check if timer exists if ! systemctl list-unit-files | grep -q "^${full_service_name}.timer" &>/dev/null; then timer_status="not-found" timer_enabled="not-found" fi if [[ "$timer_status" != "active" || ("$timer_enabled" != "enabled" && "$timer_enabled" != "static") ]]; then issues_found=true echo -e " ${RED}•${NC} ${BOLD}$full_service_name${NC}" if [[ "$timer_status" == "not-found" ]]; then echo -e " ${RED}→${NC} Timer unit file is missing" elif [[ "$timer_status" != "active" ]]; then echo -e " ${RED}→${NC} Timer is not running (status: $timer_status)" fi if [[ "$timer_enabled" == "not-found" ]]; then echo -e " ${RED}→${NC} Timer unit file is missing" elif [[ "$timer_enabled" != "enabled" && "$timer_enabled" != "static" ]]; then echo -e " ${YELLOW}→${NC} Timer won't start on boot (status: $timer_enabled)" fi echo "" fi done if [[ "$issues_found" == "false" ]]; then echo -e " ${GREEN}✓${NC} All timers are properly configured!" fi # Recent Executions - Simplified print_section "Last Execution Status" echo "" printf " %-12s %-20s %s\n" "Service" "Last Run" "Status" printf " %-12s %-20s %s\n" "-------" "--------" "------" for service in "${SERVICES[@]}"; do full_service_name="nebuleair-${service}-data" # Get last execution time and status last_log=$(journalctl -u ${full_service_name}.service -n 3 --no-pager 2>/dev/null | grep -E "(Started|Finished|Failed)" | tail -1) if [[ -n "$last_log" ]]; then timestamp=$(echo "$last_log" | awk '{print $1, $2, $3}') if echo "$last_log" | grep -q "Finished"; then status="${GREEN}✓ Success${NC}" elif echo "$last_log" | grep -q "Failed"; then status="${RED}✗ Failed${NC}" elif echo "$last_log" | grep -q "Started"; then status="${YELLOW}⟳ Running${NC}" else status="${DIM}- Unknown${NC}" fi printf " %-12s %-20s %b\n" "$service" "$timestamp" "$status" else printf " %-12s %-20s %b\n" "$service" "-" "${DIM}- No data${NC}" fi done # Summary print_section "Summary" echo "" working=0 needs_attention=0 for service in "${SERVICES[@]}"; do full_service_name="nebuleair-${service}-data" timer_status=$(systemctl is-active ${full_service_name}.timer 2>/dev/null | tr -d '\n') timer_enabled=$(systemctl is-enabled ${full_service_name}.timer 2>/dev/null | tr -d '\n') if [[ "$timer_status" == "active" ]] && [[ "$timer_enabled" == "enabled" || "$timer_enabled" == "static" ]]; then ((working++)) else ((needs_attention++)) fi done total=${#SERVICES[@]} # Visual progress bar echo -n " Overall Health: [" for ((i=1; i<=10; i++)); do if ((i <= working * 10 / total)); then echo -n -e "${GREEN}▰${NC}" else echo -n -e "${RED}▱${NC}" fi done echo -e "] ${working}/${total}" echo "" echo -e " ${GREEN}✓${NC} Working properly: ${BOLD}$working${NC} services" echo -e " ${RED}✗${NC} Need attention: ${BOLD}$needs_attention${NC} services" # Quick Commands print_section "Quick Commands" echo "" echo -e " ${BOLD}Fix a timer that needs attention:${NC}" echo " $ sudo systemctl enable --now nebuleair-[service]-data.timer" echo "" echo -e " ${BOLD}View live logs:${NC}" echo " $ sudo journalctl -u nebuleair-[service]-data.service -f" echo "" echo -e " ${BOLD}Check timer details:${NC}" echo " $ systemctl status nebuleair-[service]-data.timer" echo "" echo -e " ${BOLD}Run service manually:${NC}" echo " $ sudo systemctl start nebuleair-[service]-data.service" # Specific fixes needed if [[ $needs_attention -gt 0 ]]; then echo "" echo -e "${YELLOW}${BOLD}Recommended Actions:${NC}" for service in "${SERVICES[@]}"; do full_service_name="nebuleair-${service}-data" timer_status=$(systemctl is-active ${full_service_name}.timer 2>/dev/null | tr -d '\n') timer_enabled=$(systemctl is-enabled ${full_service_name}.timer 2>/dev/null | tr -d '\n') if [[ "$timer_status" != "active" ]] && [[ "$timer_status" != "not-found" ]]; then echo -e " ${RED}→${NC} sudo systemctl start ${full_service_name}.timer" fi if [[ "$timer_enabled" != "enabled" ]] && [[ "$timer_enabled" != "static" ]] && [[ "$timer_enabled" != "not-found" ]]; then echo -e " ${YELLOW}→${NC} sudo systemctl enable ${full_service_name}.timer" fi done fi echo ""