...
Code Block |
---|
./castor-change-log-level.sh -d 192.168.8.84 -p admin:datacore -i 20 -t 10 |
Example 2: Set node(s) log level to debug (10) and keep it for 10 seconds
Code Block |
---|
./castor-change-log-level.sh -d 192.168.8.84,192.168.8.86 -p admin:datacore -i debug -t 10 |
Example 3: Run in background mode with verbose logging
Code Block |
---|
./castor-change-log-level.sh -d 192.168.8.84 -p admin:datacore -i 20 -t 30 --detach -v |
Example
...
4: Running the Script at a Specific Time
The at
command can used to schedule the scrip to run at a later time. This is useful when you need to start collecting debug logs at a specific hour.
Example 5: Schedule the script to run at 3:00 AM and collect debug logs for 1 hour
...
Code Block | ||
---|---|---|
| ||
#!/bin/bash # Written by Milton Suen (milton.suen@datacore.com) Oct 31, 2024 # Revision: Update to support running the script in a persistentdetachable session using screen or tmux. # # Define colors RED='\033[0;31m' BOLD_Revision: 2025-02-20 Add support node(s) level log level change. # Revision: 2025-02-26 SUPSCR-209 Auto detect CSN or SCS to adjust castor.log file path. # Define colors RED='\033[0;31m' BOLD_RED='\033[1;31m' GREEN='\033[0;32m' BOLD_GREEN='\033[1;32m' UNDERLINE_BOLD_GREEN='\033[4;32m' YELLOW='\033[0;33m' BOLD_YELLOW='\033[1;33m' BLUE='\033[0;34m' BOLD_BLUE='\033[1;34m' MAGENTA='\033[0;35m' BOLD_MAGENTA='\033[1;35m' CYAN='\033[0;36m' BOLD_CYAN='\033[1;36m' RESET='\033[0m' # Reset color to default # Function to display usage information usage() { echo "Usage: $0./castor-change-log-level10.sh -d swarm_ip -p admin:password [-i new_log_level | -L new_node_log_level] [-t duration_in_seconds] [--persistent] [-v]D]" echo " -d, --swarm_ip IP address of the Swarm API endpoint. (or set SCSP_HOST environment variable)Supports single or multiple IPs separated by \",\", \";\" or \" \"." echo " -p, --credentials Credentials in the format admin:password" echo " -i, --log.level If multiple IPs are provided, the script will update Newthe log level to setfor all nodes." echo " -t, --time Duration in seconds to keep the new log level (optional)"Alternatively, set the SCSP_HOST environment echovariable "to the --persistent Swarm IP.)" echo " -p, --credentials Run the script in a detachedCredentials sessionin usingthe screen or tmuxformat admin:password" echo " -vi, --verboselog.level New cluster Enablelog verboselevel modeto forset debug messages" exit 1 } # Default options persistent=false verbose=false output_log="script_output.log" # Log file for capturing persistent session output # Function to display debug messages if verbose mode is enabled debug() { if $verbose; then (5, 10, 15, 20, 30, 40, 50, chatter, debug, announce, info, error, critical, default)" echo " -L, --node.log.level New node log level to set (0, 5, 10, 15, 20, 30, 40, 50, chatter, debug, announce, info, error, critical, default)" echo "[DEBUG] $1" fi } # Function to check if either 'screen' or 'tmux' is installed check_screen_or_tmux() { if ! command**Either -i or -vL screen &>/dev/null && ! command -v tmux &>/dev/null; then echo "Error: Neither 'screen' nor 'tmux' is installed. Cannot run in persistent mode." persistent=false # Disable persistent session fi } # Function to format file size format_size() { local size=$1 if (( size >= 1073741824 )); then echo "$(awk "BEGIN {printf \"%.1fGB\", $size/1073741824}")" elif (( size >= 1048576 )); then echo "$(awk "BEGIN {printf \"%.1fMB\", $size/1048576}")" elif (( size >= 1024 )); then echo "$(awk "BEGIN {printf \"%.1fKB\", $size/1024}")" else echo "${size}B" fi } # Function to format duration format_duration() { local duration=$1 local hours=$((duration / 3600)) local minutes=$(( (duration % 3600) / 60 )) local seconds=$((duration % 60)) printf "%02d:%02d:%02d" $hours $minutes $seconds } # Function to check if jq is available and set up JSON parsing method check_jq() { if [[ -x "/usr/local/bin/jq" ]]; then echo "/usr/local/bin/jq" elif [[ -x "$(pwd)/jq" ]]; then echo "$(pwd)/jq" elif command -v jq &>/dev/null; then echo "jq" else echo "grep" fi } jq_or_grep=$(check_jq) # Parse input arguments while [[ "$#" -gt 0 ]]; do case $1 in -d|--swarm_ip) swarm_ip="$2"; shift 2 ;; -p|--credentials) credentials="$2"; shift 2 ;; -i|--log.level) new_log_level="$2"; shift 2 ;; -t|--time) if [[ -n "$2" && "$2" != -* ]]must be specified, but not both.**" echo " -t, --time (Optional) Duration in seconds to keep the new log level (must be greater than 0)" echo " -D, --detach (Optional) Detach the script from the current terminal and run in a detachable session using screen or tmux" exit 1 } # Default options detachable=false debug=false output_log="script_output.log" # Log file for capturing detachable session output log_level_type="cluster" # Default log level type default_log_level=30 # Default log level log_file="/var/log/datacore/castor.log" # Default log file location # Global associative array for log levels declare -A log_levels=( [5]="chatter" [10]="debug" [15]="audit" [20]="info" [30]="warning" [40]="error" [45]="defect" [50]="critical" [60]="announce" [30]="default" ) # Global associative array for log level names declare -A log_level_names=( ["chatter"]=5 ["debug"]=10 ["audit"]=15 ["info"]=20 ["warning"]=30 ["error"]=40 ["defect"]=45 ["critical"]=50 ["announce"]=60 ["default"]=30 ) # Function to display debug messages if debug mode is enabled debug_msg() { if $debug; then echo -e "[DEBUG] $1" >> "$output_log" fi } # Function to check if either 'screen' or 'tmux' is installed check_screen_or_tmux() { if ! command -v screen &>/dev/null && ! command -v tmux &>/dev/null; then echo "Error: Neither 'screen' nor 'tmux' is installed. Cannot run in detachable mode." detachable=false # Disable detachable session debug_msg "detachable=${YELLOW}false${RESET}" fi } # Function to format file size format_size() { local size=$1 if (( size >= 1073741824 )); then echo "$(awk "BEGIN {printf duration="$2\"%.1fGB\", $size/1073741824}")" elif (( size >= 1048576 )); then shift 2 echo "$(awk "BEGIN {printf \"%.1fMB\", $size/1048576}")" elif else(( size >= 1024 )); then echo "$(awk "BEGIN read -p "Enter duration in seconds: " duration{printf \"%.1fKB\", $size/1024}")" else echo "${size}B" shift fi } # Function to format duration format_duration() { fi local duration=$1 local hours=$((duration / ;;3600)) local minutes=$(( (duration % --persistent3600) persistent=true; shift ;;/ 60 )) local seconds=$((duration -v|--verbose) verbose=true; shift ;; *) usage ;; esac done # Check if 'screen' or 'tmux' is installed check_screen_or_tmux # If swarm_ip is not provided, try using SCSP_HOST environment variable % 60)) printf "%02d:%02d:%02d" $hours $minutes $seconds } # Function to check if jq is available and set up JSON parsing method check_jq() { if [[ -zx "$swarm_ip/usr/local/bin/jq" ]]; then ifecho "/usr/local/bin/jq" elif [[ -nx "$SCSP_HOST$(pwd)/jq" ]]; then swarm_ip="$SCSP_HOST" echo "$(pwd)/jq" elif command -v jq debug "Using Swarm IP from SCSP_HOST: $swarm_ip&>/dev/null; then echo "jq" else echo "grep"Error: swarm_ip not provided and SCSP_HOSTfi is} not set." jq_or_grep=$(check_jq) # Function to determine the log file usage path determine_log_file() { fi fi if # Check if required arguments are provided if [[ -z "$credentials" || -z "$new_log_level[[ -f "/var/log/datacore/castor.log" ]]; then echo "/var/log/datacore/castor.log" elif [[ -f "/var/log/caringo/castor.log" ]]; then usage fi # Retrieve cluster name and handle JSON parsing debug "Retrieving the cluster name from Swarm API." if [[ "$jq_or_grep" == "grep" ]]; then clusterName=$(curl --user "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters" | grep -oP '"name":\s*"\K[^"]+') else clusterName=$(curl --user "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters" | "$jq_or_grep" -r '._embedded.clusters[0].name') fi if [[ -z "$clusterName" ]]; then echo "Failed to retrieve the cluster name. Please check your inputs." exit 1 fi debug "Cluster Name: $clusterName" # Main logic function to run the script tasks main_script() { local swarm_ip="$1" local credentials="$2" local new_log_level="$3" local duration="$4" local clusterName="$5" local log_file="/var/log/datacore/castor.log" local initial_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) local current_log_level local jq_or_grep="$6" # Display initial information echo -e "Swarm IP: ${GREEN}$swarm_ip${RESET}" echo -e "Credentials: ${GREEN}[hidden for security]${RESET}" echo -e "Cluster Name: ${GREEN}$clusterName${RESET}" debug "Starting main_script function..." # Retrieve current log level if [[ "$jq_or_grep" == "grep" ]]; then current_log_level=$(curl --user "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" | grep -oP '"value":\s*\K[0-9]+') elseecho "/var/log/caringo/castor.log" else echo "Error: Log file not found in /var/log/datacore/castor.log or /var/log/caringo/castor.log" exit 1 fi } log_file=$(determine_log_file) # Parse input arguments while [[ "$#" -gt 0 ]]; do case $1 in -d|--swarm_ip) swarm_ip="$2"; debug_msg "Set swarm_ip to $swarm_ip"; shift 2 ;; -p|--credentials) credentials="$2"; debug_msg "Set credentials"; shift 2 ;; -i|--log.level) if [[ -n "$new_log_level" ]]; then echo "Error: Options -i (cluster log leve) and -L (node log level) cannot be used together." usage fi if [[ ${log_level_names[$2]} ]]; then new_log_level=${log_level_names[$2]} elif [[ ${log_levels[$2]} ]]; then new_log_level=$2 else echo "Invalid log level: $2" exit 1 fi currentnew_log_level_name=$(curl --user "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" | "$jq_or_grep" -r '.value') fi{log_levels[$new_log_level]} log_level_type="cluster" echo "" echo -e "New log level: ${BOLD_GREEN}$new_log_level${RESET}" default_log_level=30 echo -e "Current log level is ${GREEN}$currentdebug_msg "Set new_log_level to $new_log_level ($new_log_level.${RESET}"_name)" shift 2 ;; # Skip update if new level matches the current level -L|--node.log.level) if [[ "$current_log_level" -eq-n "$new_log_level" ]]; then echo "" echo "Error: echoOptions -ei "Log(cluster levellog isleve) alreadyand set-L to ${BOLD_GREEN}$new_log_level${RESET}. No changes made."(node log level) cannot be used together." returnusage fi # Update thefi log level using PUT echo -e "Updating log levelif to[[ ${GREEN}$newlog_log_level${RESET}..." level_names[$2]} ]]; then response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ new_log_level=${log_level_names[$2]} "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" \ elif -d[[ "{\"value\": $new_log_level}") if [[ "$jq_or_grep" == "grep" ]]; then${log_levels[$2]} || $2 -eq 0 ]]; then updatednew_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')$2 else updatednew_log_level_name=$(echo "$responsedefault" | "$jq_or_grep" -r '.value') fi else if [[ "$updated_log_level" -eq "$new_log_level" ]]; then echo -e "Log"Invalid log level changed successfully from ${GREEN}$current_log_level${RESET} → ${BOLD_GREEN}$new_log_level${RESET}.": $2" else exit 1 echo -e "Failed to update log level. Response: ${RED}$response${RESET}"fi exit 1 log_level_type="node" fi # Countdown and revert default_log _level=0 if [[ -n "$duration" && "$duration" -gt 0 ]]; then debug_msg "Set new_log_level to $new_log_level ($new_log_level_name)" echo -e "Keeping log level at ${YELLOW}$new_log_level${RESET} for ${YELLOW}$duration${RESET} second(s)..." shift 2 echo -e "" ;; for ((i=duration; i>0; i-t|--)time); do if printf[[ -v countdown "%02d:%02d:%02d" $((i/3600)) $(( (i%3600) / 60 )) $((i%60))n "$2" && "$2" != -* && "$2" -gt 0 ]]; then echo -ne "Countdown: ${YELLOW}$countdown${RESET} remaining...\r"duration="$2" sleep 1debug_msg "Set duration to $duration" done echo -e "\n\nTime's up! Reverting log level back to ${GREEN}$current_log_level${RESET}..." shift 2 else response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ echo "Error: Duration must be a number greater "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" \than 0." -d "{\"value\": $current_log_level}") exit 1 if [[ "$jq_or_grep" == "grep" ]]; thenfi ;; reverted_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') elseD|--detach) detachable=true; debug_msg "Set detachable to true"; shift ;; --debug) debug=true; debug_msg "Set reverted_log_level=$(echo "$response" | "$jq_or_grep" -r '.value')debug to true"; shift ;; *) usage fi;; esac done debug_msg "Set final_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) size_diff=$(( final_size - initial_size )) size_diff_formatted=$(format_size "$size_diff")log_level_type to ${YELLOW}$log_level_type${RESET}" # Set default values if not provided if [[ -z "$new_log_level" ]]; then if [[ "$log_level_type" == "cluster" ]]; then durationnew_log_formatted=$(format_duration "$duration")level=$default_log_level else echo -e "Approximate ${BOLD_GREEN}$size_diff_formatted${RESET} new logs were generated at log level ${BOLD_GREEN}$new_log_level${RESET}. Current castor.log size is ${BOLD_GREEN}$(format_size "$final_size")${RESET} after $duration_formatted." if [[ "$reverted_log_level" -eq "$current_log_level" ]]; then new_log_level=0 fi new_log_level_name="default" new_log_level_name=${log_levels[$new_log_level]} debug_msg "Set default new_log_level to $new_log_level ($new_log_level_name)" fi # Check if 'screen' or 'tmux' is installed check_screen_or_tmux # If swarm_ip is not provided, try using SCSP_HOST environment variable if [[ -z "$swarm_ip" ]]; then if [[ -n "$SCSP_HOST" ]]; then swarm_ip="$SCSP_HOST" debug "Using Swarm IP from SCSP_HOST: $swarm_ip" else echo "Error: swarm_ip not provided and SCSP_HOST is not set." usage fi fi # Check if required arguments are provided if [[ -z "$credentials" || -z "$new_log_level" ]]; then usage fi # Split the swarm_ip into an array of IP addresses if it contains delimiters IFS=';, ' read -r -a ip_array <<< "$swarm_ip" # Retrieve cluster name and handle JSON parsing using the first IP address debug_msg "Retrieving the cluster name from Swarm API using IP: ${ip_array[0]}" if [[ "$jq_or_grep" == "grep" ]]; then clusterName=$(curl --user "$credentials" -sS "http://${ip_array[0]}:91/api/storage/clusters" | grep -oP '"name":\s*"\K[^"]+') else clusterName=$(curl --user "$credentials" -sS "http://${ip_array[0]}:91/api/storage/clusters" | "$jq_or_grep" -r '._embedded.clusters[0].name') fi if [[ -z "$clusterName" ]]; then echo "Failed to retrieve the cluster name. Please check your inputs." exit 1 fi debug_msg "Cluster Name: $clusterName" # Main logic function to run the script tasks main_script() { local swarm_ip="$1" local credentials="$2" local new_log_level="$3" local new_log_level_name="$4" local duration="$5" local log_level_type="$6" # local log_file="/var/log/datacore/castor.log" local initial_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) local current_log_level local clusterName="$7" local jq_or_grep="$8" local debug="$9" debug_msg "**********************************************************" debug_msg "local variables" debug_msg "Swarm IP: $swarm_ip" debug_msg "Credentials: $credentials" debug_msg "New Log Level: $new_log_level ($new_log_level_name)" debug_msg "Duration: $duration" debug_msg "Log Level Type: $log_level_type" debug_msg "Log File: $log_file" debug_msg "Initial Log File Size: $initial_size" debug_msg "Current Log Level: $current_log_level" debug_msg "Cluster Name: $clusterName" debug_msg "jq_or_grep: $jq_or_grep" debug_msg "Debug: $debug" debug_msg "**********************************************************" # Split the swarm_ip into an array of IP addresses IFS=';, ' read -r -a ip_array <<< "$swarm_ip" debug_msg "IP Array: ${ip_array[*]}" # Display initial information if [[ "$log_level_type" == "cluster" ]]; then echo -e "Swarm IP: ${GREEN}${ip_array[0]}${RESET}" else echo -e "Swarm IPs: ${GREEN}${ip_array[*]}${RESET}" fi # echo -e "Swarm IP: ${GREEN}$swarm_ip${RESET}" echo -e "Credentials: ${GREEN}[hidden for security]${RESET}" echo -e "Cluster Name: ${GREEN}$clusterName${RESET}" debug_msg "Starting main_script function..." debug_msg "Log level type: $log_level_type" # Store the original log levels declare -A original_log_levels declare -A original_log_level_names if [[ $log_level_type == "cluster" ]]; then debug_msg "Setting cluster log level to $new_log_level ($new_log_level_name)" # Retrieve current log level if [[ "$jq_or_grep" == "grep" ]]; then current_log_level=$(curl --user "$credentials" -sS "http://${ip_array[0]}:91/api/storage/clusters/$clusterName/settings/log.level" | grep -oP '"value":\s*\K[0-9]+') else current_log_level=$(curl --user "$credentials" -sS "http://${ip_array[0]}:91/api/storage/clusters/$clusterName/settings/log.level" | "$jq_or_grep" -r '.value') fi current_log_level_name=${log_levels[$current_log_level]} debug_msg "Current cluster log level: ${BOLD_GREEN}$current_log_level${RESET}" debug_msg "Current log level: ${BOLD_GREEN}$current_log_level_name${RESET}" echo -e "" echo -e "New cluster log level: ${BOLD_GREEN}$new_log_level_name${RESET}" echo -e "Current cluster log level is ${GREEN}$current_log_level_name.${RESET}" # Skip update if new level matches the current level if [[ "$current_log_level" -eq "$new_log_level" ]]; then echo "" echo -e "Cluster log level is already set to ${BOLD_GREEN}$new_log_level_name${RESET}. No changes made." return fi # Update the cluster log level using PUT debug_msg "Updating cluster log level to $new_log_level_name" debug_msg "Cluster Name: $clusterName" response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ "http://${ip_array[0]}:91/api/storage/clusters/$clusterName/settings/log.level" \ -d "{\"value\": $new_log_level}") debug_msg "Response: $response" if [[ "$jq_or_grep" == "grep" ]]; then updated_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') else updated_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') fi debug_msg "Updated cluster log level: $updated_log_level" if [[ "$updated_log_level" -eq "$new_log_level" ]]; then echo -e "Log level changed successfully from ${GREEN}$current_log_level${RESET} → ${BOLD_GREEN}$new_log_level${RESET}." else echo -e "Failed to update log level. Response: ${RED}$response${RESET}" exit 1 fi # Countdown and revert log level if [[ -n "$duration" && "$duration" -gt 0 ]]; then echo -e "Keeping log level at ${YELLOW}$new_log_level${RESET} for ${YELLOW}$duration${RESET} second(s)..." echo -e "" for ((i=duration; i>0; i--)); do printf -v countdown "%02d:%02d:%02d" $((i/3600)) $(( (i%3600) / 60 )) $((i%60)) echo -ne "Countdown: ${YELLOW}$countdown${RESET} remaining...\r" sleep 1 done echo -e "\n\nTime's up! Reverting log level back to ${GREEN}$current_log_level${RESET}..." # Revert the log level back to the original value response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ "http://${ip_array[0]}:91/api/storage/clusters/$clusterName/settings/log.level" \ -d "{\"value\": $current_log_level}") debug_msg "Response: $response" if [[ "$jq_or_grep" == "grep" ]]; then reverted_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') else reverted_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') fi debug_msg "Reverted cluster log level: $reverted_log_level" final_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) size_diff=$(( final_size - initial_size )) size_diff_formatted=$(format_size "$size_diff") duration_formatted=$(format_duration "$duration") echo -e "Approximate ${BOLD_GREEN}$size_diff_formatted${RESET} new logs were generated at log level ${BOLD_GREEN}$new_log_level${RESET}. Current castor.log size is ${BOLD_GREEN}$(format_size "$final_size")${RESET} after $duration_formatted." if [[ "$reverted_log_level" -eq "$current_log_level" ]]; then echo -e "Log level reverted successfully back to ${BOLD_GREEN}$current_log_level${RESET}." else echo -e "Failed to revert log level. Response: ${RED}$response${RESET}" exit 1 fi else echo "Log level change is permanent until manually modified." fi elif [[ "$log_level_type" == "node" ]]; then # First loop: Change the node log level for ip in "${ip_array[@]}"; do # Retrieve current node log level debug_msg "Retrieving current node log level for IP: $ip" debug_msg "curl -s -u \"$credentials\" \"http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel\"" current_log_level=$(curl -s -u "$credentials" "http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel" | $jq_or_grep -r '.value') original_log_levels["$ip"]=$current_log_level if [[ "$current_log_level" == "0" ]]; then current_log_level_name="default" else current_log_level_name=${log_levels[$current_log_level]} fi original_log_level_names["$ip"]=$current_log_level_name if [[ "$new_log_level" == "0" ]]; then new_log_level_name="default" else new_log_level_name=${log_levels[$new_log_level]} fi debug_msg "Current log level for IP $ip: $current_log_level ($current_log_level_name)" echo "" echo -e "New node log level: ${BOLD_GREEN}$new_log_level_name${RESET}" echo -e "Current node log level for IP $ip is ${GREEN}$current_log_level_name.${RESET}" # Skip update if new level matches the current level if [[ "$current_log_level" -eq "$new_log_level" ]]; then echo "" echo -e "Node log level for IP $ip is already set to ${BOLD_GREEN}$new_log_level_name${RESET}. No changes made." continue fi # Update the node log level using PUT debug_msg "Updating node log level to $new_log_level_name for IP $ip..." debug_msg "curl --user \"$credentials\" -sS -X PUT -H \"Content-Type: application/json\" \"http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$new_log_level\"" response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ "http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$new_log_level") debug_msg "Response: $response" if [[ "$jq_or_grep" == "grep" ]]; then updated_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') else updated_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') fi debug_msg "Updated log level for IP $ip: $updated_log_level" if [[ "$updated_log_level" -eq "$new_log_level" ]]; then echo -e "Node log level for IP $ip changed successfully from ${GREEN}$current_log_level_name${RESET} → ${BOLD_GREEN}$new_log_level_name${RESET}." else echo -e "Failed to update node log level for IP $ip. Response: ${RED}$response${RESET}" exit 1 fi done # Second loop: Countdown if duration is provided if [[ -n "$duration" && "$duration" -gt 0 ]]; then echo -e "" echo -e "Keeping node(s) log level at ${YELLOW}$new_log_level_name${RESET} for ${YELLOW}$duration${RESET} second(s)..." echo -e "" for ((i=duration; i>0; i--)); do printf -v countdown "%02d:%02d:%02d" $((i/3600)) $(( (i%3600) / 60 )) $((i%60)) echo -ne "Countdown: ${YELLOW}$countdown${RESET} remaining...\r" sleep 1 done echo -e "\n\nTime's up! Reverting node log level back to original levels..." # Third loop: Revert the node log level for ip in "${ip_array[@]}"; do current_log_level=${original_log_levels["$ip"]} current_log_level_name=${original_log_level_names["$ip"]} debug_msg "Reverting node log level back to $current_log_level_name for IP $ip..." debug_msg "curl --user \"$credentials\" -sS -X PUT -H \"Content-Type: application/json\" \"http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$current_log_level\"" response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ "http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$current_log_level") debug_msg "Response: $response" if [[ "$jq_or_grep" == "grep" ]]; then reverted_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') else reverted_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') fi final_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) size_diff=$(( final_size - initial_size )) size_diff_formatted=$(format_size "$size_diff") duration_formatted=$(format_duration "$duration") if [[ "$reverted_log_level" -eq "$current_log_level" ]]; then echo -e "Node log level for IP $ip reverted successfully back to ${BOLD_GREEN}${current_log_level_name}${RESET}." else echo -e "Failed to revert node log level for IP $ip. Response: ${RED}$response${RESET}" exit 1 fi done # Combine the log output for multiple IP addresses into a single summary echo -e "" echo -e "Approximate ${BOLD_GREEN}$size_diff_formatted${RESET} new logs were generated at log level ${BOLD_GREEN}$new_log_level_name${RESET} for IP ${ip_array[*]}. Current castor.log size is ${BOLD_GREEN}$(format_size "$final_size")${RESET} after $duration_formatted." else echo "Log level change is permanent until manually modified." fi fi } # Run in detachable or directly if $detachable; then # Pass the main_script function to the screen session and store the output in a file if command -v screen &>/dev/null; then # screen -dmS indexer_script bash -c "$(declare -f main_script format_size format_duration check_jq debug); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$new_log_level_name\" \"$duration\" \"$log_level_type\" \"$clusterName\" \"$jq_or_grep\" | tee \"$output_log\"" screen -dmS indexer_script bash -c "$(declare -f main_script debug_msg format_size format_duration check_jq); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$new_log_level_name\" \"$duration\" \"$log_level_type\" \"$clusterName\" \"$jq_or_grep\" \"$debug\" | tee \"$output_log\"" echoscreen -e "Log level reverted successfully back to ${BOLD_GREEN}$current_log_level${RESET}." r indexer_script elif command -v tmux &>/dev/null; then else # tmux new-session -d -s indexer_script "$(declare -f main_script format_size format_duration echo -e "Failed to revert log level. Response: ${RED}$response${RESET}" check_jq debug); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$new_log_level_name\" \"$duration\" \"$log_level_type\" \"$clusterName\" \"$jq_or_grep\" | tee \"$output_log\"" exit 1tmux new-session -d -s indexer_script "$(declare -f main_script fi else echo "Log level change is permanent until manually modified.debug_msg format_size format_duration check_jq); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$new_log_level_name\" \"$duration\" \"$log_level_type\" \"$clusterName\" \"$jq_or_grep\" \"$debug\" | tee \"$output_log\"" fi } # Runtmux in persistent or directly if $persistent; then attach-session -t indexer_script else # Pass the main_script function to the screen session and store the output in a file if command -v screen &>/dev/null; thenecho "Error: Neither screen nor tmux available. Run without --detachable." exit 1 screen -dmS indexer_scriptfi bash -c "$(declare -f main_script format_size format_duration check_jq debug); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$duration\" \"$clusterName\" \"$jq_or_grep\" | tee \"$output_log\"" # Wait for the screen session to complete and then display the output log sleep 1 while screen -r list | grep -q "indexer_script"; do sleep elif1 command -v tmux &>/dev/null; then done echo "" tmux new-session -d -scat indexer"$output_script log"$(declare -felse main_script format_size format_duration check_jq debug); # main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$duration\" \"$clusterName\" \"$jq_or_grep\" | tee \"$output_log\"" tmux attach-session -t indexer_script else echo "Error: Neither screen nor tmux available. Run without --persistent.debug_msg "***********************************" debug_msg "Parameters passed to exitmain_script:" 1 debug_msg fi"Swarm IP: $swarm_ip" # Wait for the screen session to complete and then display the output logdebug_msg "Credentials: $credentials" debug_msg "New Log Level: $new_log_level" sleep 1 while screen -list | grep -q "indexer_script"; do debug_msg "Duration: $duration" debug_msg "Cluster Name: sleep$clusterName" 1 done debug_msg "jq_or_grep: $jq_or_grep" echo "debug_msg "***********************************" catdebug_msg "$output_logRunning main_script function..." else main_script "$swarm_ip" "$credentials" "$new_log_level" "$new_log_level_name" "$duration" "$log_level_type" "$clusterName" "$jq_or_grep" | tee "$output_log" fi |
...