#!/bin/bash #-----------------------------------# # VARIABLES # #-----------------------------------# this_script_url="https://git.hhf.technology/hhf/script-management-cloudpanel/raw/branch/main/monitoring/goaccess-setup.sh" this_script_name="GoAccess Setup Script" formatter_url="https://git.hhf.technology/hhf/TaskFormatter/raw/branch/main/bash_task_formatter/task_formatter.sh" scriptname=$0 # Initialize success flag success=0 # Determine the user (use the first argument if provided, otherwise fallback) USER_TO_RUN_AS="${1:-$SUDO_USER}" USER_HOME=$(eval echo ~$USER_TO_RUN_AS) #-----------------------------------# # FORMATTER # #-----------------------------------# # Download and source the formatter with error handling download_formatter() { if [ ! -f "task_formatter.sh" ]; then if ! wget "$formatter_url" --no-check-certificate -O task_formatter.sh > /dev/null 2>&1; then echo "Error: Failed to download task_formatter.sh" exit 1 fi fi if [ ! -f "task_formatter.sh" ]; then echo "Error: task_formatter.sh not found after download attempt" exit 1 fi # Make the formatter executable chmod +x task_formatter.sh # Source the formatter with error checking source ./task_formatter.sh || { echo "Error: Failed to source task_formatter.sh"; exit 1; } # Check if print_header is available after sourcing if ! declare -f print_header > /dev/null; then echo "Error: print_header function not found after sourcing." exit 1 fi } # Call the download_formatter function download_formatter #-----------------------------------# # FUNCTIONS # #-----------------------------------# # Function to check if a command exists command_exists() { command -v "$1" >/dev/null 2>&1 } # Function to find user directories in /home with exclusions find_user_dirs() { find /home -maxdepth 1 -mindepth 1 -type d | grep -v -E '^/home/(lost\+found|mysql|homelab)$' } # Function to setup GoAccess setup_goaccess() { if ! command_exists goaccess; then echo "deb https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee -a /etc/apt/sources.list.d/goaccess.list > /dev/null 2>&1 wget -O - https://deb.goaccess.io/gnugpg.key | sudo apt-key add - > /dev/null 2>&1 sudo apt-get update > /dev/null 2>&1 sudo apt-get install -y goaccess > /dev/null 2>&1 if [ $? -eq 0 ]; then echo -e "GoAccess installed successfully $CHECK_MARK" return 0 else echo -e "Failed to install GoAccess $CROSS_MARK" return 1 fi else echo -e "GoAccess already installed $CHECK_MARK" return 0 fi } # Function to update logrotate configuration update_logrotate() { local user_dirs=($(find_user_dirs)) local existing_config="" local new_config="" if [ -f "/etc/logrotate.d/nginx" ]; then existing_config=$(cat /etc/logrotate.d/nginx) fi for user_dir in "${user_dirs[@]}"; do username=$(basename "$user_dir") if [ -d "$user_dir/logs/nginx" ]; then if ! echo "$existing_config" | grep -q "$user_dir/logs/nginx/\*\.log"; then new_config+=" $user_dir/logs/nginx/*.log { yearly maxsize 1000000000 missingok rotate 4 compress delaycompress notifempty create 0640 $username adm sharedscripts prerotate if [ -d /etc/logrotate.d/httpd-prerotate ]; then \ run-parts /etc/logrotate.d/httpd-prerotate; \ fi \ endscript postrotate invoke-rc.d nginx rotate >/dev/null 2>&1 endscript } " fi fi done if [ ! -z "$new_config" ]; then if echo "${existing_config}${new_config}" | sudo tee /etc/logrotate.d/nginx > /dev/null 2>&1; then echo -e "Logrotate configuration updated $CHECK_MARK" return 0 else echo -e "Failed to update logrotate configuration $CROSS_MARK" return 1 fi else echo -e "No new logrotate configurations needed $CHECK_MARK" return 0 fi } # Function to create or update GoAccess update script create_goaccess_script() { local script_path="/usr/bin/update_goaccess.sh" local script_content='#!/bin/bash set -e set -x process_logs() { for user_dir in /home/*/; do user_dir=${user_dir%/} username=$(basename "$user_dir") case "$username" in "lost+found"|"mysql"|"homelab") continue ;; esac log_file="$user_dir/logs/nginx/access.log" if [ -f "$log_file" ]; then if [ -d "$user_dir/htdocs" ]; then for domain_dir in "$user_dir/htdocs"/*/ ; do if [ -d "$domain_dir" ]; then domain=$(basename "$domain_dir") insights_dir="$domain_dir/insights" mkdir -p "$insights_dir" goaccess "$log_file" \ --log-format=COMBINED \ --date-format="%d/%b/%Y" \ --time-format="%H:%M:%S" \ --double-decode \ --anonymize-ip \ -a \ -o "$insights_dir/goaccess.html" chown -R "$username:$username" "$insights_dir" chmod -R 755 "$insights_dir" fi done fi fi done } echo "Starting GoAccess report generation..." process_logs echo "Finished GoAccess report generation"' if echo "$script_content" | sudo tee "$script_path" > /dev/null 2>&1 && sudo chmod +x "$script_path"; then echo -e "GoAccess script created/updated successfully $CHECK_MARK" return 0 else echo -e "Failed to create/update GoAccess script $CROSS_MARK" return 1 fi } # Function to setup cron job setup_cron() { if ! crontab -l 2>/dev/null | grep -q "update_goaccess.sh"; then if (crontab -l 2>/dev/null; echo "*/5 * * * * /usr/bin/update_goaccess.sh > /var/log/goaccess_cron.log 2>&1") | crontab -; then echo -e "Cron job setup successful $CHECK_MARK" return 0 else echo -e "Failed to setup cron job $CROSS_MARK" return 1 fi else echo -e "Cron job already exists $CHECK_MARK" return 0 fi } # Function to do initial run initial_run() { if sudo /usr/bin/update_goaccess.sh; then echo -e "Initial GoAccess run completed successfully $CHECK_MARK" return 0 else echo -e "Initial GoAccess run failed $CROSS_MARK" return 1 fi } # Remove the script itself remove_script() { if [ -f "$0" ]; then rm -- "$0" fi if [ -f "task_formatter.sh" ]; then rm task_formatter.sh fi echo -e "Cleaned up $CHECK_MARK" return 0 } #-----------------------------------# # MAIN LOGIC # #-----------------------------------# # Check if print_header function exists if ! command -v print_header >/dev/null 2>&1; then echo "Error: print_header function not found. Formatter may not be properly sourced." exit 1 fi # Print header print_header "$this_script_name" "$this_script_url" echo -e "Running as User: $USER_TO_RUN_AS\nUser Home: $USER_HOME\n" # Run all functions with formatted output if ! format_output setup_goaccess "Setting up GoAccess"; then success=1 fi if ! format_output update_logrotate "Updating logrotate configuration"; then success=1 fi if ! format_output create_goaccess_script "Creating GoAccess update script"; then success=1 fi if ! format_output setup_cron "Setting up cron job"; then success=1 fi if ! format_output initial_run "Running initial GoAccess update"; then success=1 fi format_output remove_script "Removing script" # Final message function final_message() { local script_name=$1 local success=$2 if [[ $success -eq 0 ]]; then log "${CHECK_MARK} $script_name completed successfully." log "GoAccess reports will be updated every 5 minutes" log "You can check the cron job logs at /var/log/goaccess_cron.log" log "Reports available at: /home//htdocs//insights/goaccess.html" else log "${CROSS_MARK} $script_name encountered errors." fi } # Print final message and exit final_message "$this_script_name" $success exit $success