Skip to content

logging

A library of logging functions.

Note

This library is automatically loaded by the helpers library.

Variables:
Name Type Description Default Options
LIBBASH_LOG_LEVEL Environmental The log level during runtime info debug|info|warn|error|fatal

Note

printf functions currently do not support the passing of multiple parameters.

lb_debugf msg

Print a debug message without a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_infof msg

Print a info message without a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_warnf msg

Print a warn message without a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_errorf msg

Print a error message without a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_fatalf msg

Print a fatal message without a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_debugln msg

Print a debug message with a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_infoln msg

Print a info message with a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_warnln msg

Print a warn message with a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_errorln msg

Print a error message with a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}

lb_fatalln msg

Print a fatal message with a new line.

Parameters:
Name Type Description Default
msg string The message to print required
Examples:
#!/usr/bin/env bash

# shellcheck source=/dev/null
source ../init
# logging does not need to be sourced because it is automatically sourced by init.

# Set write log level
# shellcheck disable=SC2034
LIBBASH_LOG_LEVEL=debug

function main() {
  printf "LIBBASH_LOG_LEVEL: %s\n" "${LIBBASH_LOG_LEVEL}"
  lb_debugf "debugf test\n"
  lb_infof "infof test\n"
  lb_warnf "warnf test\n"
  lb_errorf "errorf test\n"
  lb_fatalf "fatalf test\n"

  lb_debugln "debugln test"
  lb_infoln "infoln test"
  lb_warnln "warnln test"
  lb_errorln "errorln test"
  lb_fatalln "fatalln test"
}

main "${@}"
Show source code in logging
#!/usr/bin/env bash
: "${LIBBASH_DIR:?LIBBASH_DIR must be set. Please source libbash/init before other libraries.}"

# shellcheck source=/dev/null
# source ./init

LIBBASH_LOG_LEVEL=${LIBBASH_LOG_LEVEL:-"info"}
export LIBBASH_LOG_LEVEL
# export LIBBASH_LOG_LEVEL=info

#------------------------------ Private Functions ------------------------------

function _lb_check_out(){
  local out="${1}"
  if [[ "${out}" =~ stdout|stderr ]]; then
    return 0
  else
    printf "%s is not a valid output argument, it should be stdout|stderr\n" "${out}"
    return 1
  fi
}

function _lb_check_print(){
  local print="${1}"
  if [[ "${print}" =~ printf|echo ]]; then
    return 0
  else
    printf "%s is not a valid print argument, it should be printf|echo\n" "${print}"
    return 1
  fi
}

function _lb_check_log_level(){
  local level="${1}"
  if [[ "${level}" =~ debug|info|warn|error|fatal ]]; then
    return 0
  else
    printf "%s is not a valid LIBBASH_LOG_LEVEL, it should be debug|info|warn|error|fatal\n" "${level}"
    return 1
  fi
}

function _lb_log_msg(){
  declare -A LIBBASH_LOG_LEVELS=( \
    [debug]=1 \
    [info]=2 \
    [warn]=3 \
    [error]=4 \
    [fatal]=5 \
  )
  declare -A BASH_LIB_LOG_COLOURS=( \
    [debug]="$(tput setaf 7)" \
    [info]="$(tput setaf 6)" \
    [warn]="$(tput setaf 3)" \
    [error]="$(tput setaf 1)" \
    [fatal]="$(tput setaf 7)" \
  )
  local bg_color
  # Background color for fatal
  bg_color=$(tput setab 1)
  local normal
  normal=$(tput sgr0)

  local runtime_log_level="${LIBBASH_LOG_LEVEL}"
  local write_log_level="${1}"
  local print="${2}"
  local msg="${3}"
  local out="${4:-stdout}"

  # Check our input arguments
  _lb_check_log_level "${runtime_log_level}"
  _lb_check_log_level "${write_log_level}"
  _lb_check_print "${print}"
  _lb_check_out "${out}"

  # Get the log level numbers
  local runtime_level_num="${LIBBASH_LOG_LEVELS[${runtime_log_level}]}"
  local write_level_num="${LIBBASH_LOG_LEVELS[${write_log_level}]}"

  # Return if the write log level is lower than the runtime log level
  if (( write_level_num < runtime_level_num )); then
    return
  fi

  # Convert to upper case
  write_log_level_out="${write_log_level^^}"

  # Truncate to 4 characters
  write_log_level_out="${write_log_level_out::4}"

  # Set color
  write_log_level_out="${BASH_LIB_LOG_COLOURS[${write_log_level}]}${write_log_level_out}${normal}"

  # Set fatal background color
  if [[ "${write_log_level}" ==  "fatal" ]]; then
    write_log_level_out="${bg_color}${write_log_level_out}${normal}"  
  fi

  # Get the date and time format
  local date_time
  date_time=$(date +"%Y-%m-%dT%H:%M:%S%:z")

  # Create the message  
  message="${write_log_level_out}[${date_time}] ${msg}"

  if [[ "${out}" == "stderr" ]]; then
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}" 1>&2
    else
      echo "${message}" 1>&2
    fi

  else
    if [[ "${print}" == "printf" ]]; then
      # shellcheck disable=SC2059
      printf "${message}"
    else
      echo "${message}"
    fi
  fi
}

#------------------------------ Public Functions ------------------------------

function lb_debugf(){
  _lb_log_msg debug printf "${*}"
}

function lb_infof(){
  _lb_log_msg info printf "${*}"
}

function lb_warnf(){
  _lb_log_msg warn printf "${*}"
}

function lb_errorf(){
  _lb_log_msg error printf "${*}"
}

function lb_fatalf(){
  _lb_log_msg fatal printf "${*}"
}

function lb_debugln(){
  _lb_log_msg debug echo "${*}"
}

function lb_infoln(){
  _lb_log_msg info echo "${*}"
}

function lb_warnln(){
  _lb_log_msg warn echo "${*}"
}

function lb_errorln(){
  _lb_log_msg error echo "${*}"
}

function lb_fatalln(){
  _lb_log_msg fatal echo "${*}"
}