# bash # # Copyright (c) 2022 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # if [[ -z "$__LOG_UTILS_INCLUDED" ]] ; then __LOG_UTILS_INCLUDED=1 # # Usage: dump_stack [FRAME_OFFSET] # dump_stack() { local -i index local -i max_index="${#BASH_SOURCE[@]}" local -a line_numbers=($LINENO "${BASH_LINENO[@]}") for ((index=${1:-0}; index < max_index; ++index)) { echo " at ${BASH_SOURCE[$index]} line ${line_numbers[$index]}" } } # # Usage: print_log [OPTIONS...] LINES... # # Print a log message; each LINE is printed on a separate line and should # be quoted in scripts. # # --dump-stack include stack trace in output # --frame-offset=N frame offset for stack trace (default: 0) # --prefix=PREFIX include PREFIX in front of each LINE # --location include caller function name in front of each LINE # --epilog=EPILOG include EPILOG in output # --loud be loud # -i,--increment-frame-offset # add one to frame-offset (additive) # # --error set --prefix --loud + TTY codes as necessary # --warning --warn # --notice # --info # __print_log_usage() { local func="${FUNCNAME[1]}" echo " ################################################################################ ERROR: ${func}: invalid syntax $(dump_stack 2) Usage: $func [OPTIONS...] LINES... See ${BASH_SOURCE[0]} near line ${LINENO} for more info. ################################################################################ " } print_log() { ( set +x local -i frame_offset=1 local -i frame_offset_offset=0 local -i dump_stack_frame_offset local -i dump_stack=0 local line_prefix local epilog local -i include_location=0 local loud local loud_prefix loud_suffix local loud_line_prefix local preset_line_prefix # color codes local tty_error tty_warning tty_notice tty_info local tty_on tty_off if [[ -t 1 ]] ; then tty_error=$'\033[1;31m' tty_warning=$'\033[0;33m' tty_notice=$'\033[0;32m' tty_off=$'\033[0m' fi # parse command line local opts local -a rsync_opts opts="$(\ getopt -n "${FUNCNAME[0]}" -o "+i" \ -l dump-stack \ -l frame-offset: \ -l increment-frame-offset \ -l prefix: \ -l location\ -l epilog: \ -l loud \ -l error \ -l warning -l warn \ -l notice \ -l info \ -- "$@" )" if [[ $? -ne 0 ]] ; then __print_log_usage exit 1 fi eval set -- "${opts}" while true ; do case "$1" in --dump-stack) dump_stack=1 shift ;; --frame-offset) frame_offset="$2" shift 2 ;; -i | --increment-frame-offset) let ++frame_offset_offset shift ;; --prefix) line_prefix="$2" shift 2 ;; --location) include_location=1 shift ;; --epilog) epilog="$2" shift 2 ;; --loud) loud="yes" shift ;; --error) loud="yes" preset_line_prefix='ERROR: ' tty_on="$tty_error" shift ;; --warning | --warn) loud="yes" preset_line_prefix='WARNING: ' tty_on="$tty_warning" shift ;; --notice) loud="yes" tty_on="$tty_notice" shift ;; --info) preset_line_prefix='# ' shift ;; --) shift break ;; -*) __print_log_usage exit 1 ;; *) break ;; esac done if [[ "$#" -lt 1 ]] ; then __print_log_usage exit 1 fi if [[ -z "$line_prefix" ]] ; then line_prefix="$preset_line_prefix" fi if [[ "$loud" = "yes" ]] ; then local nl=$'\n' loud_line_prefix=$'### ' loud_prefix="${nl}${nl}${loud_line_prefix}${nl}" loud_suffix="${loud_line_prefix}${nl}${nl}" fi let frame_offset+=frame_offset_offset local location if [[ $include_location -eq 1 ]] ; then local -i funcname_index=$frame_offset local func="${FUNCNAME[$funcname_index]}" if [[ -n "$func" && "$func" != "main" ]] ; then location="$func: " fi fi echo -n "$loud_prefix" while [[ "$#" -gt 0 ]] ; do local line="$1" ; shift || true echo "${loud_line_prefix}${location}${tty_on}${line_prefix}${line}${tty_off}" done shift || true if [[ $dump_stack -eq 1 ]] ; then let dump_stack_frame_offset=frame_offset+1 dump_stack $dump_stack_frame_offset | awk -v PREFIX="${loud_line_prefix}" -v SUFFIX="" '{print PREFIX, $0, SUFFIX}' fi if [[ -n "$epilog" ]] ; then echo -n "$epilog" fi echo -n "$loud_suffix" ) >&2 } fi # include guard