Skip to content

Instantly share code, notes, and snippets.

@ardabbour
Created April 10, 2023 14:14
Show Gist options
  • Save ardabbour/66b5d858b3c4c98cee198b1394581c7a to your computer and use it in GitHub Desktop.
Save ardabbour/66b5d858b3c4c98cee198b1394581c7a to your computer and use it in GitHub Desktop.
A simple logging 'library' for bash scripts.
#!/bin/bash
# A simple logging 'library' for bash scripts.
#
# There are three basic things to set:
# - Minimum log level [default: info] (debug < info < warn < error < critical)
# - Node name [default: unidentified]
# - Log path [default: $HOME/.local/log/$LOGGER_NODE_NAME.log]
#
# Example usage:
#
# ```bash
# # initialize logger
# source logger.sh
# LOGGER_LOG_LEVEL="$LOGGER_LEVEL_WARN"
# LOGGER_LOG_PATH="a_node.log"
# LOGGER_NODE_NAME="my_awesome_node"
#
# # exit if a specific file doesn't exist
# FILE=$HOME/my_important_file
# if [ ! -f "$FILE" ]; then
# log_critical "file does not exist!"
# exit 1
# fi
# ```
#
# When triggered, this appends an entry into "a_node.log" such as:
# [2014-10-31 23:46:59.678] [my_awesome_node] [critical] file does not exist!
readonly LOGGER_LEVEL_DEBUG=0
readonly LOGGER_LEVEL_INFO=1
readonly LOGGER_LEVEL_WARN=2
readonly LOGGER_LEVEL_ERROR=3
readonly LOGGER_LEVEL_CRITICAL=4
LOGGER_LOG_LEVEL=${LOGGER_LOG_LEVEL:-$LOGGER_LEVEL_INFO}
LOGGER_NODE_NAME=${LOGGER_NODE_NAME:-"unidentified"}
LOGGER_LOG_PATH="$HOME/.local/log/$LOGGER_NODE_NAME.log"
_log() {
local log_level
local message
local timestamp
log_level=$1
shift
message="$*"
timestamp=$(date +"%Y-%m-%d %H:%M:%S.%3N")
prefix="[$timestamp] [$LOGGER_NODE_NAME]"
if [ ! -f "$LOGGER_LOG_PATH" ]; then
mkdir -p "$(dirname "$LOGGER_LOG_PATH")"
touch "$LOGGER_LOG_PATH"
fi
if [ "$log_level" -ge "$LOGGER_LOG_LEVEL" ]; then
case $log_level in
"$LOGGER_LEVEL_DEBUG")
echo "$prefix [debug] $message" >>"$LOGGER_LOG_PATH"
;;
"$LOGGER_LEVEL_INFO")
echo "$prefix [info] $message" >>"$LOGGER_LOG_PATH"
;;
"$LOGGER_LEVEL_WARN")
echo "$prefix [warn] $message" >>"$LOGGER_LOG_PATH"
;;
"$LOGGER_LEVEL_ERROR")
echo "$prefix [error] $message" >&2 >>"$LOGGER_LOG_PATH"
;;
"$LOGGER_LEVEL_CRITICAL")
echo "$prefix [critical] $message" >&2 >>"$LOGGER_LOG_PATH"
;;
*)
echo "Unknown log level $log_level"
;;
esac
fi
}
log_debug() { _log $LOGGER_LEVEL_DEBUG "$@"; }
log_info() { _log $LOGGER_LEVEL_INFO "$@"; }
log_warn() { _log $LOGGER_LEVEL_WARN "$@"; }
log_error() { _log $LOGGER_LEVEL_ERROR "$@"; }
log_critical() { _log $LOGGER_LEVEL_CRITICAL "$@"; }
#!/bin/bash
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$CURRENT_DIR"/logger.sh
LOGGER_NODE_NAME="bash_logger_test"
LOGGER_LOG_LEVEL="$LOGGER_LEVEL_DEBUG"
LOGGER_LOG_PATH=$(mktemp)
log_dummy_messages() {
log_debug "debug message"
log_info "info message"
log_warn "warn message"
log_error "error message"
log_critical "critical message"
}
assert() {
local test_name="$1"
local expected="$2"
local result="failed"
while read -r line; do
if [[ "$line" == *"$expected" ]]; then
result="passed"
break
fi
done <"$LOGGER_LOG_PATH"
echo "$test_name: $result"
}
assert_dummy_messages() {
assert "debug_test" "[$LOGGER_NODE_NAME] [debug] debug message"
assert "info_test" "[$LOGGER_NODE_NAME] [info] info message"
assert "warn_test" "[$LOGGER_NODE_NAME] [warn] warn message"
assert "error_test" "[$LOGGER_NODE_NAME] [error] error message"
assert "critical_test" "[$LOGGER_NODE_NAME] [critical] critical message"
}
log_dummy_messages
assert_dummy_messages
rm "$LOGGER_LOG_PATH"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment