github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/scripts/lib/logging.sh (about) 1 #!/usr/bin/env bash 2 3 # Copyright 2014 The Kubernetes Authors. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 # Controls verbosity of the script output and logging. 18 KUBE_VERBOSE="${KUBE_VERBOSE:-5}" 19 20 # Handler for when we exit automatically on an error. 21 # Borrowed from https://gist.github.com/ahendrix/7030300 22 kube::log::errexit() { 23 local err="${PIPESTATUS[*]}" 24 25 # If the shell we are in doesn't have errexit set (common in subshells) then 26 # don't dump stacks. 27 set +o | grep -qe "-o errexit" || return 28 29 set +o xtrace 30 local code="${1:-1}" 31 # Print out the stack trace described by $function_stack 32 if [ ${#FUNCNAME[@]} -gt 2 ] 33 then 34 kube::log::error "Call tree:" 35 for ((i=1;i<${#FUNCNAME[@]}-1;i++)) 36 do 37 kube::log::error " ${i}: ${BASH_SOURCE[${i}+1]}:${BASH_LINENO[${i}]} ${FUNCNAME[${i}]}(...)" 38 done 39 fi 40 kube::log::error_exit "Error in ${BASH_SOURCE[1]}:${BASH_LINENO[0]}. '${BASH_COMMAND}' exited with status ${err}" "${1:-1}" 1 41 } 42 43 kube::log::install_errexit() { 44 # trap ERR to provide an error handler whenever a command exits nonzero this 45 # is a more verbose version of set -o errexit 46 trap 'kube::log::errexit' ERR 47 48 # setting errtrace allows our ERR trap handler to be propagated to functions, 49 # expansions and subshells 50 set -o errtrace 51 } 52 53 # Print out the stack trace 54 # 55 # Args: 56 # $1 The number of stack frames to skip when printing. 57 kube::log::stack() { 58 local stack_skip=${1:-0} 59 stack_skip=$((stack_skip + 1)) 60 if [[ ${#FUNCNAME[@]} -gt ${stack_skip} ]]; then 61 echo "Call stack:" >&2 62 local i 63 for ((i=1 ; i <= ${#FUNCNAME[@]} - stack_skip ; i++)) 64 do 65 local frame_no=$((i - 1 + stack_skip)) 66 local source_file=${BASH_SOURCE[${frame_no}]} 67 local source_lineno=${BASH_LINENO[$((frame_no - 1))]} 68 local funcname=${FUNCNAME[${frame_no}]} 69 echo " ${i}: ${source_file}:${source_lineno} ${funcname}(...)" >&2 70 done 71 fi 72 } 73 74 # Log an error and exit. 75 # Args: 76 # $1 Message to log with the error 77 # $2 The error code to return 78 # $3 The number of stack frames to skip when printing. 79 kube::log::error_exit() { 80 local message="${1:-}" 81 local code="${2:-1}" 82 local stack_skip="${3:-0}" 83 stack_skip=$((stack_skip + 1)) 84 85 if [[ ${KUBE_VERBOSE} -ge 4 ]]; then 86 local source_file=${BASH_SOURCE[${stack_skip}]} 87 local source_line=${BASH_LINENO[$((stack_skip - 1))]} 88 echo "!!! Error in ${source_file}:${source_line}" >&2 89 [[ -z ${1-} ]] || { 90 echo " ${1}" >&2 91 } 92 93 kube::log::stack ${stack_skip} 94 95 echo "Exiting with status ${code}" >&2 96 fi 97 98 exit "${code}" 99 } 100 101 # Log an error but keep going. Don't dump the stack or exit. 102 kube::log::error() { 103 timestamp=$(date +"[%m%d %H:%M:%S]") 104 echo "!!! ${timestamp} ${1-}" >&2 105 shift 106 for message; do 107 echo " ${message}" >&2 108 done 109 } 110 111 # Print an usage message to stderr. The arguments are printed directly. 112 kube::log::usage() { 113 echo >&2 114 local message 115 for message; do 116 echo "${message}" >&2 117 done 118 echo >&2 119 } 120 121 kube::log::usage_from_stdin() { 122 local messages=() 123 while read -r line; do 124 messages+=("${line}") 125 done 126 127 kube::log::usage "${messages[@]}" 128 } 129 130 # Print out some info that isn't a top level status line 131 kube::log::info() { 132 local V="${V:-0}" 133 if [[ ${KUBE_VERBOSE} < ${V} ]]; then 134 return 135 fi 136 137 for message; do 138 echo "${message}" 139 done 140 } 141 142 # Just like kube::log::info, but no \n, so you can make a progress bar 143 kube::log::progress() { 144 for message; do 145 echo -e -n "${message}" 146 done 147 } 148 149 kube::log::info_from_stdin() { 150 local messages=() 151 while read -r line; do 152 messages+=("${line}") 153 done 154 155 kube::log::info "${messages[@]}" 156 } 157 158 # Print a status line. Formatted to show up in a stream of output. 159 kube::log::status() { 160 local V="${V:-0}" 161 if [[ ${KUBE_VERBOSE} < ${V} ]]; then 162 return 163 fi 164 165 timestamp=$(date +"[%m%d %H:%M:%S]") 166 echo "+++ ${timestamp} ${1}" 167 shift 168 for message; do 169 echo " ${message}" 170 done 171 }