...
Parameter | Description |
---|---|
| IP address of the Swarm API endpoint (or set |
| Admin credentials in the format |
| New log level to set (values: |
| Duration in seconds to keep the new log level (optional). |
| Runs the script in a detachable session using |
| Enables verbose mode to display debug information. |
Instruction for Use
Example 1: Set cluster log level to 20
and keep it for 10
...
minutes
Code Block |
---|
./castor-change-log-level.sh -d 192.168.8.84 -p admin:datacore -i 20 -t 10600 |
Example 2: Set node(s) log level to debug (10) and keep it for 10 secondsminutes
Code Block |
---|
./castor-change-log-level.sh -d 192.168.8.84,192.168.8.86 -p admin:datacore -i debug -t 10600 |
Example 3: Run in background mode
...
Code Block |
---|
./castor-change-log-level.sh -d 192.168.8.84 -p admin:datacore -i 20 -t 30 --detach -v |
Running the Script at a Specific Time
...
Log Level Change: Sets the log level to the specified value. If the current log level matches the requested level, the script skips the update.
Countdown: During the specified duration, the script displays a countdown every second.
Revert Log Level: After the countdown, the log level reverts to the initial value.
Log Size Report: Provides approximately log size generated during the temporary log level change.
Debug Mode: When
-v
is specified, debug messages display the script's internal operations.
Output Messages
Message | Description |
---|---|
| Displays the specified Swarm IP address. |
| Credentials are masked for security. |
| Displays the cluster name retrieved from the Swarm API. |
| Shows the new log level requested. |
| Displays the current log level. |
| Indicates the beginning of the log level update process. |
| Confirms that the log level was successfully updated. |
| Shows the temporary period for which the new log level is retained, with a countdown. |
| Indicates that the temporary period has ended and the script is reverting the log level. |
| Provides information on the amount of logging activity generated during the temporary log level. |
...
Code Block | ||
---|---|---|
| ||
#!/bin/bash # ----------------------------------------------------------------------------------------------------------------------------- # Script: castor-change-log-level.sh # ----------------------------------------------------------------------------------------------------------------------------- # Description: # This script changes the log level for the Castor cluster or node(s) using the Swarm API. # The script supports changing the log level for the entire cluster or individual node(s). # The script can run in a detachable session using 'screen' or 'tmux'. # ----------------------------------------------------------------------------------------------------------------------------- # Written by Milton Suen (milton.suen@datacore.com) Oct 31, 2024 # Revision History: # v1.0.0 - Update to support running the script in a detachable session using screen or tmux. # v1.1.0 - 2025-02-20 Add support node(s) level log level change. # v1.2.0 - 2025-02-26 SUPSCR-208: Auto detect CSN or SCS to adjust castor.log file path # - Enforced proper credential formatting: credentials must be in the username:password format. # v1.2.1 - 2025-02-26 Address the issue of the- scriptFixed nothelp displaymessage correctshows whenscript thename castor.logwithout filehard iscode rotatedit. # v1.2.21 - 2025-02-26 SUPSCR-209: EnforcedAuto properdetect credentialCSN formatting:or credentialsSCS mustto beadjust incastor.log the username:password formatfile path. # v1.2.2 - 2025-02-27 Address the issue of the script not display correct when the castor.log file is rotated. # v1.2.3 - 2025-02-27 Address the issue of log level not display correct within detach session. # v1.2.4 - 2025-02--------------------------------------------------------------------------------------------------------------------- # Current Version: 1.2.2 # -----------------------27 Bug fix: The default node-level log level is 0 (unset), which differs from the cluster-level default of 30. # v1.2.5 - 2025-02-28 SUPSCR-208: # - Credentials validation and password prompt enhancements. # - screen or tmux required with detachable mode, script will stopped with '-D' option if neither is installed. # - Fixed an issue where users were prompted to enter password multiple times issue. # - Passwords are now hidden in debug output messages. # v1.2.6 - 2025-02-28 SUPSCR-208: # - Disabled credential display on the screen. # - Bug fix: Resolved the "debug: command not found" error when removing the -d [IP address] option. # v1.3.0 - 2025-02-28 minor bug fix and enhancement. # v1.3.1 - 2025-03-01 SUPSCR-208: # - Fixed an issue where credentials enclosed in single quotes (') were not processed correctly. # ----------------------------------------------------------------------------------------------------------------------------- # KBCurrent Version: https://perifery.atlassian.net/wiki/spaces/public/pages/3872161835/Setting+and+Managing+Swarm+Log+Levels+with+script # 1.3.1 # --------------------------------------------------------------------------------------------------------------------------------------- # 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: ./castor-change-log-level10.sh -d swarm_ip -p admin:password [-i new_log_level | -L new_node_log_level] [-t duration_in_seconds] [-D]" echo " -d, --swarm_ip IP address of the Swarm API endpoint. Supports single or multiple IPs separated by \",\", \";\" or \" \"." echo " If multiple IPs are provided, the script will update the log level for all nodes." echo " # KB: https://perifery.atlassian.net/wiki/spaces/public/pages/3872161835/Setting+and+Managing+Swarm+Log+Levels+with+script # ----------------------------------------------------------------------------------------------------------------------------- # 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 SCRIPT_NAME=$(basename "$0") # Function to display usage information usage() { echo "" echo "Usage: ./$SCRIPT_NAME -d swarm_ip -p admin:password [-i new_log_level | -L new_node_log_level] [-t duration_in_seconds] [-D]" echo " -d, --swarm_ip IP address of the Swarm API endpoint. Supports single or multiple IPs separated by \",\", \";\" or \" \"." echo " If multiple IPs are provided, the script will update the log level for all nodes." echo " (Alternatively, set the SCSP_HOST environment variable to the Swarm IP.)" echo " -p, --credentials Credentials in the format admin:password" echo " -i, --log.level New cluster log level to set (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 " **Either -i or -L 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" echo "" exit 1 } # Default options detachable=false debug=false output_log="castor-change-log-level_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 SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) JQLOCATION=$SCRIPTDIR/jq MAX_RETRIES=3 # Maximum number of password retries attempts username="admin" # Default username password="" # Default password # 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 get the current timestamp timestamp() { date +"%Y-%m-%d_%H:%M:%S.%4N" } # Function to display debug messages if debug mode is enabled debug_msg() { if $debug; then local caller_line=${BASH_LINENO[0]:-unknown} # Fallback to "unknown" if empty echo -e "$(timestamp) [DEBUG] (Line $caller_line) $*" 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 -e "" echo -e "---------------------------------------------------------------------------------------" echo -e " ${YELLOW}Warning${RESET}: Neither '${BOLD_GREEN}screen${RESET}' nor '${BOLD_GREEN}tmux${RESET}' is installed. Cannot run in detachable mode." echo -e " Please install either '${BOLD_GREEN}screen${RESET}' or '${BOLD_GREEN}tmux${RESET}' to run the script in a detachable session." echo -e "---------------------------------------------------------------------------------------" echo -e "" detachable=false # Disable detachable session debug_msg "detachable=${YELLOW}false${RESET}" debug_msg "Stopping the script..." exit 1 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 } if [[ -f "$JQLOCATION" ]]; then jq_or_grep=$JQLOCATION else jq_or_grep=$(check_jq) fi debug_msg "jq_or_grep: $jq_or_grep" #jq_or_grep=$(check_jq) # Function to determine the log file path determine_log_file() { if [[ -f "/var/log/datacore/castor.log" ]]; then echo "/var/log/datacore/castor.log" elif [[ -f "/var/log/caringo/castor.log" ]]; then echo "/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) # Function to check if credentials are valid check_credentials() { local CREDENTIALS="$1" local SWARM_IP="$2" debug_msg "Credentials: [hidden for security]" debug_msg "Swarm IP: $SWARM_IP" # API endpoint for validating user credentials local VALIDATE_URL="http://${SWARM_IP}:91/api/validateUser" debug_msg "Validate URL: $VALIDATE_URL" # Make the API request debug_msg "Validating user credentials..." debug_msg "curl -s -u \"********\" -X GET \"$VALIDATE_URL\" -H 'Content-Type: application/json'" RESPONSE=$(curl -s -u "$CREDENTIALS" -X GET "$VALIDATE_URL" -H 'Content-Type: application/json') debug_msg "Validate User Response: $RESPONSE" # Check if the response contains "isValid": true if echo "$RESPONSE" | "$jq_or_grep" -e '.isValid == true' > /dev/null 2>&1; then debug_msg "Authentication successful for user '${CREDENTIALS%%:*}'" return 0 # Success elif echo "$RESPONSE" | "$jq_or_grep" -e '.isValid == false' > /dev/null 2>&1; then debug_msg "Authentication failed for user '${CREDENTIALS%%:*}'" return 1 # Failure else debug_msg "Error: Unable to validate credentials. Please check your inputs." return 1 # Failure fi } # Function to print credentials - hide password print_credentials() { local CREDENTIALS="$1" local USERNAME="${CREDENTIALS%%:*}" echo -e "${GREEN}$USERNAME${RESET}":"${GREEN}********${RESET}" } # 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" 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 new_log_level_name=${log_levels[$new_log_level]} log_level_type="cluster" default_log_level=30 debug_msg "Set new_log_level to $new_log_level ($new_log_level_name)" shift 2 ;; -L|--node.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]} || $2 -eq 0 ]]; then new_log_level=$2 new_log_level_name="default" else echo "Invalid log level: $2" exit 1 fi new_log_level_name=${log_levels[$new_log_level]} log_level_type="node" default_log_level=0 debug_msg "Set new_log_level to $new_log_level ($new_log_level_name)" shift 2 ;; -t|--time) if [[ -n "$2" && "$2" != -* && "$2" -gt 0 ]]; then duration="$2" debug_msg "Set duration to $duration" shift 2 else echo "Error: Duration must be a number greater than 0." exit 1 fi ;; -D|--detach) detachable=true; debug_msg "Set detachable to true"; shift ;; --debug) debug=true; debug_msg "Set debug to true with ${YELLOW}--debug${RESET}"; shift ;; *) usage ;; esac done debug_msg "Set log_level_type to ${YELLOW}$log_level_type${RESET}" # Set default values if not provided debug_msg "Checking for default log level values..." # Change the default log level based on Log Level Type debug_msg "Changing default log level based on Log Level Type: ${YELLOW}$log_level_type${RESET}" if [[ -n "$new_log_level" ]]; then if [[ "$log_level_type" == "node" ]]; then # new_log_level=0 debug_msg "Checing node default log level" default_log_level=0 if [[ $new_log_level == 30 ]]; then new_log_level=$default_log_level new_log_level_name="default" (Alternatively, set the SCSP_HOST environmentfi variable to the Swarm IP.)" debug_msg echo"node " -p, --credentials- new_log_level: to $new_log_level" Credentials in the format admin:password" debug_msg "node - new_log_level_name: to $new_log_level_name" echo " elif -i, --log.level [[ "$log_level_type" == "cluster" ]]; then New cluster default_log _level to=30 set (5, 10, 15, 20,fi 30, 40, 50, chatter, debug, announce, info, error, critical, default)_msg "New log level: ${GREEN}$new_log_level${RESET}" echodebug_msg "New -L, --node.log.levellog level name: ${GREEN}$new_log_level_name${RESET}" New node log debug_msg "Set default_log_level to set (0, 5, 10, 15, 20, 30, 40, 50, chatter, debug, announce, info, error, critical, default)" echo " **Either -i or -L 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: $default_log_level" fi # Check if 'screen' or 'tmux' is installed if [[ "$detachable" == true ]]; then check_screen_or_tmux fi # 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_msg "Using Swarm IP from SCSP_HOST: $swarm_ip" else echo "Error: swarm_ip not provided and SCSP_HOST is not set." usage (Optional)fi Detachfi the script# fromCheck theif currentrequired terminalarguments andare runprovided inif a[[ detachable session using screen or tmux" -z "$credentials" || -z "$new_log_level" ]]; then exit 1usage }fi # 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 \"%.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) # Function to determine the log file path determine_log_file() { if [[ -f "/var/log/datacore/castor.log" ]]; then echo "/var/log/datacore/castor.log" elif [[ -f "/var/log/caringo/castor.log" ]]; thenSplit the swarm_ip into an array of IP addresses if it contains delimiters IFS=';, ' read -r -a ip_array <<< "$swarm_ip" # Validate credentials before proceeding debug_msg "Validating credentials..." #if [[ "$credentials" =~ ^[^:]+$ ]]; then if [[ -n "$credentials" ]]; then CREDENTIALS="$credentials" ATTEMPT=$MAX_RETRIES USERNAME="" PASSWORD="" debug_msg "CREDENTIALS: $(print_credentials "$CREDENTIALS")" debug_msg "ATTEMPT: $ATTEMPT" # Check if credentials contain a colon (username:password format) debug_msg "Checking for colon in credentials..." if [[ "$CREDENTIALS" == *":"* ]]; then debug_msg "Credentials contain colon" USERNAME="${CREDENTIALS%%:*}" PASSWORD="${CREDENTIALS#*:}" # # Check if credentials contains special characters # debug_msg "Checking for special characters in credentials..." # if [[ "$PASSWORD" == *['!@#\$%^\&*()_+''-']* ]]; then # debug_msg "Credentials contain special characters" # debug_msg "Username: $USERNAME" # debug_msg "Password: $PASSWORD" # echo -e "" # echo -e "${YELLOW}Warning${RESET}: Password contains special characters. Please enclose the credentials in single quotes. ('username:password')" # echo -e "" # exit 1 # fi # Validate credentials check_credentials "$CREDENTIALS" "${ip_array[0]}" if [[ $? -ne 0 ]]; then debug_msg "Invalid credentials. Please check your username and password." echo -e "" echo -e "${RED}Error${RESET}: Invalid credentials. Please check your username and password." echo -e "" exit 1 fi debug_msg "Validate credentials" credentials=$CREDENTIALS else debug_msg "Credentials do not contain password" debug_msg "Username: $(print_credentials "$CREDENTIALS")" USERNAME="$CREDENTIALS" # Prompt for password while [[ $ATTEMPTS -lt $MAX_RETRIES ]]; do echo "" read -sp "Enter password for user $USERNAME: " PASSWORD echo "" echo "/var/log/caringo/castor.log" else CREDENTIALS="$USERNAME:$PASSWORD" echo "Error: Log file not found in /var/log/datacore/castor.log or /var/log/caringo/castor.logdebug_msg "CREDENTIALS: $(print_credentials "$CREDENTIALS"))" exit 1 check_credentials fi } log_file=$(determine_log_file) # Parse input arguments while [[ "$#" -gt"$CREDENTIALS" "${ip_array[0]}" if [[ $? -eq 0 ]]; dothen case $1 in -d|--swarm_ip) swarm_ip="$2"; debug_msg "Set swarm_ip to $swarm_ip"; shift 2 ;; CREDENTIALS: $(print_credentials "$CREDENTIALS"))" -p|--credentials) debug_msg "Valid credentials="$2" if ! [[ "$credentials" =~ ^[^:]+:[^:]+$ ]]; thencredentials=$CREDENTIALS break echo -e "" else echo -e "Error: Credentials must be in theecho format ${BOLD_GREEN}username:password${RESET}-e "" exitecho 1 -e "${RED}Error${RESET}: Invalid credentials. Please check your username and password." fi fi if [[ "$credentials" =~ [^a-zA-Z0-9:] ]]; then ((ATTEMPTS++)) done fi echoelse -e "" if ! check_credentials "$credentials" "${ip_array[0]}"; then echo -e "Warning: Password" contains special characters. Please enclose the credentials with singleecho quotes-e ("${BOLD_YELLOW}'${BOLD_GREEN}username:password${RESET}${BOLD_YELLOW}'$Warning${RESET}: ${RED}Invalid credentials${RESET})." echo -e "" exit 1 exit 1 fi fi # Retrieve ficluster name and handle JSON parsing using the first IP address debug_msg "SetRetrieving credentials";the shiftcluster 2name ;;from Swarm API using -i|--log.level) IP: ${ip_array[0]}" if [[ -n "$new$jq_log_levelor_grep" == "grep" ]]; then clusterName=$(curl --user "$credentials" -sS "http://${ip_array[0]}:91/api/storage/clusters" | grep 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 -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=$2"$3" local new_log_level_name="$4" local duration="$5" else local log_level_type="$6" #local log_file="/var/log/datacore/castor.log" if echo[[ -z "Invalid log level: $2"$log_file" ]]; then log_file=$(determine_log_file) fi exit 1 local initial_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) local ficurrent_log_level local clusterName="$7" local newjq_logor_level_name=${log_levels[$new_log_level]}grep="$8" local detachable="$9" if log_level_type="cluster" [[ "$detachable" ]]; then default_log_level=30local debug="${10}" eval "$(echo "${11}" | debug_msg "Set new_log_level to $new_log_level ($new_log_level_namesed 's/declare -A/declare -A/')" eval "$(echo "${12}" | shift 2 sed 's/declare -A/declare -A/')" fi ;;debug_msg "**********************************************************" debug_msg "local variables" -L|--node.log.level) debug_msg "Log Level Type: ${GREEN}$log_level_type${RESET}" debug_msg if"Default [[ -n "$newLog Level: ${GREEN}$default_log_levellevel${RESET}" ]]; then debug_msg "Swarm IP: $swarm_ip" echo "Error: Options -i (cluster log leve) and -L (node log level) cannot be used together.debug_msg "Credentials: $(print_credentials "$credentials")" debug_msg "New Log Level: $new_log_level" debug_msg "New log Level Name: $new_log_level_name" debug_msg "Duration: usage$duration" debug_msg "Log File: $log_file" fidebug_msg "Initial Log File Size: $initial_size" debug_msg "Current if [[ ${Log Level: $current_log_level_names[$2]} ]]; then" debug_msg "Cluster Name: $clusterName" debug_msg "jq_or_grep: $jq_or_grep" new_log_level=${log_level_names[$2]} debug_msg "Detach: $detachable" debug_msg "Debug: $debug" elif [[ ${log_levels[$2]} || $2 -eq 0 ]]; then new_log_level=$2 new_log_level_name="defaultdebug_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 else echo "Invalid log level: $2" if [[ "$log_level_type" == "cluster" ]]; then exit 1 echo -e "Swarm IP: ${GREEN}${ip_array[0]}${RESET}" else fi echo -e "Swarm log_level_type="node"IPs: ${GREEN}${ip_array[*]}${RESET}" fi # echo default_log_level=0 -e "Swarm IP: ${GREEN}$swarm_ip${RESET}" debug_msg "Credentials: ${GREEN}[hidden for security]${RESET}" debug_msg "Set new_log_level to $new_log_level ($new_log_level_name)" echo -e "Cluster Name: ${GREEN}$clusterName${RESET}" debug_msg "Starting main_script function..." shift 2 debug_msg "Log level type: $log_level_type" # ;;Store the original log levels declare -t|--time) A original_log_levels declare -A original_log_level_names if [[ -n "$2" && "$2" != -* && "$2" -gt 0 ]]; then $log_level_type == "cluster" ]]; then debug_msg "Setting cluster log level to $new_log_level ($new_log_level_name)" duration="$2" # Retrieve current log level if debug_msg "Set duration to $duration" [[ "$jq_or_grep" == "grep" ]]; then current_log_level=$(curl shift 2 --user "$credentials" -sS "http://${ip_array[0]}:91/api/storage/clusters/$clusterName/settings/log.level" | grep -oP '"value":\s*\K[0-9]+') else echo "Error: Duration must be a number greater than 0." 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 exit 1 current_log_level_name=${log_levels[$current_log_level]} fidebug_msg "Current cluster log level: ${BOLD_GREEN}$current_log_level${RESET}" ;; debug_msg "Current log level -D|--detach) detachable=true; debug_msg "Set detachable to true"; shift ;;name: ${BOLD_GREEN}$current_log_level_name${RESET}" echo --debug) debug=true; debug_msg "Set debug to true"; shift ;; *) usage ;;e "" echo -e "New cluster log level: ${BOLD_GREEN}$new_log_level_name${RESET}" esac doneecho debug_msg "Set-e "Current cluster log_ level_type tois ${YELLOWGREEN}$log$current_log_level_type$name.${RESET}" # SetSkip default valuesupdate if notnew providedlevel ifmatches [[the -z "$new_log_level" ]]; thencurrent level if [[ "$log$current_log_level_type" ==-eq "cluster$new_log_level" ]]; then new_log_level=$default_log_level echo else"" new_log_level=0 echo fi-e "Cluster new_log_level_name="default" new_log_level_name=${log_levels[log level is already set to ${BOLD_GREEN}$new_log_level]_name${RESET}. No 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_HOSTchanges made." return fi # Update the cluster log level using PUT debug_msg "Updating cluster log level to $new_log_level_name" debug_msg "Using Swarm IP from SCSP_HOST: $swarm_ipCluster Name: $clusterName" else debug_msg "Credentials: $(print_credentials "$credentials")" 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]}"debug_msg "curl --user \"$(print_credentials "$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}\"" 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 clusterNameupdated_log_level=$(curl --userecho "$credentials$response" -sS "http://${ip_array[0]}:91/api/storage/clusters" | grep -oP '"namevalue":\s*"\K[^"0-9]+') else clusterName updated_log_level=$(curl --user "$credentials" -sS "http://${ip_array[0]}:91/api/storage/clusters" | "$jq_or_grep" -r '._embedded.clusters[0].name') fiecho "$response" | "$jq_or_grep" -r '.value') fi debug_msg "Updated cluster log level: $updated_log_level" if [[ -z "$clusterName"$updated_log_level" -eq "$new_log_level" ]]; then echo "Failed to retrieve the cluster name. Please checkecho your-e inputs."Log level changed successfully exit 1 fi debug_msg "Cluster Name: $clusterName" # Main logic function to run the script tasks main_script() {from ${GREEN}$current_log_level${RESET} -> ${BOLD_GREEN}$new_log_level${RESET}." local swarm_ip="$1" else local credentials="$2" local new_log_level="$3" echo -e "Failed localto update new_log_level_name="$4 level. Response: ${RED}$response${RESET}" local duration="$5" local log_level_type="$6" exit 1 # local log_file="/var/log/datacore/castor.log" fi local initial_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) # Countdown and localrevert current_log_ level local clusterName="$7" if [[ local jq_or_grep="$8" local debug="$9"-n "$duration" && "$duration" -gt 0 ]]; then debug_msg "**********************************************************" debug_msg "local variables" debug_msg "Swarm IP: $swarm_ip" debug_msg "Credentials: $credentials"echo -e "Keeping log level at ${YELLOW}$new_log_level_name${RESET} for ${YELLOW}$duration${RESET} seconds (${YELLOW}$(format_duration $duration)${RESET}) ..." debug_msg "New Log Level: $new_log_level ($new_log_level_name)echo -e "" debug_msg "Duration: $duration" debug_msg "Log Level Type: $log_level_type" debug_msg "Log File: $log_file"for ((i=duration; i>0; i--)); do debug_msg "Initial Log File Size: $initial_size" printf -v debug_msgcountdown "Current Log Level: $current_log_level" debug_msg "Cluster Name: $clusterName"%02d:%02d:%02d" $((i/3600)) $(( (i%3600) / 60 )) $((i%60)) debug_msg "jq_or_grep: $jq_or_grep" debug_msg "Debug: $debug" echo -ne debug_msg "**********************************************************"Countdown: ${YELLOW}$countdown${RESET} remaining...\r" # Split the swarm_ip into an array of IP addresses IFS=';, ' read -r -a ip_array <<< "$swarm_ip" debug_msg "IP Array: ${ip_array[*]} sleep 1 done echo -e "\n\nTime's up! Reverting log level back to ${GREEN}$current_log_level${RESET}..." # Display initial information if [[ "$log_level_type" == "cluster" ]]; thenRevert the log level back to the original value response=$(curl --user "$credentials" echo-sS -X PUT -eH "Swarm IP: ${GREEN}${ip_array[0]}${RESET}" Content-Type: application/json" \ else echo -e "Swarm IPs: http://${GREEN}${ip_array[*]}${RESET}" fi0]}:91/api/storage/clusters/$clusterName/settings/log.level" \ # echo -e "Swarm IP: ${GREEN}$swarm_ip${RESET}" echo -ed "Credentials: ${GREEN}[hidden for security]${RESET}"{\"value\": $current_log_level}") echo -e "Cluster Name: ${GREEN}$clusterName${RESET}" debug_msg "Response: $response"Starting main_script function..." debug_msg "Log level type: $log_level_type" if [[ # Store the original log levels"$jq_or_grep" == "grep" ]]; then declare -A original_log_levels declare -A originalreverted_log_level_names if [[ $log_level_type == "cluster" ]]; then=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') debug_msgelse "Setting cluster log level to $new_log_level ($new_log_level_name)" # Retrieve current log level reverted_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') if [[ "$jq_or_grep" == "grep" ]]; thenfi 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]+'debug_msg "Reverted cluster log level: $reverted_log_level" final_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) else debug_msg "Initial log file size: $initial_size" currentdebug_msg "Final log_level=$(curl --user "$credentials" -sS "http://${ip_array[0]}:91/api/storage/clusters/$clusterName/settings/log.level" | "$jq_or_grep" -r '.value') fi file size: $final_size" size_diff=$(( final_size - initial_size )) currentsize_logdiff_level_nameformatted=${log_levels[$current_log_level]}(format_size "$size_diff") debug_msg "Current cluster log level: ${BOLD_GREEN}$current_log_level${RESET}" debug_msg "Current log level: ${BOLD_GREEN}$current_log_level_name${RESET}"duration_formatted=$(format_duration "$duration") if (( size_diff < 0 )); then echo -e "castor.log file was rotated." else echo -e "" echo -e "New cluster log level: Approximate ${BOLD_GREEN}$new$size_logdiff_level_name$formatted${RESET}" new logs were generated at log echo -e "Current cluster log levellevel ${BOLD_GREEN}$new_log_level${RESET}. Current castor.log size is ${BOLD_GREEN}$current_log_level_name.${RESET}$(format_size "$final_size")${RESET} after ${YELLOW}$duration${RESET} seconds (${YELLOW}$duration_formatted${RESET})." # Skip update if new level matches the current level echo -e "" fi if [[ "$current$reverted_log_level" -eq "$new$current_log_level" ]]; then echo "" echo -e "Cluster logLog level isreverted alreadysuccessfully setback to ${BOLD_GREEN}$new$current_log_level_name$level${RESET}. No changes made." returnelse fi echo -e #"Failed Updateto the clusterrevert 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" \. Response: ${RED}$response${RESET}" exit 1 "http://${ip_array[0]}:91/api/storage/clusters/$clusterName/settings/log.level" \ fi -d "{\"value\": $new_log_level}") else debug_msg "Response: $response" echo "Log level change ifis [[ "$jq_or_grep" == "grep" ]]; thenpermanent until manually modified." fi elif updated_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')[[ "$log_level_type" == "node" ]]; then # First loop: Change elsethe node log level local updatedsame_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') false for ip in "${ip_array[@]}"; do fi # debug_msg "Updated clusterRetrieve current node log level: $updated_log_level" if [[ "$updated_log_level" -eq "$new_log_level" ]]; then debug_msg "Retrieving current node log level for IP: $ip" echo -edebug_msg "Logcurl level-s changed successfully from ${GREEN}$current_log_level${RESET} → ${BOLD_GREEN}$new_log_level${RESET}." else -u \"$(print_credentials "$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') echo -edebug_msg "FailedCurrent tolog updatelevel logfor level.IP Response$ip: ${RED}$response${RESET}$current_log_level" exit 1original_log_levels["$ip"]=$current_log_level fi debug_msg "Original log level for IP # Countdown and revert log level$ip: ${original_log_levels["$ip"]}" if [[ -n "$duration" && "$duration" -gt 0 "$current_log_level" == "0" ]]; then echo -e "Keeping log level at ${YELLOW}$new_log_level${RESET} for ${YELLOW}$duration${RESET} second(s)..." current_log_level_name="default" else echo -e "" for ((i=duration; i>0; i--)); do current_log_level_name=${log_levels[$current_log_level]} fi printf -v countdown "%02d:%02d:%02d" $((i/3600)) $(( (i%3600) / 60 )) $((i%60)) original_log_level_names["$ip"]=$current_log_level_name debug_msg "Original log level name: ${original_log_level_names["$ip"]}" echoif -ne[[ "Countdown: ${YELLOW}$countdown${RESET} remaining...\r" $new_log_level" == "0" ]]; then sleep 1 new_log_level_name="default" done else echo -e "\n\nTime's up! Reverting new_log level back to ${GREEN}$current_log_level${RESET}..."_level_name=${log_levels[$new_log_level]} fi # Revert the log level back to the original value debug_msg "Current log level for IP $ip: $current_log_level ($current_log_level_name)" response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ echo "" echo -e "New node log "httplevel:// ${ip_array[0]}:91/api/storage/clusters/$clusterName/settings/log.level" \BOLD_GREEN}$new_log_level_name${RESET}" echo -e "Current node -d "{\"value\": log level for IP $ip is ${GREEN}$current_log_level_name.${RESET}") # Skip update if new level debug_msg "Response: $response" matches the current level if [[ "$jq$current_orlog_greplevel" ==-eq "grep$new_log_level" ]]; then revertedsame_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')true echo "" else echo -e "Node log level for IP $ip is already set revertedto ${BOLD_GREEN}$new_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') _name${RESET}. No changes made." continue fi else debug_msg "Reverted cluster log level: $revertedsame_log_level"=false fi final_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) if [[ "$same_log_level" == false size_diff=$(( final_size - initial_size ))]]; then size_diff_formatted=$(format_size "$size_diff") # Update the node log level using PUT duration_formatted=$(format_duration "$duration") if (( size_diff < 0 )); then echo -e "castor.log file was rotated." debug_msg "Updating node log level to $new_log_level_name for IP $ip..." else debug_msg 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." fi"curl --user \"$(print_credentials "$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 if [[ "$reverted_log_level--user "$credentials" -eq "$current_log_level" ]]; then sS -X PUT -H "Content-Type: application/json" \ echo -e "Log level reverted successfully back to ${BOLD_GREEN}$current_log_level${RESET}." else "http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$new_log_level") echo -e "Failed to revert log level. Response: ${RED}$response${RESET}debug_msg "Response: $response" exit 1if [[ "$jq_or_grep" == "grep" ]]; then fi else updated_log_level=$(echo "Log$response" level| changegrep is permanent until manually modified."-oP '"value":\s*\K[0-9]+') fi elif [[ "$log_level_type" == "node" ]]; then else # First loop: Change the node log level for ip in "${ip_array[@]}"; doupdated_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') # Retrievefi current node log level debug_msg "RetrievingUpdated current node log level for IP $ip: $ip$updated_log_level" debug_msg "curl -s -u \"$credentials\" \"http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel\"" if [[ "$updated_log_level" -eq "$new_log_level" ]]; then echo -e "Node log level for currentIP $ip changed successfully from ${GREEN}$current_log_level=$(curl_name${RESET} -s -u "$credentials" "http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel" | $jq_or_grep -r '.value') > ${BOLD_GREEN}$new_log_level_name${RESET}." else original_log_levels["$ip"]=$current_log_level echo -e "Failed to ifupdate [[node "$current_log_level" == "0" ]]; then level for IP $ip. Response: ${RED}$response${RESET}" current_log_level_name="default" exit 1 else fi current_log_level_name=${log_levels[$current_log_level]} fi done fi # Second loop: original_log_level_names["$ip"]=$current_log_level_name Countdown if duration is provided if [[ "$new$same_log_level" == "0"false ]]; then\ if [[ new_log_level_name="default" else -n "$duration" && "$duration" -gt 0 ]]; then new_log_level_name=${log_levels[$new_log_level]} echo -e "" fi echo debug_msg-e "CurrentKeeping node(s) log level for IP $ip: $currentat ${YELLOW}$new_log_level ($current_log_level_name)" _name${RESET} for ${YELLOW}$duration${RESET} seconds (${YELLOW}$(format_duration $duration)${RESET}) ..." 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}"for ((i=duration; i>0; i--)); do printf -v # Skip update if new level matches the current levelcountdown "%02d:%02d:%02d" $((i/3600)) $(( (i%3600) / 60 )) $((i%60)) if [[ "$current_log_level" -eq "$new_log_level" ]]; thenecho -ne "Countdown: ${YELLOW}$countdown${RESET} remaining...\r" echo "" sleep 1 echo -e "Node log level for IP $ip isdone already set to ${BOLD_GREEN}$new_log_level_name${RESET}. No changes made." echo -e "\n\nTime's up! Reverting node log continuelevel back to original levels..." fi # Third loop: #Revert Update the node log level using PUT debug_msg "Updating node log levelfor 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\""ip in "${ip_array[@]}"; do response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \current_log_level=${original_log_levels["$ip"]} "http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$newcurrent_log_level_name=${original_log_level")_names["$ip"]} debug_msg "Response: $response" debug_msg "Reverting node log level back to if [[ "$jq_or_grep" == "grep" ]]; then$current_log_level_name for IP $ip..." updated_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')debug_msg "curl --user \"$(print_credentials "$credentials")\" -sS -X PUT -H \"Content-Type: application/json\" \"http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$current_log_level\"" else updated_log_levelresponse=$(echo "$response" | "$jq_or_grepcurl --user "$credentials" -r '.value') sS -X PUT -H "Content-Type: application/json" \ fi debug_msg "Updated log level for IP $ip: $updated_log_level" if [[ "$updated_log_level" -eq "$new "http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$current_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}. debug_msg "Response: $response" else if [[ "$jq_or_grep" echo -e "Failed to update node log level for IP $ip. Response: ${RED}$response${RESET}"== "grep" ]]; then exit 1 reverted_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+') fi done else # Second loop: Countdown if duration is provided if [[ -n "$duration" && "$duration" -gt 0 ]]; then reverted_log_level=$(echo "$response" | "$jq_or_grep" -r '.value') echo -e ""fi echo -e "Keeping node(s) log level at ${YELLOW}$new_log_level_name${RESET} for ${YELLOW}$duration${RESET} second(s)..." final_size=$(stat -c%s "$log_file" 2>/dev/null || echo 0) echo -e "" for size_diff=$((i=duration; i>0; i--)); do final_size - initial_size )) printf -v countdowndebug_msg "%02d:%02d:%02d" $((i/3600)) $(( (i%3600) / 60 )) $((i%60))Initial log file size: $initial_size" debug_msg "Final echolog -nefile "Countdown: ${YELLOW}$countdown${RESET} remaining...\rsize: $final_size" sleep 1 size_diff_formatted=$(format_size "$size_diff") done echo -e "\n\nTime's up! Reverting node log level back to original levels..."duration_formatted=$(format_duration "$duration") if [[ # Third loop: Revert the node log level"$reverted_log_level" -eq "$current_log_level" ]]; then for ip in "${ip_array[@]}"; do echo -e "Node log level for IP $ip reverted successfully back to ${BOLD_GREEN}${current_log_level=_name}${original_log_levels["$ip"]}RESET}." else current_log_level_name=${original_log_level_names["$ip"]} debug_msg "Reverting node logecho level-e back"Failed to $current_log_level_namerevert node log level for IP $ip..." Response: ${RED}$response${RESET}" 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\"" exit 1 response=$(curl --user "$credentials" -sS -X PUT -H "Content-Type: application/json" \ fi done "http://$ip:91/api/storage/nodes/_self/settings/log.nodeLogLevel?value=$current_log_level") # Combine the log output debug_msg "Response: $response" for multiple IP addresses into a single summary if [[ "$jq_or_grep" == "grep" ]](( size_diff < 0 )); then echo -e "castor.log file was rotated." reverted_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')else echo -e else"" reverted_log_level=$(echo -e "$response" | "$jq_or_grep" -r '.value') fiApproximate ${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 ${YELLOW}$duration${RESET} seconds (${YELLOW}$duration_formatted${RESET})." final_size=$(statecho -c%se "$log_file" 2>/dev/null || echo 0) fi size_diff=$(( final_size - initial_size ))else size_diff_formatted=$(format_size "$size_diff") duration_formatted=$(format_duration "$duration")echo "Log level change is permanent until manually modified." fi fi if [[ "$reverted_log_level" -eq "$current_log_level" ]]; then fi } # Run in detachable or directly if $detachable; then # Pass the main_script function to the 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}screen session and store the output in a file debug_msg "**********************************************************" | tee -a "$output_log" debug_msg "Detach mode - Parameters passed to main_script:" | tee -a "$output_log" debug_msg " Swarm IP: $swarm_ip" | tee -a "$output_log" debug_msg " Credentials: $(print_credentials "$credentials")" | tee -a "$output_log" debug_msg " exit 1 New Log Level: $new_log_level" | tee -a "$output_log" debug_msg " fi New log Level doneName: $new_log_level_name" | tee -a "$output_log" debug_msg " Duration: $duration" | tee # Combine the log output for multiple IP addresses into a single summary if (( size_diff < 0 )); then echo -e "castor.log file was rotated." else -a "$output_log" debug_msg " Log Level Type: $log_level_type" | tee -a "$output_log" debug_msg " Log File: $log_file" | tee -a "$output_log" echo -e ""debug_msg " Initial Log File Size: $initial_size" | tee -a "$output_log" 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." fi 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\"debug_msg " Current Log Level: $current_log_level" | tee -a "$output_log" debug_msg " Cluster Name: $clusterName" | tee -a "$output_log" debug_msg " jq_or_grep: $jq_or_grep" | tee -a "$output_log" debug_msg " Detach: $detachable" | tee -a "$output_log" debug_msg " Debug: $debug" | tee -a "$output_log" debug_msg "**********************************************************" | tee -a "$output_log" # Convert associative arrays to strings and pass them to the screen session log_levels_string=$(declare -p log_levels) log_level_names_string=$(declare -p log_level_names) debug_msg "log_levels_string: $log_levels_string" | tee -a "$output_log" debug_msg "log_level_names_string: $log_level_names_string" | tee -a "$output_log" if command -v screen &>/dev/null; then echo -e "Running in ${YELLOW}screen${RESET} detachable mode..." | tee -a "$output_log" screen -dmS indexercastor_log_script bash -c "$(declare -f main_script timestamp debug_msg format_size format_duration check_jqcheck_jq determine_log_file print_credentials); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$new_log_level_name\" \"$duration\" \"$log_level_type\" \"$clusterName\" \"$jq_or_grep\" \"$detachable\" \"$debug\" | tee \"$output_log\"" \"${log_levels_string}\" \"${log_level_names_string}\" | tee \"$output_log\"" screen -r castor_log_script # Wait for the screen session to complete and then display the output log sleep 1 while screen -list | grep -q "castor_log_script"; do sleep 1 screen -r indexer_scriptdone elif command -v tmux &>/dev/null; then #echo tmux new-sessione -d -s indexer_script "$(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\""Running in ${YELLOW}tmux${RESET} detachable mode..." | tee \-a "$output_log\"" tmux new-session -d -s indexercastor_log_script "$(declare -f main_script timestamp debug_msg format_size format_duration check_jq determine_log_file print_credentials); main_script \"$swarm_ip\" \"$credentials\" \"$new_log_level\" \"$new_log_level_name\" \"$duration\" \"$log_level_type\" \"$clusterName\" \"$jq_or_grep\" \"$debug$detachable\" | tee \"$output_log$debug\"" tmux attach-session -t indexer_script else echo "Error: Neither screen nor tmux available. Run without --detachable." exit 1 \"${log_levels_string}\" \"${log_level_names_string}\" | tee \"$output_log\"" fi tmux attach-session # Wait for the screen session to complete and then display the output log sleep 1 while screen -list | grep -q "indexer_script"; do-t castor_log_script else echo "Error: Neither screen nor tmux available. Run without --detachable." exit sleep 1 donefi echo "" cat "$output_log" else # main_script "$swarm_ip" "$credentials" "$new_log_level" "$duration" "$clusterName" "$jq_or_grep" | tee "$output_log" debug_msg "**********************************************************" debug_msg "Parameters passed to main_script:" debug_msg "Swarm IP: $swarm_ip" debug_msg "Credentials: $(print_credentials "$credentials")" debug_msg "New Log Level: $new_log_level" debug_msg "Duration: $duration" debug_msg "Cluster Name: $clusterName" debug_msg "jq_or_grep: $jq_or_grep" debug_msg "**********************************************************" debug_msg "Running main_script function..." main_script "$swarm_ip" "$credentials" "$new_log_level" "$new_log_level_name" "$duration" "$log_level_type" "$clusterName" "$jq_or_grep" | tee "$output_log" fi |
...