From f076694a6a4cd6cfcb7e5eb633a156d54d2e57b7 Mon Sep 17 00:00:00 2001 From: Alex Macocian Date: Sun, 27 Jul 2025 08:21:06 +0200 Subject: [PATCH] Improve metric scripts --- custom-metrics/disk-usage.sh | 35 ++++++++++----- custom-metrics/power-usage.sh | 81 ++++++++++++++++++++++++++++------- custom-metrics/temperature.sh | 72 +++++++++++++++++++++++++++---- 3 files changed, 155 insertions(+), 33 deletions(-) diff --git a/custom-metrics/disk-usage.sh b/custom-metrics/disk-usage.sh index 03cae4b..aa24668 100644 --- a/custom-metrics/disk-usage.sh +++ b/custom-metrics/disk-usage.sh @@ -4,16 +4,31 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . "${SCRIPT_DIR}/../share/logging.sh" LOGFILE=/var/log/disk_usage.log -touch "$LOGFILE" -chmod 644 "$LOGFILE" + +# Create log file with proper error handling +if ! touch "$LOGFILE" 2>/dev/null; then + LogError "Cannot create log file $LOGFILE" + exit 1 +fi +chmod 644 "$LOGFILE" 2>/dev/null + +LogInformation "Starting disk usage monitoring" for i in {1..6}; do - timestamp=$(GetTimestamp) - df --output=target,used,size -B1 \ - | tail -n +2 \ - | while read -r mount used total; do - echo "$timestamp $mount $used $total" >> "$LOGFILE" - done + timestamp=$(GetTimestamp) + + # Use process substitution instead of pipe to avoid subshell issues + while read -r mount used total; do + if [[ -n "$mount" && -n "$used" && -n "$total" ]]; then + echo "$timestamp $mount $used $total" >> "$LOGFILE" + fi + done < <(df --output=target,used,size -B1 2>/dev/null | tail -n +2) + + LogInformation "Disk usage data collected (iteration $i/6)" + + if [ $i -lt 6 ]; then + sleep 10 + fi +done - sleep 10 -done \ No newline at end of file +LogInformation "Disk usage monitoring completed" \ No newline at end of file diff --git a/custom-metrics/power-usage.sh b/custom-metrics/power-usage.sh index 103dbc9..25e555e 100644 --- a/custom-metrics/power-usage.sh +++ b/custom-metrics/power-usage.sh @@ -4,27 +4,78 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . "${SCRIPT_DIR}/../share/logging.sh" LOGFILE=/var/log/power_usage.log -touch "$LOGFILE" -chmod 644 "$LOGFILE" + +# Create log file with proper error handling +if ! touch "$LOGFILE" 2>/dev/null; then + LogError "Cannot create log file $LOGFILE" + exit 1 +fi +chmod 644 "$LOGFILE" 2>/dev/null + +# Check if bc is available +if ! command -v bc >/dev/null 2>&1; then + LogError "bc command not found. Please install bc: sudo apt-get install bc" + exit 1 +fi # Path to the energy_uj file for the CPU package RAPL_PATH="/sys/class/powercap/intel-rapl:0/energy_uj" + +# Check if RAPL interface is available +if [[ ! -r "$RAPL_PATH" ]]; then + LogError "Intel RAPL interface not available at $RAPL_PATH" + LogError "This may be due to:" + LogError "1. Non-Intel CPU" + LogError "2. RAPL not supported by kernel" + LogError "3. Insufficient permissions" + LogError "4. Module not loaded (try: sudo modprobe intel_rapl_common)" + exit 1 +fi + +LogInformation "Starting power usage monitoring" + for i in {1..6}; do - energy_1=$(cat $RAPL_PATH) - sleep 1 + # Read initial energy value + if ! energy_1=$(cat "$RAPL_PATH" 2>/dev/null); then + LogError "Failed to read energy value from $RAPL_PATH" + exit 1 + fi + + sleep 1 - energy_2=$(cat $RAPL_PATH) - energy_diff=$((energy_2 - energy_1)) + # Read second energy value + if ! energy_2=$(cat "$RAPL_PATH" 2>/dev/null); then + LogError "Failed to read energy value from $RAPL_PATH" + exit 1 + fi + + energy_diff=$((energy_2 - energy_1)) - # Convert microjoules to joules (1 J = 1,000,000 µJ) - energy_joules=$(echo "scale=6; $energy_diff / 1000000" | bc) + # Convert microjoules to joules (1 J = 1,000,000 µJ) + energy_joules=$(echo "scale=6; $energy_diff / 1000000" | bc 2>/dev/null) + + if [[ $? -ne 0 ]]; then + LogError "Failed to calculate energy in joules" + continue + fi - # Since we waited 1 second, the power usage is simply the energy difference in joules (W) - power_watts=$(echo "scale=6; $energy_joules / 1" | bc) + # Since we waited 1 second, the power usage is simply the energy difference in joules (W) + power_watts=$(echo "scale=6; $energy_joules / 1" | bc 2>/dev/null) + + if [[ $? -ne 0 ]]; then + LogError "Failed to calculate power in watts" + continue + fi - timestamp=$(GetTimestamp) + timestamp=$(GetTimestamp) - # Write power usage to log file - echo "$timestamp $power_watts" >> "$LOGFILE" - sleep 9 -done \ No newline at end of file + # Write power usage to log file + echo "$timestamp $power_watts" >> "$LOGFILE" + LogInformation "Power usage recorded: ${power_watts}W (iteration $i/6)" + + if [ $i -lt 6 ]; then + sleep 9 + fi +done + +LogInformation "Power usage monitoring completed" \ No newline at end of file diff --git a/custom-metrics/temperature.sh b/custom-metrics/temperature.sh index 18b4ce7..d2cd6f3 100644 --- a/custom-metrics/temperature.sh +++ b/custom-metrics/temperature.sh @@ -4,13 +4,69 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" . "${SCRIPT_DIR}/../share/logging.sh" LOGFILE=/var/log/temperature.log -touch "$LOGFILE" -chmod 644 "$LOGFILE" + +# Create log file with proper error handling +if ! touch "$LOGFILE" 2>/dev/null; then + LogError "Cannot create log file $LOGFILE" + exit 1 +fi +chmod 644 "$LOGFILE" 2>/dev/null + +# Check if thermal zones exist +THERMAL_ZONES=(/sys/class/thermal/thermal_zone*/type) +if [[ ! -e "${THERMAL_ZONES[0]}" ]]; then + LogError "No thermal zones found in /sys/class/thermal/" + LogError "This system may not support thermal monitoring" + exit 1 +fi + +LogInformation "Starting temperature monitoring" for i in {1..6}; do - timestamp=$(GetTimestamp) - paste <(cat /sys/class/thermal/thermal_zone*/type) <(cat /sys/class/thermal/thermal_zone*/temp) | column -s $'\t' -t | sed 's/\(.\)..$/.\1°C/' | while read line; do - echo "$timestamp $line" >> "$LOGFILE" - done - sleep 10 -done \ No newline at end of file + timestamp=$(GetTimestamp) + + # Use arrays to avoid complex pipe chains that can hang + types=() + temps=() + + # Read thermal zone types + for type_file in /sys/class/thermal/thermal_zone*/type; do + if [[ -r "$type_file" ]]; then + type_value=$(cat "$type_file" 2>/dev/null) + if [[ -n "$type_value" ]]; then + types+=("$type_value") + fi + fi + done + + # Read thermal zone temperatures + for temp_file in /sys/class/thermal/thermal_zone*/temp; do + if [[ -r "$temp_file" ]]; then + temp_value=$(cat "$temp_file" 2>/dev/null) + if [[ -n "$temp_value" && "$temp_value" =~ ^[0-9]+$ ]]; then + # Convert millidegrees to degrees with one decimal place + temp_celsius=$(echo "scale=1; $temp_value / 1000" | bc 2>/dev/null) + if [[ $? -eq 0 ]]; then + temps+=("${temp_celsius}°C") + else + temps+=("${temp_value}m°C") + fi + fi + fi + done + + # Output paired type and temperature data + for j in "${!types[@]}"; do + if [[ $j -lt ${#temps[@]} ]]; then + echo "$timestamp ${types[$j]} ${temps[$j]}" >> "$LOGFILE" + fi + done + + LogInformation "Temperature data collected (iteration $i/6)" + + if [ $i -lt 6 ]; then + sleep 10 + fi +done + +LogInformation "Temperature monitoring completed" \ No newline at end of file