Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Managing Log Levels in Swarm Cluster Using a Shell Script

Overview

This knowledge base entry provides detailed information about the set_swarm_log_level.sh script , which is used designed to set and manage the logging levels of Swarm API clusters. This script simplifies the process of changing log levels and allows users to revert changes after a specified duration if needed.

Purpose

The purpose of this script is to:

...

adjust the log level of a Swarm cluster. The script can set the log level permanently or temporarily (for a specified duration), after which it reverts to the original log level.

Script Overview

This script enables administrators to:

  • Adjust the log level of a Swarm cluster to a specified value.Optionally revert permanently or temporarily.

  • Monitor log file growth after setting a higher log level for diagnostics.

  • Revert the log level back to its original setting automatically after a defined duration.

  • Provide an easy-to-use interface for managing log levels without needing extensive API knowledge.

Script Functionality

  • Input Parameters: The script accepts parameters for the Swarm API IP address, credentials, new log level, and optional duration for temporary changes.

  • Validation and Error Handling: It checks for required parameters and handles errors gracefully.

  • Logging Level Management: Retrieves the current log level, updates it if necessary, and optionally reverts it after a countdown.

Key Features

  • Dynamic Duration Input: If the duration parameter is provided without a value, the user is prompted to enter the duration in seconds.

  • User Feedback: The script provides informative output regarding the current state and actions being taken, including success and error messages.

  • Count Down Timer: If a duration is specified, the script displays a countdown in hours, minutes, and seconds.

Script Source Code

...

languagebash

...

  • period.

Script Source Code

Code Block
languagebash
#!/bin/bash

# Function to display usage information
usage() {
    echo "Usage: $0 -d swarm_ip -p admin:password -i new_log_level [-t duration_in_seconds]"
    echo "  -d, --swarm_ip           IP address of the Swarm API endpoint"
    echo "  -p, --credentials        Credentials in the format admin:password"
    echo "  -i, --log.level          New log level to set"
    echo "  -t, --time               Duration in seconds to keep the new log level (optional)"
    exit 1
}

# 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  -i, --log.level "BEGIN {printf \"%.1fKB\", $size/1024}")"
        Newelse
log level to set"     echo "${size}B"
 -t, --time  fi
}

# Function to format duration
format_duration() {
    Durationlocal induration=$1
seconds to keep the new log level (optional)"local hours=$((duration / 3600))
    local exit 1
}

# Function to format file size
format_size() {minutes=$(( (duration % 3600) / 60 ))
    local seconds=$((duration % 60))
     local size=$1
    if (( size >= 1073741824 )); then
   printf "%02d:%02d:%02d" $hours $minutes $seconds
}

# Parse input arguments
while [[ "$#" -gt 0 ]]; do
    echo "$(awk "BEGIN {printf \"%.1fGB\", $size/1073741824}")"case $1 in
       elif (( size >= 1048576 )); then -d|--swarm_ip) swarm_ip="$2"; shift ;;
         echo "$(awk "BEGIN {printf \"%.1fMB\", $size/1048576}")"-p|--credentials) credentials="$2"; shift ;;
      elif (( size >= 1024 )); then -i|--log.level) new_log_level="$2"; shift ;;
         echo "$(awk "BEGIN {printf \"%.1fKB\", $size/1024}")"-t|--time)
        else    if [[ -n   echo "${size}B"
    fi
}

# Function to format duration
format_duration() {"$2" && "$2" != -* ]]; then
               local duration=$1"$2"
    local hours=$((duration / 3600))     local minutes=$(( (duration % 3600)shift
/ 60 ))     local seconds=$((duration % 60))  else
  printf "%02d:%02d:%02d" $hours $minutes $seconds }  # Parse input    arguments whileread [[-p "$#" -gt 0 ]]; doEnter duration in seconds: " duration
           case $1fi
in         -d|--swarm_ip) swarm_ip="$2"; shift ;;
        -p|--credentials*) credentials="$2"; shiftusage ;;
     esac
  -i|--log.level) new_log_level="$2"; shift
;;done

# Check if required arguments   -t|--time)
            are provided
if [[ -nz "$2" && "$2" != -*$swarm_ip" || -z "$credentials" || -z "$new_log_level" ]]; then
    usage
fi

# Retrieve the cluster name
clusterName=$(curl -u admin:caringo -sS duration="$2"
         "http://$swarm_ip:91/api/storage/clusters" | grep -oP '"name":\s*"\K[^"]+')
if [[ -z "$clusterName" ]]; then
    echo "Failed shiftto retrieve the cluster name. Please check your inputs."
    elseexit 1
fi

# Convert duration to an integer if it is set
if   read[[ -pn "$duration"Enter duration]]; inthen
seconds: " duration  if ! [[ "$duration" =~ ^[0-9]+$ ]]; then
   fi     echo "Error: Duration must be a positive integer ;;value in seconds."
      *) usage ;;exit 1
   esac     shift
donefi
fi

# CheckDisplay ifinput requiredparameters
argumentsecho are provided
if [[ -z ""Swarm IP: $swarm_ip"
|| -zecho "$credentials" || -z "$new_log_level" ]]; then
    usage
fiCredentials: [hidden for security]"
echo "Cluster Name: $clusterName"

# RetrieveIdentify the log clusterfile namelocation
clusterName=$(curl -u admin:caringo -sS "http://$swarm_ip:91/api/storage/clusters" | grep -oP '"name":\s*"\K[^"]+')
iflog_file=""
if [[ -f "/var/log/caringo/castor.log" ]]; then
    log_file="/var/log/caringo/castor.log"
elif [[ -zf "$clusterName/var/log/datacore/castor.log" ]]; then
    echo "Failed to retrieve the cluster name. Please check your inputs."
    exit 1
log_file="/var/log/datacore/castor.log"
fi

# ConvertDisplay durationlog tofile aninformation integerand if it is set
truncate
if [[ -n "$duration$log_file" ]]; then
    ifecho !"Log [[ "$duration" =~ ^[0-9]+$ ]]; thenfile located at: $log_file"

    # Capture initial file size
echo "Error: Duration must be a positive integer value in seconds." initial_size=$(stat -c%s "$log_file")
    initial_size_formatted=$(format_size "$initial_size")
   exit 1echo "Initial log file  fi
fi

# Display input parameterssize: $initial_size_formatted"

else
    echo "Swarm IPWarning: $swarm_ip"
echo "Credentials: [hidden for security]"
echo "Cluster Name: $clusterName"Log file not found in expected directories."
fi

# IdentifyGet the current log filelevel
locationecho log_file=""
echo if"Retrieving [[the -f "/var/log/caringo/castor.log" ]]; then
    log_file="/var/log/caringo/castor.log"
elif [[ -f "/var/log/datacore/castor.log" ]]; then
    log_file="/var/log/datacore/castor.log"
fi

# Display log file information and truncatecurrent log level..."
current_log_level=$(curl -u "$credentials" -sS "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" | grep -oP '"value":\s*\K[0-9]+')

# Check if the current log level was retrieved successfully
if [[ -nz "$log$current_log_filelevel" ]]; then
    echo "LogFailed to fileretrieve locatedthe at: $log_file"

    # Capture initial file size
    initial_size=$(stat -c%s "$log_file")
    initial_size_formatted=$(format_size "$initial_size")
    echo "Initial log file size: $initial_size_formatted"

elsecurrent log level. Please check your inputs."
    exit 1
fi
echo "New log level: $new_log_level"
echo "Current log level is $current_log_level."

# Check if the new log level is the same as the current log level
if [[ "$current_log_level" -eq "$new_log_level" ]]; then
    echo "Warning: Log file not found in expected directories."
"
    echo "Log level is already set to $new_log_level. No changes made."
    exit 0
fi

# GetUpdate the current log level echousing ""PUT
echo "RetrievingUpdating log thelevel currentto $new_log _level..."
current_log_level=response=$(curl -u "$credentials" -sS -X PUT -H "Content-Type: application/json" \
    "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" \
|   grep -oPd '"{\"value":\s*\K[0-9]+'\": $new_log_level}")

# CheckVerify if the current log level was retrieved successfully updated
updated_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')
if [[ -z"$updated_log_level" -eq "$current$new_log_level" ]]; then
    echo "FailedLog tolevel retrievechanged thesuccessfully currentfrom $current_log _level. Please check your inputs→ $new_log_level."
else
   exit 1echo fi"Failed echoto "Newupdate log level. Response: $new_log_level$response"
 echo "Current log levelexit is $current_log_level."1
fi

# CheckIf ifduration theis newspecified, logwait leveland is the same asrevert after the currentspecified log leveltime
if [[ -n "$current_log_level$duration" -eq&& "$new_log_level"$duration" -gt 0 ]]; then
    echo ""Keeping log level at $new_log_level echofor "Log level is already set to $new_log_level. No changes made."
    exit 0
fi

# Update the log level using PUT
echo "Updating log level to $new_log_level..."
response=$(curl -u "$credentials" -sS -X PUT -H "Content-Type: application/json" \
    "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" \
    -d "{\"value\": $new_log_level}")

# Verify if the log level was updated
updated_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')
if [[ "$updated_log_level" -eq "$new_log_level" ]]; then
    echo "Log level changed successfully from $current_log_level → $new_log_level."
else
    echo "Failed to update log level. Response: $response"
    exit 1
fi

# If duration is specified, wait and revert after the specified time
if [[ -n "$duration" && "$duration" -gt 0 ]]; then
    echo "Keeping log level at $new_log_level for $duration second(s)$duration second(s)..."
    echo ""

    # Countdown loop
    for ((i=duration; i>0; i--)); do
        # Calculate hours, minutes, and seconds
        hours=$((i / 3600))
        minutes=$(( (i % 3600) / 60 ))
        seconds=$((i % 60))

        # Format countdown in hh:mm:ss
        printf -v countdown "%02d:%02d:%02d" $hours $minutes $seconds
        echo -ne "Countdown: $countdown remaining...\r"
        sleep 1
    done
    echo -e "\n\nTime's up! Reverting log level back to $current_log_level..."

   echo ""# Check log file size before #reverting
Countdown loop     for ((i=duration; i>0; i--)); do
   final_size=$(stat -c%s "$log_file")
    final_size_formatted=$(format_size "$final_size")

    # Calculate hours,size minutes,difference
and seconds         hourssize_diff=$((i / 3600 final_size - initial_size ))
        minutessize_diff_formatted=$(( (i % 3600) / 60 ))format_size "$size_diff")

    # Display size difference and  seconds=$((i % 60))

    final log size
    # Formatecho countdown in hh:mm:ss
        printf -v countdown "%02d:%02d:%02d" $hours $minutes $seconds
        echo -ne "Countdown: $countdown remaining...\r""Approximate $size_diff_formatted new logs was genreated at log level $new_log_level. Current castor.log size is $final_size_formatted."
    # Format the duration for display
    duration_formatted=$(format_duration "$duration")

    # Updated message with sleepduration 1in hh:mm:ss format
  done  echo "Approximate $size_diff_formatted echonew -e "\n\nTime's up! Revertinglogs was generated at log level back to $current$new_log_level..." Current castor.log size is $final_size_formatted # Check log file size before reverting
    final_size=$(stat -c%s "$log_file")after $duration_formatted."
    final_size_formatted=$(format_sizeecho "$final_size")

    # Revert to Calculateoriginal sizelog differencelevel
    size_diffresponse=$(( final_size - initial_size ))
    size_diff_formatted=$(format_size "$size_diff")

    # Display size difference and final log size
    # echo "Approximate $size_diff_formatted new logs was genreated at log level $new_log_level. Current castor.log size is $final_size_formatted."
    # Format the duration for display
    duration_formatted=$(format_duration "$duration")

    # Updated message with duration in hh:mm:ss format
    echo "Approximate $size_diff_formatted new logs was generated at log level $new_log_level. Current castor.log size is $final_size_formatted after $duration_formatted."
    echo ""

    # Revert to original log level
    response=$(curl -u "$credentials" -sS -X PUT -H "Content-Type: application/json" \
        "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" \
        -d "{\"value\": $current_log_level}")

    reverted_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')
    if [[ "$reverted_log_level" -eq "$current_log_level" ]]; then
        echo "Log level reverted successfully back to $current_log_level."
    else
        echo "Failed to revert log level. Response: $response"
        exit 1
    fi
else
    echo "Log level change is permanent until manually modified."
fi

Usage Instructions

To use the script, run it from the command line with the appropriate parameters:

Code Block
./set_swarm_log_level.sh -d <swarm_ip> -p <admin:password> -i <new_log_level> [-t <duration_in_seconds>]

Examples

  1. Change Log Level Permanently:

    Code Block
    . /set_swarm_log_level.sh -d 192.168.8.84 -p admin:datacore -i 30
  2. Change Log Level Temporarily:

    Code Block
    ./set_swarm_log_level.sh -d 192.168.8.84 -p admin:datacore -i 20 -t 300
  3. Prompt for Duration:

    Code Block
    ./set_swarm_log_level.sh -d 192.168.8.84 -p admin:datacore -i 10 -t

Troubleshooting

  • Ensure correct permissions and network access to the Swarm API.

  • Verify input parameters and check for typos.

  • Ensure that curl and jq are installed and available in the environment.

Conclusion

...

curl -u "$credentials" -sS -X PUT -H "Content-Type: application/json" \
        "http://$swarm_ip:91/api/storage/clusters/$clusterName/settings/log.level" \
        -d "{\"value\": $current_log_level}")

    reverted_log_level=$(echo "$response" | grep -oP '"value":\s*\K[0-9]+')
    if [[ "$reverted_log_level" -eq "$current_log_level" ]]; then
        echo "Log level reverted successfully back to $current_log_level."
    else
        echo "Failed to revert log level. Response: $response"
        exit 1
    fi
else
    echo "Log level change is permanent until manually modified."
fi

Script Usage

Code Block
./log_level_script.sh -d SWARM_IP -p ADMIN:PASSWORD -i LOG_LEVEL [-t DURATION]
  • Parameters:

    • -d / --swarm_ip: Specifies the IP address of the Swarm API endpoint. (Required)

    • -p / --credentials: Administrator credentials in admin:password format. (Required)

    • -i / --log.level: Desired log level to apply. (Required)

    • -t / --time: Duration in seconds to keep the new log level before reverting to the previous setting. If omitted, the change is permanent. (Optional)

Prerequistites

  • Access to the Swarm storage nodes and valid credentials

  • Verify network access to the Swarm storage nodes from the machine where the script runs.

Instruction for Use

  • Setting the Log Level Permanently To make a permanent change, omit the -t parameter:

    Code Block
    bash

    Copy code

    ./log_level_script.sh -d 192.168.1.100 -p admin:password -i 3

    This sets the log level to 3 permanently until you manually change it.

  • Setting the Log Level Temporarily Specify a duration (in seconds) with the -t parameter to revert automatically after a defined period:

    Code Block
    bash

    Copy code

    ./log_level_script.sh -d 192.168.1.100 -p admin:password -i 3 -t 600

    In this example, the log level is set to 3 and reverts to the original level after 600 seconds (10 minutes).

  • Monitoring Log File Size

    • The script identifies the log file (castor.log) in either /var/log/caringo/ or /var/log/datacore/.

    • Initial file size is shown before setting the new log level.

    • Final file size and size difference are displayed after the temporary duration ends, indicating logs generated during this period.

  • Output Details

    • The script displays Swarm IP, log file location, initial and final log file sizes, and the cluster name.

    • For temporary log levels, a countdown timer displays time remaining before reverting.

    • Once completed, it provides the approximate amount of logs generated, duration, and confirms reversion to the original log level.

Example Output

Code Block
Swarm IP: 192.168.1.100
Credentials: [hidden for security]
Cluster Name: Cluster_01
Log file located at: /var/log/datacore/castor.log
Initial log file size: 10.5MB
New log level: 3
Current log level is 2.
Updating log level to 3...
Log level changed successfully from 2 → 3.
Keeping log level at 3 for 600 second(s)...
Approximate 1.2MB new logs were generated at log level 3. Current castor.log size is 11.7MB after 00:10:00.
Log level reverted successfully back to 2.

Error Handling

  • Missing Parameters: Missing parameters prompt a usage message.

  • Invalid Duration: If a non-numeric duration is provided, you’re prompted to enter a valid duration in seconds.

  • Connection Issues: If unable to connect to the Swarm API, check the IP, credentials, and network access.

Notes

  • Credentials are masked in the output for security.

  • Log file sizes are shown in human-readable format (GB, MB, KB, B).

This script provides administrators with an effective way to adjust and monitor Swarm logging, supporting both temporary and permanent log level changes for troubleshooting and performance monitoring.