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  }