diff --git a/monitoring/goaccess-setup.sh b/monitoring/goaccess-setup.sh new file mode 100644 index 0000000..7234a41 --- /dev/null +++ b/monitoring/goaccess-setup.sh @@ -0,0 +1,290 @@ +#!/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 \ No newline at end of file