mirror of
https://github.com/RetroDECK/RetroDECK.git
synced 2024-12-02 18:45:42 +00:00
130 lines
4.6 KiB
Bash
Executable file
130 lines
4.6 KiB
Bash
Executable file
# This script provides a logging function 'log' that can be sourced in other scripts.
|
|
# It logs messages to both the terminal and a specified logfile, supporting multiple log levels.
|
|
# The log function takes three parameters: log level, log message, and optionally the logfile. If no logfile is specified, it writes to retrodeck/logs/retrodeck.log.
|
|
#
|
|
# Supported logging levels (controlled by the variable 'logging_level'):
|
|
# - none: No logs are produced.
|
|
# - info: Logs informational messages (i) and errors (e).
|
|
# - warn: Logs warnings (w), informational messages (i), and errors (e).
|
|
# - debug: Logs all message types (d, w, i, e).
|
|
#
|
|
# Type of log messages:
|
|
# - d: Debug message (logged only in debug level).
|
|
# - i: Informational message (logged in debug, info, and warn levels).
|
|
# - w: Warning message (logged in debug and warn levels).
|
|
# - e: Error message (logged in all levels except none).
|
|
#
|
|
# Example usage:
|
|
# log w "foo" -> Logs a warning with message "foo" to the default log file retrodeck/logs/retrodeck.log.
|
|
# log e "bar" -> Logs an error with message "bar" to the default log file retrodeck/logs/retrodeck.log.
|
|
# log i "baz" rekku.log -> Logs an informational message "baz" to the specified log file retrodeck/logs/rekku.log.
|
|
#
|
|
# The function auto-detects if the shell is sh and avoids colorizing the output in that case.
|
|
|
|
log() {
|
|
# Exit early if logging_level is "none"
|
|
if [[ $logging_level == "none" ]]; then
|
|
return
|
|
fi
|
|
|
|
local level="$1" # Logging level of the current message
|
|
local message="$2" # Message to log
|
|
local logfile="${3:-$rd_logs_folder/retrodeck.log}" # Log file, default to retrodeck.log
|
|
local timestamp="$(date +[%Y-%m-%d\ %H:%M:%S.%3N])" # Timestamp for the log entry
|
|
local colorize_terminal=true
|
|
|
|
# Determine the calling function or use [FWORK]
|
|
local caller="${FUNCNAME[1]:-[FWORK]}"
|
|
caller="${caller^^}" # Convert to uppercase
|
|
|
|
# Check if the shell is sh (not bash or zsh) to avoid colorization
|
|
if [ "${SHELL##*/}" = "sh" ]; then
|
|
colorize_terminal=false
|
|
fi
|
|
|
|
# Function to check if the current message level should be logged
|
|
should_log() {
|
|
case "$logging_level" in
|
|
debug) return 0 ;; # Always log everything
|
|
info) [[ "$level" == "i" || "$level" == "e" ]] && return 0 ;;
|
|
warn) [[ "$level" != "d" ]] && return 0 ;;
|
|
error) [[ "$level" == "e" ]] && return 0 ;;
|
|
esac
|
|
return 1
|
|
}
|
|
|
|
if should_log; then
|
|
# Define message colors based on level
|
|
case "$level" in
|
|
d)
|
|
color="\e[32m[DEBUG]"
|
|
prefix="[DEBUG]"
|
|
;;
|
|
e)
|
|
color="\e[31m[ERROR]"
|
|
prefix="[ERROR]"
|
|
;;
|
|
w)
|
|
color="\e[33m[WARN]"
|
|
prefix="[WARN]"
|
|
;;
|
|
i)
|
|
color="\e[34m[INFO]"
|
|
prefix="[INFO]"
|
|
;;
|
|
*)
|
|
color="\e[37m[LOG]"
|
|
prefix="[LOG]"
|
|
;;
|
|
esac
|
|
|
|
# Construct the log message
|
|
if [ "$colorize_terminal" = true ]; then
|
|
colored_message="$color [$caller] $message\e[0m"
|
|
else
|
|
colored_message="$timestamp $prefix [$caller] $message"
|
|
fi
|
|
log_message="$timestamp $prefix [$caller] $message"
|
|
|
|
# Display the message in the terminal
|
|
echo -e "$colored_message" >&2
|
|
|
|
# Write the log message to the log file
|
|
if [ ! -f "$logfile" ]; then
|
|
#echo "$timestamp [WARN] Log file not found in \"$logfile\", creating it" >&2 # Disabled it as it's always appearing because of log rotation
|
|
touch "$logfile"
|
|
fi
|
|
echo "$log_message" >> "$logfile"
|
|
fi
|
|
}
|
|
|
|
|
|
# The rotate_logs function manages log file rotation to limit the number of logs retained.
|
|
# It compresses the current log file into a .tar.gz archive, increments the version of
|
|
# older log files (e.g., retrodeck.1.tar.gz to retrodeck.2.tar.gz), and deletes the oldest
|
|
# archive if it exceeds the maximum limit (default: 3 rotated logs). After rotation,
|
|
# the original log file is cleared for continued logging.
|
|
|
|
rotate_logs() {
|
|
local logfile="${1:-$rd_logs_folder/retrodeck.log}" # Default log file
|
|
local max_logs=3 # Maximum number of rotated logs to keep
|
|
|
|
# Rotate existing logs
|
|
for ((i=max_logs; i>0; i--)); do
|
|
if [[ -f "${logfile}.${i}.tar.gz" ]]; then
|
|
if (( i == max_logs )); then
|
|
# Remove the oldest log if it exceeds the limit
|
|
rm -f "${logfile}.${i}.tar.gz"
|
|
else
|
|
# Rename log file to the next number
|
|
mv "${logfile}.${i}.tar.gz" "${logfile}.$((i+1)).tar.gz"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Compress the current log file if it exists
|
|
if [[ -f "$logfile" ]]; then
|
|
# Compress without directory structure and suppress tar output
|
|
tar -czf "${logfile}.1.tar.gz" -C "$(dirname "$logfile")" "$(basename "$logfile")" --remove-files &>/dev/null
|
|
fi
|
|
} |