#!/bin/bash # Authors: Dalibor Pospíšil # Author: Dalibor Pospisil # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # # Copyright (c) 2013 Red Hat, Inc. All rights reserved. # # This copyrighted material is made available to anyone wishing # to use, modify, copy, or redistribute it subject to the terms # and conditions of the GNU General Public License version 2. # # This program is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # library-prefix = Log # library-version = 11 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __INTERNAL_Log_LIB_VERSION=11 : <<'=cut' =pod =head1 NAME BeakerLib library Log =head1 DESCRIPTION This library provide logging capability which does not rely on beakerlib so it can be used standalone. If it is used within beakerlib it automatically bypass all messages to the beakerlib. Also this library provide journaling feature so the summary can be printed out at the end. =head1 USAGE To use this functionality you need to import library distribution/Log and add following line to Makefile. @echo "RhtsRequires: library(distribution/Log)" >> $(METADATA) =head1 FUNCTIONS =cut echo -n "loading library Log v$__INTERNAL_Log_LIB_VERSION... " __INTERNAL_Log_prefix='' __INTERNAL_Log_prefix2='' __INTERNAL_Log_postfix='' __INTERNAL_Log_default_level=3 __INTERNAL_Log_level=$__INTERNAL_Log_default_level LogSetDebugLevel() { if [[ -n "$1" ]]; then if [[ "$1" =~ ^[0-9]+$ ]]; then let __INTERNAL_Log_level=$__INTERNAL_Log_default_level+$1; else __INTERNAL_Log_level=255 fi else __INTERNAL_Log_level=$__INTERNAL_Log_default_level fi } LogSetDebugLevel "$DEBUG" let __INTERNAL_Log_level_LOG=0 let __INTERNAL_Log_level_FATAL=0 let __INTERNAL_Log_level_ERROR=1 let __INTERNAL_Log_level_WARNING=2 let __INTERNAL_Log_level_INFO=3 let __INTERNAL_Log_level_DEBUG=4 let __INTERNAL_Log_level_MORE=5 let __INTERNAL_Log_level_MORE_=$__INTERNAL_Log_level_MORE+1 let __INTERNAL_Log_level_MORE__=$__INTERNAL_Log_level_MORE_+1 let __INTERNAL_Log_level_MORE___=$__INTERNAL_Log_level_MORE__+1 # Log ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ Log() { LogMore___ -f "begin '$*'" local pri=$2 message="${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}" if [[ -n "$pri" ]]; then LogPrintMessage "$pri" "$message" LogjAddMessage "$pri" "$message" else LogPrintMessage "$(date +%H:%M:%S)" "$message" LogjAddMessage "INFO" "$message" fi LogMore___ -f "end" return 0 }; # end of Log }}} __INTERNAL_Log_condition() { cat <&2 return 0 }; # end of LogPrintMessage }}} # LogReport ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ : <<'=cut' =pod =head3 LogReport Prints final report similar to breakerlib's rlJournalPrintText. This is useful mainly if you use TCF without beakerlib. LogReport =cut #' LogReport() { echo -e "\n ====== Summary report begin ======" local a p l i for i in $(seq 0 2 $((${#__INTERNAL_Log_journal[@]}-1)) ); do LogPrintMessage "${__INTERNAL_Log_journal[$i]}" "${__INTERNAL_Log_journal[$((++i))]}" done echo " ======= Summary report end =======" __INTERNAL_Log_journal=() }; # end of LogReport }}} # LogFile ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ LogFile() { LogMore__ -f "begin '$*'" local prio='' [[ $# -ge 3 ]] && { optsBegin optsAdd 'prio|tag|p|t' --mandatory optsDone; eval "${optsCode}" } cat $1 | while IFS= read line; do Log "$line" "${prio:-$2}" done LogMore__ -f "end" }; #}}} # LogText ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ LogText() { LogMore__ -f "begin '$*'" local prio='' [[ $# -ge 3 ]] && { optsBegin optsAdd 'prio|tag|p|t' --mandatory optsDone; eval "${optsCode}" } { if [[ "$1" == "-" ]]; then cat - else echo "$1" fi } | while IFS= read line; do Log "$line" "${prio:-$2}" done LogMore__ -f "end" }; #}}} # LogStrippedDiff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ LogStrippedDiff() { LogMore__ -f "begin '$*'" local prio='' [[ $# -ge 3 ]] && { optsBegin optsAdd 'prio|tag|p|t' --mandatory optsDone; eval "${optsCode}" } { if [[ -n "$2" ]]; then diff -U0 "$1" "$2" else cat $1 fi } | grep -v -e '^@@ ' -e '^--- ' -e '^+++ ' | while IFS= read line; do Log "$line" "$prio" done LogMore__ -f "end" }; #}}} # LogRun ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ # log info about execution to Debug level LogRun() { local pref='' [[ "$1" =~ ^-f([0-9]*) ]] && { shift pref="-f$((${BASH_REMATCH[1]:-1}+1))" } LogMore local dolog=$? [[ $dolog -eq 0 ]] || { local param params blacklist="[[:space:]]|>|<|\|" [[ "${#@}" -eq 1 ]] && params="$1" || { for param in "$@"; do if [[ "$param" =~ $blacklist ]]; then params="$params \"${param//\"/\\\"}\"" else params="$params $param" fi done params="${params:1}" } LogDo $pref "executing >>>>> ${params} <<<<<" } eval "$@" ret=$? [[ $dolog -eq 0 ]] || LogMore $pref "execution >>>>> ${params} <<<<< returned '$ret'" return $ret }; # end of LogRun }}} # LogDebugNext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ # log info about execution to Debug level LogDebugNext() { local pref='' [[ "$1" =~ ^-f([0-9]*) ]] && { shift pref="-f$((${BASH_REMATCH[1]:-1}))" } LogDebug '' ${1:-$__INTERNAL_Log_level_DEBUG} || { __INTERNAL_Log_DEBUGING=0 trap " __INTERNAL_Log_DEBUGING_res=\$? let __INTERNAL_Log_DEBUGING++ if [[ \$__INTERNAL_Log_DEBUGING -eq 1 ]]; then __INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\" LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG} else trap - DEBUG LogDebug $pref \"execution >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<< returned \$__INTERNAL_Log_DEBUGING_res\" ${1:-$__INTERNAL_Log_level_DEBUG} fi" DEBUG } }; # end of LogDebugNext }}} # LogMoreNext ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ # log info about execution to Debug level LogMoreNext() { LogMore || { local pref='' [[ "$1" =~ ^-f([0-9]*) ]] && { shift pref="-f$((${BASH_REMATCH[1]:-1}))" } LogDebugNext $pref ${1:-$__INTERNAL_Log_level_MORE} } }; # end of LogMoreNext }}} LogNext() { LogMoreNext "$@" } # LogDebugOn ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ # log info about execution to Debug level LogDebugOn() { local pref='' [[ "$1" =~ ^-f([0-9]*) ]] && { shift pref="-f$((${BASH_REMATCH[1]:-1}))" } LogDebug '' ${1:-$__INTERNAL_Log_level_DEBUG} || { trap " __INTERNAL_Log_DEBUGING_res=\$? let __INTERNAL_Log_DEBUGING++ if [[ -z \"\$__INTERNAL_Log_DEBUGING_cmd\" ]]; then __INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\" LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG} else LogDebug $pref \"execution >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<< returned \$__INTERNAL_Log_DEBUGING_res\" ${1:-$__INTERNAL_Log_level_DEBUG} __INTERNAL_Log_DEBUGING_cmd=\"\$BASH_COMMAND\" if [[ \"\$__INTERNAL_Log_DEBUGING_cmd\" =~ LogDebugOff ]]; then trap - DEBUG else LogDebug $pref \"executing >>>>> \$__INTERNAL_Log_DEBUGING_cmd <<<<<\" ${1:-$__INTERNAL_Log_level_DEBUG} fi fi" DEBUG } }; # end of LogDebugOn }}} # LogMoreOn ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ # log info about execution to Debug level LogMoreOn() { LogMore || { local pref='' [[ "$1" =~ ^-f([0-9]*) ]] && { shift pref="-f$((${BASH_REMATCH[1]:-1}))" } LogDebugOn $pref ${1:-$__INTERNAL_Log_level_MORE} } }; # end of LogMoreOn }}} # LogDebugOff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ # log info about execution to Debug level LogDebugOff() { __INTERNAL_Log_DEBUGING_cmd='' }; # end of LogDebugOff }}} # LogVar ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ LogVar() { [[ -n "$DEBUG" ]] && { echo -n 'eval ' while [[ -n "$1" ]]; do echo -n "LogDebug -f \"\$(set | grep -P '^$1=')\";" shift done } }; # end of LogVar }}} # __INTERNAL_LogRedirectToBeakerlib ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ __INTERNAL_LogRedirectToBeakerlib() { echo -e "\nrunning inside the beakerlib - redirect own logging functions to beakerlib ones" true; LogjAddMessage() { LogMore___ -f "begin $*" rljAddMessage "$2" "$1" LogMore___ -f "end $*" } true; Log() { LogMore___ -f "begin $*" case ${2} in INFO) LogjAddMessage "INFO" "$1" LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}" ;; BEGIN) LogjAddMessage "INFO" "$*:" LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}" ;; WARNING|WARN|ERROR|FATAL) LogjAddMessage "WARNING" "$1" LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}" ;; SKIP|SKIPPING) LogjAddMessage "WARNING" "$*:" LogPrintMessage "$2" "${__INTERNAL_Log_prefix}${__INTERNAL_Log_prefix2}${1}${__INTERNAL_Log_postfix}" ;; FAIL) rlFail "$*" return $? ;; PASS) rlPass "$*" return $? ;; *) rlLog "$*" ;; esac LogMore___ -f "end $*" return 0; } } # end of __INTERNAL_LogRedirectToBeakerlib }}} # LogLibraryLoaded ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ {{{ LogLibraryLoaded() { declare -F rlDie > /dev/null && __INTERNAL_LogRedirectToBeakerlib return 0 }; # end of LogLibraryLoaded }}} echo "done." : <<'=cut' =pod =head1 AUTHORS =over =item * Dalibor Pospisil =back =cut