diff options
Diffstat (limited to 'subr.rtl/rtl_log.subr')
-rw-r--r-- | subr.rtl/rtl_log.subr | 200 |
1 files changed, 163 insertions, 37 deletions
diff --git a/subr.rtl/rtl_log.subr b/subr.rtl/rtl_log.subr index 3a7560a5..69e620bf 100644 --- a/subr.rtl/rtl_log.subr +++ b/subr.rtl/rtl_log.subr @@ -1,88 +1,214 @@ # +# Copyright (c) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 LucĂa Andrea Illanes Albornoz <lucia@luciaillanes.de> # set +o errexit -o noglob -o nounset is assumed. # # -# Private globals and subroutines +# Private globals # RTLP_LOG_FNAME=""; RTLP_LOG_NO_ATTR=0; RTLP_LOG_TAGS=""; +RTLP_LOG_TERMINAL_COLOURS="$(tput colors 2>/dev/null)"; -rtlp_log_printf() { - local _attr="${1}" _fmt_pfx="${2}" _fmt="${3#*;}" _fmt_argc="${3%%;*}"; shift 3; - if [ "${#}" -ne "${_fmt_argc}" ]; then - if [ "${_fmt_argc}" -eq 0 ]; then +# +# Private subroutines +# + +# +# rtlp_log_msg_get_attr() - get attributes e.g. ANSI escape sequences for single log tag +# @_rattr: out reference to attributes e.g. ANSI escape sequences +# @_tag: tag to log message at +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtlp_log_msg_get_attr() { + local _rplmga_rattr="${1#\$}" _rplmga_tag="${2}" \ + _rplmga_attr="" _rplmga_attr_state="" \ + _rplmga_term_colour=0; + + if [ "${RTLP_LOG_TERMINAL_COLOURS}" = 256 ]; then + set -- 256 ""; + else + set -- ""; + fi; + + for _rplmga_term_colour in "${@}"; do + eval _rplmga_attr='${LOG_TAG_'"${_rplmga_tag}${_rplmga_term_colour:+_${_rplmga_term_colour}}"':-}'; + + if [ "${_rplmga_attr:+1}" = 1 ]; then + break; + else + eval _rplmga_attr_state='${RTLP_ATTR_STATE_'"${_rplmga_tag}"':-}'; + if [ "${_rplmga_attr_state:+1}" != 1 ]; then + _rplmga_attr_state=0; + else + : $((_rplmga_attr_state += 1)); + fi; + eval "RTLP_ATTR_STATE_${_rplmga_tag}=${_rplmga_attr_state}"; + + if [ "$((${_rplmga_attr_state} % 2))" -eq 0 ]; then + eval _rplmga_attr='${LOG_TAG_'"${_rplmga_tag}"'_even'"${_rplmga_term_colour:+_${_rplmga_term_colour}}"':-}'; + else + eval _rplmga_attr='${LOG_TAG_'"${_rplmga_tag}"'_odd'"${_rplmga_term_colour:+_${_rplmga_term_colour}}"':-}'; + fi; + + if [ "${_rplmga_attr:+1}" = 1 ]; then + break; + fi; + fi; + done; + + eval ${_rplmga_rattr}='${_rplmga_attr}'; + return 0; +}; + +# +# rtlp_log_printfV() - print single message to log file +# @_attr: attributes e.g. ANSI escape sequences to log message with +# @_fmt_pfx: printf(1) format string prefix +# @_fmt: printf(1) format string +# @...: parameters to printf(1) w/ @_fmt +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtlp_log_printfV() { + local _rplp_attr="${1}" _rplp_fmt_pfx="${2}" \ + _rplp_fmt="${3#*;}" _rplp_fmt_argc="${3%%;*}"; + shift 3; + + if [ "${#}" -ne "${_rplp_fmt_argc}" ]; then + if [ "${_rplp_fmt_argc}" -eq 0 ]; then shift "${#}"; else - rtlp_log_printf "" "" "0;==> [4;41;97mFIXME TODO XXX MESSAGE STRING ARGUMENT COUNT MISMATCH[0m\n"; + rtlp_log_printfV "" "" "0;==> [4;41;97mFIXME TODO XXX MESSAGE STRING ARGUMENT COUNT MISMATCH[0m\n"; fi; fi; - _msg="$(printf "${_fmt_pfx}${_fmt}" "${@}")"; + _rplp_msg="$(printf "${_rplp_fmt_pfx}${_rplp_fmt}" "${@}")"; - if [ -n "${RTLP_LOG_FNAME}" ]; then - printf "%s\n" "${_msg}" >> "${RTLP_LOG_FNAME}"; + if [ "${RTLP_LOG_FNAME:+1}" = 1 ]; then + printf "%s\n" "${_rplp_msg}" >> "${RTLP_LOG_FNAME}"; fi; if [ "${RTLP_LOG_NO_ATTR:-0}" -eq 0 ]; then - printf "\033[0m\033[${_attr}m%s\033[0m\n" "${_msg}"; + printf "\033[0m\033[${_rplp_attr}m%s\033[0m\n" "${_rplp_msg}"; else - printf "%s\n" "${_msg}"; - fi; return 0; + printf "%s\n" "${_rplp_msg}"; + fi; + return 0; }; # # Public subroutines # +# +# rtl_log_clear_tags() - clear all log tags +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_log_clear_tags() { - RTLP_LOG_TAGS=""; return 0; + RTLP_LOG_TAGS=""; + return 0; }; -rtl_log_enable_tags() { +# +# rtl_log_enable_tagsV() - enable log tags +# @...: list of tags to enable as positional parameters +# +# Returns: zero (0) on success, non-zero (>0) on failure +# +rtl_log_enable_tagsV() { local IFS=","; set -- ${*}; + while [ "${#}" -gt 0 ]; do - if ! rtl_lmatch "${RTLP_LOG_TAGS}" "${1}" ","; then + if ! rtl_lmatch \$RTLP_LOG_TAGS "${1}" ","; then RTLP_LOG_TAGS="${RTLP_LOG_TAGS:+${RTLP_LOG_TAGS},}${1}"; fi; shift; - done; return 0; + done; + return 0; }; +# +# rtl_log_env_vars() - log all environment variables to log file +# @_tag: tag to log environment variables at +# @_type: type string printed in log message header +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_log_env_vars() { - local _tag="${1}" _type="${2}" _arg_len_max=0; shift 2; + local _rlev_tag="${1}" _rlev_type="${2}" \ + _rlev_arg_len_max=0 _rlev_list="" _rlev_msg="" _rlev_msg_=""; + shift 2; - rtl_log_msg "${_tag}" "${MSG_rtl_log_vars_header}" "${_type}"; - _arg_len_max="$(rtl_lmax "${@}")"; + rtl_log_msgV "${_rlev_tag}" "${MSG_rtl_log_vars_header}" "${_rlev_type}"; + _rlev_list="${@}"; rtl_lmax \$_rlev_list \$_rlev_arg_len_max; while [ "${#}" -gt 0 ]; do - rtl_log_msg "${_tag}" \ - "2;%${_arg_len_max}.${_arg_len_max}s=%s" \ - "${1%%=*}" "$(rtl_get_var_unsafe "${1#*=}")"; + rtl_get_var_unsafe \$_rlev_msg "${1#*=}"; + rtl_llift2 \$_rlev_msg \$_rlev_msg_ "" " "; + rtl_log_msgV "${_rlev_tag}" \ + "2;%${_rlev_arg_len_max}.${_rlev_arg_len_max}s=%s" \ + "${1%%=*}" "${_rlev_msg_}"; shift; - done; return 0; + done; + return 0; }; -rtl_log_msg() { - local _tag="${1}" _fmt="${2}" _attr="" _exitfl=0; shift 2; +# +# rtl_log_msgV() - log message to log file +# @_tag: tag to log message at +# @_fmt: printf(1) format string +# @...: parameters to printf(1) w/ @_fmt +# +# Returns: zero (0) on success, non-zero (>0) on failure +# N.B.: Optional attributes e.g. ANSI escape sequences w/ which the the log message is to +# be printed are taken from the variable corresponding to @_tag named "LOG_TAG_<@_tag>", +# if present/set. +# +# @_tag must have previously been enabled w/ rtl_log_enable_tagsV() to be logged at all. +# +rtl_log_msgV() { + local _rlm3_tag="${1}" _rlm3_fmt="${2}" \ + _rlm3_attr="" _rlm3_date_now=0 _rlm3_exitfl=0 + shift 2; - [ "x${_tag}" = "xfatalexit" ] && { _tag="fatal"; _exitfl=1; }; - if rtl_lmatch "${RTLP_LOG_TAGS}" "${_tag}" ","; then - eval _attr='${LOG_TAG_'"${_tag}"':-}'; - if [ "${#_attr}" -eq 0 ]; then - rtlp_log_printf "" "" "0;==> [4;41;97mFIXME TODO XXX UNKNOWN TAG \`${_tag}' PASSED TO rtl_log_msg()[0m\n"; - fi; - rtlp_log_printf "${_attr}" "==> $(rtl_date) " "${_fmt}" "${@}"; - if [ "${_exitfl}" -eq 1 ]; then + if [ "x${_rlm3_tag}" = "xfatalexit" ]; then + _rlm3_tag="fatal"; _rlm3_exitfl=1; + fi; + + if [ "${_rlm3_tag}" = "fatal" ]\ + || rtl_lmatch \$RTLP_LOG_TAGS "${_rlm3_tag}" ","; + then + rtlp_log_msg_get_attr \$_rlm3_attr "${_rlm3_tag}"; + rtl_date \$_rlm3_date_now; + rtlp_log_printfV "${_rlm3_attr}" "==> ${_rlm3_date_now} " "${_rlm3_fmt}" "${@}"; + if [ "${_rlm3_exitfl}" -eq 1 ]; then exit 1; fi; - fi; return 0; + fi; + return 0; }; +# +# rtl_log_set_fname() - set log file pathname +# @_fname: pathname to new log file +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_log_set_fname() { - RTLP_LOG_FNAME="${1}"; return 0; + RTLP_LOG_FNAME="${1}"; + return 0; }; +# +# rtl_log_set_no_attr() - set or clear no ANSI escape sequences in log file flag +# @_flag: either 0 to set or 1 to clear no ANSI escape sequences in log file flag +# +# Returns: zero (0) on success, non-zero (>0) on failure +# rtl_log_set_no_attr() { - RTLP_LOG_NO_ATTR="${1}"; return 0; + RTLP_LOG_NO_ATTR="${1}"; + return 0; }; -# vim:filetype=sh +# vim:filetype=sh textwidth=0 |