TOMODACHI SHELL

Free Palestine !! - Free Gaza !!


 
OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0755) :  /../opt/managed_servers/scripts/

 Home   ☍ Command   ☍ Upload File   ☍Info Server   ☍ Buat File   ☍ Mass deface   ☍ Jumping   ☍ Config   ☍ Symlink   ☍ About 

Current File : //../opt/managed_servers/scripts/free_memory.sh
readonly FREE_MEMORY_CHECK_DATA="${BACKGROUND_DATA}/free_memory_check.data";
readonly FREE_MEMORY_CHECK_ERRORS="${BACKGROUND_DATA}/free_memory_check.errors";
readonly INNODB_VALS_TOO_LOW=2;

set_new_innodb_vars(){
        declare -A human_multipliers;
        human_multipliers=([K]=1000 [M]=1000000 [G]=1000000000);
        local innodb_vars="$@";
        local mysql_config="/etc/my.cnf";
        local mysql_config_backup="${mysql_config}_$(date +%s)";
        rsync -q $mysql_config $mysql_config_backup;

        /scripts/restartsrv_mysql --status &>/dev/null || return 1;

        for i_var in $innodb_vars; do
                local var_name=$(cut -d= -f1 <<< $i_var);
                local multiplier=$(cut -d= -f2 <<< $i_var | grep -oP "[a-zA-Z]$" | tr [:lower:] [:upper:]);
                local i_value=$(cut -d= -f2 <<< $i_var | grep -oP "[0-9]+");
                local i_value_min;

                if [[ $multiplier && ${human_multipliers[$multiplier]} ]]; then
                        i_value=$(( $i_value * ${human_multipliers[$multiplier]} ));
                fi;

                if [[ $var_name == "innodb_buffer_pool_size" ]]; then
                        i_value_min=20000000;
                elif [[ $var_name == "innodb_log_file_size" ]]; then
                        i_value_min=5000000;
                fi;

                if [[ $i_value -lt $i_value_min ]]; then
                        return $INNODB_VALS_TOO_LOW;
                fi;

                local i_value_new=$(( $i_value / 2 ));

                sed -i "s/$i_var/$var_name=$i_value_new/" $mysql_config;
                # Restore the mysql config backup if a value wasn't set in the mysql config file
                if [[ -z $(grep "^$var_name=$i_value_new$" $mysql_config) ]]; then
                        rsync -q $mysql_config_backup $mysql_config;
                        rm -f $mysql_config_backup;
                        return 1;
                fi;
        done;

        /scripts/restartsrv_mysql &>/dev/null && {
                rm -f $mysql_config_backup;
                return 0;
        } || {
                rsync -q $mysql_config_backup $mysql_config;
                rm -f $mysql_config_backup;
                return 1;
        }
}

innodb_vars_optimization(){
        local innodb_buffer_pool_size=$(grep innodb_buffer_pool_size <<< "$innodb_vars" | tail -1);
        local innodb_log_file_size=$(grep innodb_log_file_size <<< "$innodb_vars" | tail -1);
        local cur_cpu_utilization=$(top -bn1 | head -5 | grep "^%Cpu(s)" | grep -oP "(?<=ni, ).+(?= id)" | tr -d ' ' |
                awk '{printf "%d", (100 - $1)}');
        local cpu_utilization_threshold=80; # percentage

        if [[ $cur_cpu_utilization -lt $cpu_utilization_threshold ]]; then
                set_new_innodb_vars "$innodb_buffer_pool_size $innodb_log_file_size" && {
                        ram_usage_data[service_status]=$SERVICE_ACTIVE;
                        ram_usage_data[auto_fix_status]=$AUTO_FIX_SUCCESS;
                } || {
                        if [[ $? -eq $INNODB_VALS_TOO_LOW ]]; then
                                # optimization unavailable due to minimal innodb values limits
                                ram_usage_data[recommendations]=$(printf "%s\n\n%s\n\n%s" \
                                        "$(memory_recommendation_mysql_optimization_unavailable_minimal_innodb_vals)"\
                                        "$(memory_recommendation_generic)"\
                                        "$(plan_upgrade_recommendation_as_alternative)" | json_escape);
                        else
                                ram_usage_data[service_status]=$SERVICE_DOWN;
                                ram_usage_data[auto_fix_status]=$AUTO_FIX_FAIL;
                        fi;
                };
        else
                # innodb values cannot be optimized due to high CPU usage
                ram_usage_data[recommendations]=$(printf "%s\n\n%s\n\n%s" \
                        "$(memory_recommendation_mysql_optimization_unavailable_high_cpu_usage)"\
                        "$(memory_recommendation_generic)"\
                        "$(plan_upgrade_recommendation_as_alternative)" | json_escape);
        fi;
}

memory_recommendation_mysql(){
        local mysql_config="/etc/my.cnf";
        local innodb_vars=$(grep -e ^innodb_buffer_pool_size -e ^innodb_log_file_size $mysql_config 2>/dev/null);

        if [[ $(management_type_check) == $COMPLETE && -n $innodb_vars ]]; then
                # If ram_usage_data[auto_fix_status] is unset, notifications will not be sent automatically.
                #unset ram_usage_data[auto_fix_status]; # Currently disabled, to sent notifications automatically.

                innodb_vars_optimization;
        elif [[ $(management_type_check) == $BASIC && -n $innodb_vars ]]; then
                ram_usage_data[recommendations]=$(printf "%s\n\n%s\n\n%s" "$(memory_recommendation_mysql_body)"\
                        "$(memory_recommendation_generic)" "$(plan_upgrade_recommendation_as_alternative)" |
                                json_escape);
        fi;
}

memory_check_recommendation(){
        declare -a proc;
        readarray -t proc <<< "$(ps -eo user,pid,%mem,rss,command)";

        local ps_head=$(head -1 <<< "${proc[0]}");
        # Processes under %1 ram usage will be filtered out
        local processes_sorted=$(process_filter proc);

        local top_proc=$(head -1 <<< "$processes_sorted");
        local mysql_match="mysql|maria";

        # Tickets will not be sent automatically for servers with Complete management when the memory load is unclear
        if [[ $(management_type_check) == $COMPLETE ]]; then
                unset ram_usage_data[auto_fix_status];
        fi;
        # Check if mysql is the top ram usage process
        if [[ -n $(grep -iE "$mysql_match" <<< "$top_proc") ]]; then
                memory_recommendation_mysql;
        else
                ram_usage_data[recommendations]=$(printf "%s\n\n%s" "$(memory_recommendation_generic)"\
                        "$(plan_upgrade_recommendation_as_alternative)" | json_escape);
        fi;

        ram_usage_data[details]=$(echo -e "${ps_head}\n${processes_sorted}" | json_escape);
}

process_filter(){
        local name=$1[@];
        shift;
        local arr=("${!name}");
        local usage_threshold=1;

        for (( i = 1; $i < ${#arr[@]}; ((++i)) )); do
                if [[ $(tr -s ' ' <<< "${arr[$i]}" | cut -d' ' -f3 | cut -d. -f1) -ge $usage_threshold ]]; then
                        echo "${arr[$i]}";
                        fi;
        done | sort -rnk3;
}

bytes_to_human_readable(){
        awk 'function bytes_to_hread(bytes){
        mult_c=split("K M G", mult)
        c=0

        while(bytes > 1000 && c < mult_c){
            bytes=(bytes / 1000)
            ++c
        }

        printf "%.2f %s", bytes, mult[c]
        }
        bytes_to_hread($1)
        ' <<< "$1";
}

memory_check_main(){
        local critical_threshold=10;
        #local warning_threshold=15;

        declare -A ram_usage_data;
        local free_cmd_bytes=$(free -b);
        local ram_total_bytes=$(grep Mem: <<< "$free_cmd_bytes" | awk {'print $2'});
        local ram_free_bytes=$(grep Mem: <<< "$free_cmd_bytes" | awk {'print $7'});
        ram_usage_data[ram_total]=$(bytes_to_human_readable "$(grep Mem: <<< "$free_cmd_bytes" | awk {'print $2'})");
        ram_usage_data[ram_free]=$(bytes_to_human_readable "$(grep Mem: <<< "$free_cmd_bytes" | awk {'print $7'})");
        local free_ram_percentage=$(( $ram_free_bytes * 100 / $ram_total_bytes ));
        ram_usage_data[free_percent]="$free_ram_percentage";
        ram_usage_data[auto_fix_status]=$AUTO_FIX_NOPE;

        if [[ $free_ram_percentage -lt $critical_threshold ]]; then
                ram_usage_data[service_status]=$SERVICE_DOWN;
                memory_check_recommendation;
        #elif [[ $free_ram_percentage -lt $warning_threshold ]]; then
        #        ram_usage_data[service_status]=$SERVICE_WARNING;
        #        memory_check_recommendation;
        else
                ram_usage_data[service_status]=$SERVICE_ACTIVE;
        fi;

        bash_arr_to_json ram_usage_data ${!ram_usage_data[@]} > "$FREE_MEMORY_CHECK_DATA";
}

memory_check(){
        run_check_in_background "memory_check_main" "$FREE_MEMORY_CHECK_DATA" "$FREE_MEMORY_CHECK_ERRORS"\
                "${CHECK_LOCKS_DIR}/${FUNCNAME}.lock";
}

TOMODACHI | Tempest Hacker