Kiểm tra nhanh LEMP stack
Quick Command
curl -sSL https://go.nguyenanhung.com/server-report | bash
server-report.sh
#!/bin/bash
# Get the script's filename without path
directory_name=$(dirname "$0")
script_name=$(basename "$0")
# Generate a unique lock file name by combining the directory name and script name,
# converting them to lowercase, replacing spaces and non-alphanumeric characters with hyphens,
locked_name="${directory_name}-${script_name}-by-${USER}"
locked_name=$(echo "$locked_name" | tr '[:upper:]' '[:lower:]') # Convert to lowercase
locked_name=$(echo "$locked_name" | sed -E 's/[^a-z0-9]+/-/g') # Replace spaces and non-alphanumeric characters with hyphens
locked_name=$(echo "$locked_name" | sed -E 's/^-+|-+$//g') # Remove any extra hyphens at the beginning or end of the string
mkdir -p /tmp/hungng-locked && chmod 0777 /tmp/hungng-locked
locked_filename="/tmp/hungng-locked/${locked_name}.lock"
# Lock the script so that only one instance can run at a time.
exec 200>"${locked_filename}" || exit 1
flock -n 200 || exit 1
##################################################################################
# _ _ _ _ #
# | | | | | \ | | #
# | |__| |_ _ _ __ __ _ | \| | __ _ _ _ _ _ ___ _ __ #
# | __ | | | | '_ \ / _` | | . ` |/ _` | | | | | | |/ _ \ '_ \ #
# | | | | |_| | | | | (_| | | |\ | (_| | |_| | |_| | __/ | | | #
# |_| |_|\__,_|_| |_|\__, | |_| \_|\__, |\__,_|\__, |\___|_| |_| #
# __/ | __/ | __/ | #
# |___/ |___/ |___/ #
#--------------------------------------------------------------------------------#
# BEAR Manage Server Script Configure #
# Manage Server by Hung Nguyen - [email protected] - https://nguyenanhung.com #
# Any copying without written permission is a violation of copyright policy! #
##################################################################################
DEVELOP_BY="Hung Nguyen - [email protected]"
SCRIPT_VERSION="2.0.4"
# Bash variables
export NC='\033[0m'
export RED='\033[0;31m'
export GREEN='\033[0;32m'
export YELLOW='\033[0;33m'
export CYAN='\033[0;36m'
export NAVAJO_WHITE='\033[38;5;223m' # Navajo white
print_message() {
local LINE="----------------------------------------------------------------------"
if [ "$1" = "" ]; then
echo
echo "$LINE"
echo
else
echo
echo "$LINE"
echo -e "${CYAN}$1${NC}"
echo "$LINE"
echo
fi
}
message() {
local level
level=$(echo "$1" | tr '[:lower:]' '[:upper:]')
local message=$2
# Color
local RSC='\033[0m'
local FATAL='\033[1;41m\033[1;33m' # Nền đỏ - chữ vàng
local ERROR='\033[41m\033[1;37m' # Nền đỏ - Màu trắng đậm
local FAILED='\033[0;31m' # Màu đỏ
local INFO='\033[0;92m' # Màu xanh lá nhạt
local DEBUG='\033[0;35m' # Magenta
local TRACE='\033[35m' # Magenta
local EMERGENCY='\033[41;1m' # Màu nền đỏ đậm nhấp nháy
local CRITICAL='\033[41m\033[1;32m' # Xanh lá cây đậm - Nền đỏ
local ALERT='\033[1;31m' # Màu cam đậm
local WARNING='\033[0;33m' # Màu vàng
local NOTICE='\033[0;36m' # Màu xanh dương nhạt
local SUCCESS='\033[1;36m' # Cyan đậm
local LINK='\033[1;34m' # Blue đậm
local SUGGEST='\033[38;5;223m' # Navajo white
# Write message
case $level in
FATAL) echo -e "${level}: ${FATAL}${message}${RSC}" ;;
ERROR | ERR) echo -e "${level}: ${ERROR}${message}${RSC}" ;;
FAILED) echo -e "${level}: ${FAILED}${message}${RSC}" ;;
WARN | WARNING) echo -e "${level}: ${WARNING}${message}${RSC}" ;;
INFO) echo -e "${level}: ${INFO}${message}${RSC}" ;;
SUCCESS | FINISHED) echo -e "${level}: ${SUCCESS}${message}${RSC}" ;;
LINK | URL) echo -e "${level}: ${LINK}${message}${RSC}" ;;
DEBUG) echo -e "${level}: ${DEBUG}${message}${RSC}" ;;
TRACE | CURRENT) echo -e "${level}: ${TRACE}${message}${RSC}" ;;
EMERGENCY) echo -e "${level}: ${EMERGENCY}${message}${RSC}" ;;
ALERT) echo -e "${level}: ${ALERT}${message}${RSC}" ;;
CRITICAL) echo -e "${level}: ${CRITICAL}${message}${RSC}" ;;
NOTICE | NOTE) echo -e "${level}: ${NOTICE}${message}${RSC}" ;;
SUGGEST) echo -e "${level}: ${SUGGEST}${message}${RSC}" ;;
*) echo -e "${message}" ;;
esac
}
has_command() {
command -v "$1" &>/dev/null
}
os_detect() {
local os="Unknown"
if [[ "$(uname)" == "Darwin" ]]; then
os="MacOS"
elif [[ -f /etc/os-release ]]; then
source /etc/os-release
case "$ID" in
rhel | centos | rocky | rockylinux | almalinux | fedora)
os="RHEL"
;;
ubuntu | linuxmint | debian)
os="Ubuntu"
;;
alpine)
os="Alpine"
;;
opensuse)
os="OpenSUSE"
;;
sles)
os="SLES"
;;
esac
elif command -v lsb_release &>/dev/null; then
local distro
distro=$(lsb_release -si)
case "$distro" in
Ubuntu | LinuxMint | Debian)
os="Ubuntu"
;;
Fedora | CentOS | RedHatEnterpriseServer | Rocky | RockyLinux | AlmaLinux)
os="RHEL"
;;
openSUSE)
os="OpenSUSE"
;;
SUSE)
os="SLES"
;;
esac
fi
echo "$os"
}
is_installed() {
local package_name=$1
if [[ -z "$package_name" ]]; then
message ERROR "Package name is required."
return 1
fi
if command -v rpm &>/dev/null; then
if rpm -q "$package_name" &>/dev/null; then
return 0
else
return 1
fi
elif command -v dpkg-query &>/dev/null; then
if dpkg-query -W -f='${Status}' "$package_name" 2>/dev/null | grep -q "installed"; then
return 0
else
return 1
fi
else
message ERROR "Unsupported package manager."
return 1
fi
}
install_need_package() {
local package=$1
if command -v dnf &>/dev/null; then
sudo dnf install -y "$package"
elif command -v yum &>/dev/null; then
sudo yum install -y "$package"
elif command -v apt &>/dev/null; then
sudo apt install -y "$package"
else
echo "Unsupported package manager. Please install $package manually."
return 1
fi
}
install_package() {
if ! is_installed "$1"; then
print_message "Installing package $1"
if install_need_package "$1"; then
message INFO "Package $1 installed successfully!"
else
message ERROR "Error installing package $1!"
fi
fi
}
install_required_scripts() {
install_package bc
}
install_required_scripts
display_script_information() {
local SCRIPT_NAME
SCRIPT_NAME=${1:-"BEAR Manage Server Script"}
echo "==========================================================="
echo
echo " _ _ _ _ _____ "
echo " | | | | | \ | | / ____|"
echo " | |__| | _ _ _ __ __ _ | \| | | | __ "
echo " | __ | | | | | | '_ \ / _\` | | . \` | | | |_ |"
echo " | | | | | |_| | | | | | | (_| | | |\ | | |__| |"
echo " |_| |_| \__,_| |_| |_| \__, | |_| \_| \_____|"
echo " __/ | "
echo " |___/ "
echo
echo -e "Powered by ${NAVAJO_WHITE}${DEVELOP_BY}${NC}"
echo
echo -e "${GREEN}${SCRIPT_NAME}${NC} - version ${YELLOW}${SCRIPT_VERSION}${NC}"
echo
echo "==========================================================="
}
display_script_information "Script Check Server Resources"
calculator_disk() {
local total_size=0
local size_t size unit
local array=("$@") # Lưu toàn bộ tham số vào mảng
for size in "${array[@]}"; do
size_t="${size:0:${#size}-1}" # Lấy phần số
unit="${size:(-1)}" # Lấy ký tự cuối cùng làm đơn vị
# Chuyển đổi các đơn vị
case "$unit" in
M) size=$(awk 'BEGIN{printf "%.1f", '"$size_t"' / 1024}') ;; # Từ MB -> GB
T) size=$(awk 'BEGIN{printf "%.1f", '"$size_t"' * 1024}') ;; # Từ TB -> GB
G) size="$size_t" ;; # GB không cần thay đổi
*) size=0 ;; # Nếu đơn vị không phải M, G, T thì coi như 0
esac
# Cộng kích thước vào tổng
total_size=$(awk 'BEGIN{printf "%.1f", '"$total_size"' + '"$size"'}')
done
echo "${total_size}"
}
count_processes_by_user() {
# Input: $1 is the user to check
local check_user=$1
# Check if user is provided
if [[ -z "$check_user" ]]; then
echo 0 # Return 0 if no user is provided
return
fi
# Count processes by user, including threads
local process_count
process_count=$(ps -eLf | awk -v pattern="$1" '$0 ~ pattern {count++} END {print count}')
# Output the result
echo "$process_count"
}
fetch_public_ip() {
local CHECK_URL IP
for CHECK_URL in "https://checkip.amazonaws.com/" "https://icanhazip.com/" "https://whatismyip.akamai.com/" "https://api.ipify.org/" "https://cpanel.net/showip.cgi" "https://myip.directadmin.com/" "https://ipinfo.io/ip"; do
IP=$(curl -s --max-time 1 "${CHECK_URL}") && [ -n "${IP}" ] && echo "${IP}" && return 0
done
return 1
}
########################################################################################################################
cpu_name=$(awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')
cpu_cores=$(awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo)
cpu_freq=$(awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')
cpu_load=$(grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}')
cpu_bogo_mips=$(lscpu | grep 'BogoMIPS:' | awk '{print $2}')
cpu_cache_l1=$(lscpu | grep 'L1d' | awk '{print $3 " " $4}')
cpu_cache_l2=$(lscpu | grep 'L2' | awk '{print $3 " " $4}')
cpu_cache_l3=$(lscpu | grep 'L3' | awk '{print $3 " " $4}')
server_ram_total=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
server_ram_mb=$(echo "scale=0;$server_ram_total/1024" | bc)
total_ram=$(free -m | awk '/Mem/ {print $2}')
used_ram=$(free -m | awk '/Mem/ {print $3}')
ram_usage_percent=$(((used_ram * 100) / total_ram))
total_swap=$(free -m | awk '/Swap/ {print $2}')
used_swap=$(free -m | awk '/Swap/ {print $3}')
if [ "$total_swap" -eq 0 ]; then
swap_usage_percent=0
else
swap_usage_percent=$(((used_swap * 100) / total_swap))
fi
#server_hdd=$(df -h | awk 'NR==5 {print $2}')
free_hdd=$(df -h | awk 'NR==5 {print $4}')
disk_size1=$(LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $2}')
disk_size2=$(LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $3}')
disk_total_size=$(calculator_disk "${disk_size1[@]}")
disk_used_size=$(calculator_disk "${disk_size2[@]}")
disk_used_percent=$(df -h / | tail -n 1 | awk '{print $5}')
free_hdd_size=$(calculator_disk "${free_hdd[@]}")
#server_swap_total=$(awk '/SwapTotal/ {print $2}' /proc/meminfo)
#server_swap_mb=$(echo "scale=0;$server_swap_total/1024" | bc)
max_children=$(echo "scale=0;$server_ram_mb*0.4/30" | bc)
min_spare_server=$((cpu_cores * 2))
max_spare_server=$((cpu_cores * 4))
pm_start_servers=$((min_spare_server + (max_spare_server - min_spare_server) / 2))
server_os_compatibility=$(grep '^ID_LIKE=' /etc/os-release | cut -d= -f2- | tr -d '"')
os_compatibility="${server_os_compatibility^^}"
os_name=$(grep '^PRETTY_NAME=' /etc/os-release | cut -d= -f2- | tr -d '"')
server_os_virtualization=$(hostnamectl | grep "Virtualization" | awk '{print $2}')
os_virtualization="${server_os_virtualization^^}"
ServerIPv4="$(ip addr show | awk '/inet / && !/127.0.0.1/ {print $2}' | cut -d'/' -f1 | grep -Ev '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1]))')"
ServerIPv6="$(ip addr show | awk '/inet6/ && !/scope link/ {print $2}' | cut -d'/' -f1 | grep -vE '^fe80|^::1')"
########################################################################################################################
print_message
message INFO "Date : ${YELLOW}$(date)${NC} - ${GREEN}$(date "+%Y-%m-%d %H:%M:%S")${NC}"
message INFO "Server Public IP v4 : ${YELLOW}$(fetch_public_ip)${NC}"
message INFO "Server IP v4 Address : ${YELLOW}${ServerIPv4}${NC}"
message INFO "Server IP v6 Address : ${YELLOW}${ServerIPv6}${NC}"
message INFO "CPU model : ${YELLOW}$cpu_name${NC}"
message INFO "Number of cores : ${YELLOW}$cpu_cores${NC}"
message INFO "CPU frequency : ${YELLOW}$cpu_freq${NC} MHz"
message INFO "CPU usage load : ${YELLOW}$cpu_load${NC}"
message INFO "CPU BogoMIPS : ${YELLOW}$cpu_bogo_mips${NC}"
message INFO "CPU L1 Cache : ${YELLOW}$cpu_cache_l1${NC}"
message INFO "CPU L2 Cache : ${YELLOW}$cpu_cache_l2${NC}"
message INFO "CPU L3 Cache : ${YELLOW}$cpu_cache_l3${NC}"
message INFO "Max Children : ${YELLOW}$max_children${NC}"
message INFO "Start Servers : ${YELLOW}$pm_start_servers${NC}"
message INFO "Min Spare Server : ${YELLOW}$min_spare_server${NC}"
message INFO "Max Spare Server : ${YELLOW}$max_spare_server${NC}"
message INFO "Total size of Disk : ${YELLOW}$disk_total_size${NC} GB (Used: ${GREEN}${disk_used_percent}${NC} [${NAVAJO_WHITE}${disk_used_size}${NC} GB] - Available: ${GREEN}${free_hdd_size}${NC} GB)${NC}"
message INFO "Total amount of Memory : ${YELLOW}$total_ram${NC} MB (Used: ${GREEN}${ram_usage_percent}${NC}% - ${NAVAJO_WHITE}$used_ram${NC} MB)"
message INFO "Total amount of Swap : ${YELLOW}$total_swap${NC} MB (Used: ${GREEN}${swap_usage_percent}${NC}% - ${NAVAJO_WHITE}$used_swap${NC} MB)"
message INFO "OS Name : ${YELLOW}${os_name}${NC}"
message INFO "OS Architecture : ${YELLOW}$(uname -m)${NC}"
message INFO "OS Kernel Version : ${YELLOW}$(uname -r)${NC}"
message INFO "OS Virtualization : ${YELLOW}$os_virtualization${NC}"
message INFO "OS Compatibility : ${YELLOW}$os_compatibility${NC}"
message INFO "System Uptime : ${YELLOW}$(awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60} {printf("%d days, %d hour %d min\n",a,b,c)}' /proc/uptime)${NC}"
message INFO "Load average : ${YELLOW}$(w | head -1 | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')${NC}"
message INFO "Users logged : ${YELLOW}$(who | wc -l)${NC}"
message INFO "Total process running : ${YELLOW}$(ps aux | wc -l)${NC}"
if has_command mysql; then
message INFO "MySQL : ${NC}Process running: ${YELLOW}$(count_processes_by_user "mysql")${NC} - Version: ${GREEN}$(mysql -V | awk '{gsub(/,/, "", $5); print $5}')${NC}"
fi
if has_command php-fpm; then
WP_CLI_Version=""
if has_command wp; then
WP_CLI_Version=" - WP-CLI version: ${GREEN}$(wp --info | grep "WP-CLI version" | awk '{print $3}')${NC}"
fi
message INFO "PHP Information : ${NC}Process running: ${YELLOW}$(count_processes_by_user "php-fpm")${NC} - Path to PHP: ${YELLOW}$(which php)${NC} - PHP version: ${GREEN}$(php -v | awk '/^PHP/{print $2}')${NC} ${WP_CLI_Version}"
fi
if has_command nginx; then
message INFO "Nginx : ${NC}Process running: ${YELLOW}$(count_processes_by_user "nginx")${NC} - Version: ${GREEN}$(nginx -v 2>&1 | awk -F'/' '{print $2}')${NC}"
fi
if is_installed nginx-amplify-agent; then
message INFO "Nginx Amplify agent running : ${YELLOW}$(count_processes_by_user "amplify-agent")${NC}"
fi
if has_command httpd; then
message INFO "Apache : ${NC}Process running: ${YELLOW}$(count_processes_by_user "apache")${NC} - Version: ${GREEN}$(httpd -v | awk '/^Server version:/{print $3, $4, $5}')${NC}"
fi
if has_command perl; then
if command -v rpm &>/dev/null; then
perl_version=$(rpm -q perl)
elif command -v dpkg-query &>/dev/null; then
perl_version=$(dpkg-query -W perl | awk '{print $2}')
else
perl_version=""
fi
message INFO "Perl Information : ${NC}Process running: ${YELLOW}$(count_processes_by_user "perl")${NC} - Path to Perl: ${YELLOW}$(which perl)${NC} - Perl version: ${GREEN}${perl_version}${NC}"
fi
if has_command redis-cli; then
message INFO "Redis : ${NC}Process running: ${YELLOW}$(count_processes_by_user "redis")${NC} - Version: ${GREEN}$(redis-server --version | awk '{print $3}' | cut -d "=" -f 2)${NC}"
fi
if is_installed memcached; then
message INFO "Memcached : ${NC}Process running: ${YELLOW}$(count_processes_by_user "memcached")${NC} - Version: ${GREEN}$(memcached -V | awk '{print $2}')${NC}"
fi
if has_command gearmand; then
message INFO "Gearmand : ${NC}Process running: ${YELLOW}$(count_processes_by_user "gearmand")${NC} - Version: ${GREEN}$(gearmand --version | awk '{print $2}')${NC}"
fi
if has_command supervisord; then
message INFO "Supervisord : ${NC}Process running: ${YELLOW}$(count_processes_by_user "supervisord")${NC} - Version: ${GREEN}$(supervisord -v)${NC}"
fi
if has_command gitlab-runner; then
message INFO "Gitlab-Runner : ${NC}Process running: ${YELLOW}$(count_processes_by_user "gitlab-runner")${NC} - Version: ${GREEN}$(gitlab-runner --version | grep "Version" | awk '{print $2}')${NC}"
fi
if has_command docker; then
message INFO "Docker : ${NC}Process running: ${YELLOW}$(count_processes_by_user "docker")${NC} - ${GREEN}$(docker --version)${NC}"
print_message
docker ps
print_message
fi
print_message "Check storage on your server"
# Function to check if a device is HDD or SSD
check_storage_type() {
# Get the list of devices and their rotational flag (ROTA)
local devices_info device rota
devices_info=$(lsblk -d -o name,rota | tail -n +2) # Skip the header
# Iterate through each device and check if it's HDD or SSD
while read -r device rota; do
if [[ "$rota" -eq 1 ]]; then
printf "INFO: ${GREEN}%-27s${NC} : ${YELLOW}%-50s${NC} \n" "Storage '$device' is" "HDD Disk"
elif [[ "$rota" -eq 0 ]]; then
printf "INFO: ${GREEN}%-27s${NC} : ${YELLOW}%-50s${NC} \n" "Storage '$device' is" "SSD Disk"
else
printf "INFO: ${GREEN}%-27s${NC} : ${YELLOW}%-50s${NC} \n" "Storage '$device' is" "Unknown type"
fi
done <<<"$devices_info"
}
# Run the function
check_storage_type
print_message "Finished"
unset NAVAJO_WHITE CYAN YELLOW GREEN RED NC
Đăng nhận xét