Shell Scripting Guide : How to Show Performance Stats

Shell Scripting Guide : How to Show Performance Stats

After you read my post about Shell Scripting Guide : Basic Shell Scripting, in this step you will practice a simple project which is can boost your basic shell scripting. Lets make it!

Prerequisites:

  1. Reference project : https://roadmap.sh/projects/server-stats
  2. Acces machine with ssh, this article used ubuntu as an example
  3. Login as root

Make file server-stats.sh

touch server-stats.sh

File server-stats.sh has created, you can check with command ls

Add Executable Access to This File

Because by default, that file not assign to executable, we can add this access with command:

chmod +x server-stat.sh

Open with nano

nano server-stat.sh
if you need install nano, you can type $ sudo apt-get update -y && apt-get install nano -y

You will see blank space but don't worry, we will make the syntax together step-by-step.

Let's Create Line-by-line this Code

In first line, we used a shell script to specify the interpreter that should be used to execute the script which is bash shell with location at /bin/bash

#!/bin/bash

Now, we reset the colour of output shell

# Reset
Color_Off='\033[0m'       # Text Reset

# Regular Colors
Red='\033[0;31m'          # Red
Green='\033[0;32m'        # Green
Yellow='\033[0;33m'       # Yellow
Cyan='\033[0;36m'         # Cyan
White='\033[0;37m'        # White
DarkGray='\033[1;30m'     # DarkGray

Next, we create a function to run percentage of cpu usage. The code is:

cpu_utilization() {
    total_percentage=$(ps -e -o pcpu --no-headers | awk '{s+=$1} END {print s}');

    cpu_count=$(grep -c ^processor /proc/cpuinfo)
    percentage=$(awk "BEGIN {printf \"%.2f\", $total_percentage / $cpu_count}")

    printf " ${Cyan}CPU${Color_Off}"
    echo_progress_bar "$percentage"
    printf "\n"
}

Next, we create a function to run percentage of RAM usage. The code is:

mem_utilization() {
    percentage=$(ps -e -o pmem --no-headers | awk '{s+=$1} END {print s}')

    available=$(awk '/MemAvailable/ {print $2"K"}' /proc/meminfo | numfmt --from=iec --to=iec-i)
    total=$(awk '/MemTotal/ {print $2"K"}' /proc/meminfo | numfmt --from=iec --to=iec-i)

    printf " ${Cyan}RAM${Color_Off}"
    echo_progress_bar "$percentage"
    printf " ${Cyan}Available $White$available ${Cyan}Total $White$total$Color_Off"
    printf "\n"
}

Now, we create a function to show usage of strorage. The code is:

disk_usage() {
    available=$(df -h / --output=avail | tail -n 1)
    percentage=$(df -h / --output=pcent | tail -n 1 | sed 's/%//g')
    used=$(df -h / --output=used | tail -n 1)
    printf "${Cyan}DISK${Color_Off}"
    echo_progress_bar "$percentage"
    printf " ${Cyan}Available $White$available ${Cyan}Used $White$used$Color_Off"
    printf "\n"
}

Next, we create top 5 of every server stats


top_5_process_cpu() {
    ps -e -o pcpu,comm --sort=-pcpu | head -n 6 | tail -n 5
}

top_5_process_mem() {
    ps -e -o pmem,comm --sort=-pmem | head -n 6 | tail -n 5
}

echo_top_5_process_cpu() {
    printf "${Cyan}%-36s${Color_Off}\n" "Top 5 CPU Processes$Color_Off"
    awk '{ printf "%-7s %-29s\n", " "$1"%", $2 }' <(top_5_process_cpu)
}

echo_top_5_process_mem() {
    printf "${Cyan}%-36s${Color_Off}\n" "Top 5 RAM Processes$Color_Off"
    awk '{ printf "%-7s %-29s\n", " "$1"%", $2 }' <(top_5_process_mem)
}

echo_top_5_process_side_by_side() {
    printf "${Cyan}%-36s %-36s${Color_Off}\n" "Top 5 CPU Processes" "Top 5 RAM Processes"
    paste <(top_5_process_cpu) <(top_5_process_mem) | awk '{ printf "%-7s %-29s %-6s %-30s\n", " "$1"%", $2, $3"%", $4 }'
}

Now, lets make a function to show current user has login


echo_current_users() {
    users=$(who | wc -l)
    printf "${Cyan}Current Users ($White$users sessions$Cyan)${Color_Off}\n"
    printf "$(who | cut -d " " -f 1 | sort | awk 'BEGIN { ORS=" " }; {print $1}')"
    printf "\n"
}

After that, we create function to show failed login for every user login


echo_failed_login() {
    printf "${Cyan}Failed Login Attempts${Color_Off}\n"
    if [ ! -f /var/log/auth.log -o ! -r /var/log/auth.log ]; then
        printf "$Red Log file /var/log/auth.log not found or not readable\n$Color_Off"
        return
    fi
    awk '/Failed password/ {print $1}' /var/log/auth.log | sort | uniq -c | sort -nr | head -n 5
}

Next, we create function to show uptime and os in this system


echo_uptime() {
    uptime_days=$(uptime | awk '{print $3" "$4" "$5}' | sed 's/,//g')
    printf "${Cyan}Uptime${Color_Off} $uptime_days $uptime_hours\n"
}

echo_os() {
    os=$(cat /etc/os-release | grep PRETTY_NAME | cut -d "=" -f 2 | sed 's/"//g')
    printf "${Cyan}OS${Color_Off} $os\n"
}

To show progress bar of usage of CPU, RAM, and Strorage, we create a function below:

echo_progress_bar() {
    percentage=$(printf '%.0f\n' $1)
    bar_count=$((percentage / 2))

    if [ $bar_count -lt 35 ]; then
        color=$Green
    elif [ $bar_count -lt 45 ]; then
        color=$Yellow
    else
        color=$Red
    fi

    printf "$White[$color"
    printf '%*s' "$bar_count" '' | tr ' ' '|'
    printf '%*s' $((50 - bar_count)) ' '
    printf "$DarkGray$percentage%%$White]$Color_Off"
}

Now, we create a function to interact with user

usage() {
    echo "Usage: $0 [options]"
    echo "Options:"
    echo "  -c, --cpu       Show CPU utilization"
    echo "  -m, --mem       Show memory utilization"
    echo "  -d, --disk      Show disk usage"
    echo "  -t, --top       Show top 5 processes by CPU and memory usage side by side"
    echo "  --top_ram       Show top 5 processes by memory usage"
    echo "  --top_cpu       Show top 5 processes by CPU usage"
    echo "  -u, --users     Show current users"
    echo "  -f, --failed    Show failed login attempts"
    echo "  --uptime        Show uptime"
    echo "  --os            Show OS"
    echo "  -h, --help      Show this help message"
}

We create condition script performs certain actions only if no arguments are provided when running the script. These actions involve displaying information about CPU, memory, disk, processes, current users, and failed login attempts.

if [ $# -eq 0 ]; then
    cpu_utilization
    mem_utilization
    disk_usage
    printf "\n"
    echo_top_5_process_side_by_side
    echo_current_users
    echo_failed_login
fi

Next, we create conditional script uses a while loop to process command-line arguments provided by the user. For each argument, it uses a case statement to determine the appropriate action, such as calling functions to display system information like CPU, memory, disk usage, and more.

while [ $# -gt 0 ]; do
    case $1 in
        -c|--cpu)
            cpu_utilization
            ;;
        -m|--mem)
            mem_utilization
            ;;
        -d|--disk)
            disk_usage
            ;;
        -t|--top)
            echo_top_5_process_side_by_side
            ;;
        --top_ram)
            echo_top_5_process_mem
            ;;
        --top_cpu)
            echo_top_5_process_cpu
            ;;
        -u|--users)
            echo_current_users
            ;;
        -f|--failed)
            echo_failed_login
            ;;
        --uptime)
            echo_uptime
            ;;
        --os)
            echo_os
            ;;
        -h|--help)
            usage
            exit 0
            ;;
        *)
            echo "Invalid argument: $1 use -h or --help for usage"
            exit 1
            ;;
    esac
    shift
done

Last, don't forget we return exit code 0to show the script has run well

exit 0

Congratulations! We have successfully practice some basic of shell scripting. If you need full of script, you can going to this link:

https://gist.github.com/ridhodevnurhuda/94f0330b510c08ff1247175f06752def

Let’s explore more advanced shell scripting, see you the next post!