Skip to content

Instantly share code, notes, and snippets.

@jefferys
Created December 17, 2020 19:46
Show Gist options
  • Save jefferys/f0a597cba9b8ed7629422f5644c56f18 to your computer and use it in GitHub Desktop.
Save jefferys/f0a597cba9b8ed7629422f5644c56f18 to your computer and use it in GitHub Desktop.
Bash program messages - terminal and log file printing
# USAGE:
# say $LEVEL_INFO "This is an" "informational message."
# #> "This is an informational message."
#
# sayError "This is an" "error message."
# #> "ERROR: This is an error message."
#
# LEVELS:
# In order from highest priority message to lowest:
# $LEVEL_ALL $LEVEL_ERROR $LEVEL_WARN $LEVEL_INFO $LEVEL_VERBOSE
# $LEVEL_DEBUG $LEVEL_TRACE $LEVEL_IGNORE
#
# DETAILS:
# Print a message to the console and/or to a log file. All strings in the
# message will be concatenated with a space and a newline will be added at
# the end. The level name + a colon and a space will be prefixed to the
# message, except (by default) for INFO and VERBOSE console messages. Warning
# and error console messages will be printed (by default) to STDERR. Escape
# characters in messages will be translated when printed to the console and
# left as escape characters when printing to the log file. Messages printed
# to the log file will also have a timestamp (with no interal spaces) + a
# space added immediately after the LEVEL: prefix.
#
# Logging to the console and the screen are independent. By default logging
# to a file is turned off and messages above INFO are ignored.
#
# GLOBAL PARAMETERS:
# * SAY_BOUND - At this level and below a message is printed to the console.
# * LOG_BOUND - At this level and below a message is written to a file.
# * LOG_FILE - The file to append messages to, created if not existing.
# * DEFAULT_LEVEL - The default level for a message if not specified.
# * ERROR_BOUND - At this level and below, console messages print to STDERR.
# * NO_SAY_INFO - Set to 1 to slip INFO label on console messages.
# * NO_SAY_VERBOSE - Set to 1 to slip VERBOSE label on console messages.
#
# TODO:
# * Extract as module
# * Add functions to change default parameters (Logging and formatting).
# Message level definitions
LEVEL_ALL=-3
LEVEL_ERROR=-2
LEVEL_WARN=-1
LEVEL_INFO=0
LEVEL_VERBOSE=1
LEVEL_DEBUG=2
LEVEL_TRACE=3
LEVEL_IGNORE=4
LEVEL_NAMES=("ALL" "ERROR" "WARN" "INFO" "VERBOSE" "DEBUG" "TRACE" "IGNORE")
# Logging defaults
SAY_BOUND=$LEVEL_INFO
LOG_BOUND=$LEVEL_OFF
ERROR_BOUND=$LEVEL_WARN
DEFAULT_LEVEL=$LEVEL_INFO
LOG_FILE="$0.log"
# Formatting defaults
# TODO: Add color
NO_SAY_INFO=1
NO_SAY_VERBOSE=1
# TODO: Create parameter checking module, migrate this function
function isInt() {
local val="$1"
local re='^[-0-9]+$'
[[ "$val" =~ $re ]]
}
# TODO: Create date/time module, migrate this functions
function timeStamp() {
local ts=$(date '+%FT%T%z')
RETVAL="${ts%%??}:${ts: -2}"
}
# Main function
log() {
# Get message level. If first parameter is not a number, assume that
# it is part of the message and use the default level.
local asLevel=$1
if ! isInt $asLevel ; then
asLevel=$DEFAULT_LEVEL
else
shift
fi
# Handle out of bound numbers
[[ $asLevel -lt $LEVEL_ALL ]] && asLevel=$LEVEL_ALL
[[ $asLevel -gt $LEVEL_IGNORE ]] && asLevel=$LEVEL_IGNORE
# Want to print to terminal? Handle STDERR vs STDOUT and no-label messages.
if [[ $asLevel -le $SAY_BOUND ]]; then
# Want level name?
if [[ $asLevel == $LEVEL_INFO && $NO_SAY_INFO -eq 1 ]] ||
[[ $asLevel == $LEVEL_VERBOSE && $NO_SAY_VERBOSE -eq 1 ]]; then
# Print to stderr or to stdout
if [[ $asLevel -le $ERROR_BOUND ]]; then
echo -e "$@" 1>&2
else
echo -e "$@"
fi
else
# Print to stderr or to stdout
if [[ $asLevel -le $ERROR_BOUND ]]; then
echo -e "${LEVEL_NAMES[((asLevel - LEVEL_ALL))]}:" "$@" 1>&2
else
echo -e "${LEVEL_NAMES[((asLevel - LEVEL_ALL))]}:" "$@"
fi
fi
fi
# Want to print to the log file? Add timestamp and don't translate escapes.
if [[ $asLevel -le $LOG_BOUND ]]; then
local ts
timeStamp
ts="$RETVAL"
echo "${LEVEL_NAMES[((asLevel - LEVEL_OFF))]}" "$ts" "$@" 1>>"$LOG_FILE"
fi
}
# Shortcut alias functions
function logErr() { log $LEVEL_ERROR "$@" ; }
function logWarn() { log $LEVEL_WARNING "$@" ; }
function logInfo() { log $LEVEL_INFO "$@" ; }
function logVerbose() { log $LEVEL_VERBOSE "$@" ; }
function logDebug() { log $LEVEL_DEBUG "$@" ; }
function logTrace() { log $LEVEL_TRACE "$@" ; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment