290 lines
No EOL
8.5 KiB
Bash
290 lines
No EOL
8.5 KiB
Bash
#!/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/<username>/htdocs/<domain>/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 |