代码拉取完成,页面将自动刷新
# vim:et:ft=sh:sts=2:sw=2
#
# Copyright 2008-2018 Kate Ward. All Rights Reserved.
# Released under the Apache License 2.0 license.
#
# Logging framework 4 SHell scripts
# https://github.com/kward/log4sh
#
# Author: [email protected] (Kate Ward)
#
# This module implements something like the log4j module from the Apache group.
# return if log4sh already loaded
[ -z "${LOG4SH_VERSION:-}" ] || return
LOG4SH_VERSION='1.5.1pre'
#
# constants
#
LOG4SH_TRUE=0
LOG4SH_FALSE=1
LOG4SH_ERROR=2
[ -z "${LOG4SH_LOG_FILE:-}" ] && LOG4SH_LOG_FILE=''
__LOG4SH_LOGGER_ROOT='root'
__LOG4SH_LEVEL_TRACE='TRACE'
__LOG4SH_LEVEL_DEBUG='DEBUG'
__LOG4SH_LEVEL_INFO='INFO'
__LOG4SH_LEVEL_WARN='WARN'
__LOG4SH_LEVEL_ERROR='ERROR'
__LOG4SH_LEVEL_FATAL='FATAL'
__LOG4SH_KV_TYPE='type'
#
# global variables -- see also log4sh_resetConfiguration()
#
__log4sh_appenders='' # list of valid appenders
__log4sh_dictFile='' # internal dictionary of key/value pairs
__log4sh_tmpDir='' # temporary directory
__log4sh_trapsFile='' # previously defined traps
#
# macros
#
_LOG4SH_LINENO_='eval log4sh_lineno_=""; if [ "${1:-}" = "--lineno" ]; then [ -n "$2" ] && log4sh_lineno_="$2"; shift 2; fi'
# wrappers for interal logging to include line numbers
_LOG4SH_DEBUG_='eval _log4sh_debug --lineno "${LINENO:-}"'
_LOG4SH_INFO_='eval _log4sh_info --lineno "${LINENO:-}"'
_LOG4SH_ERROR_='eval _log4sh_error --lineno "${LINENO:-}"'
# Split fully qualified [logger.]appender string and set local variables.
#
# This function sets the following variables:
# log4sh_logger_: string: logger name; empty if none
# log4sh_appender_: string: appender name
#
# Args:
# fqla: string: fully qualified [logger.]appender
_LOG4SH_SPLIT_LOGGER_APPENDER_='eval expr "$1" : ".*\..*" >/dev/null; if [ $? -eq 0 ]; then log4sh_logger_=`expr "$1" : "\(.*\)\..*"`; log4sh_appender_=`expr "$1" : ".*\.\(.*\)"`; else log4sh_logger_=${__LOG4SH_LOGGER_ROOT}; log4sh_appender_=$1; fi; log4sh_fqAppender_="${log4sh_logger_}.${log4sh_appender_}"; shift'
_LOG4SH_CLEANUP_LOGGER_APPENDER_='eval unset log4sh_appender_ log4sh_fqAppender_ log4sh_logger_'
#-----------------------------------------------------------------------------
# log4sh functions
#
# Common logging function for log4sh itself.
#
# Args:
# level: string: logging level (e.g. INFO)
# message: string: message to log
_log4sh_log()
{
_log4sh_lineno_=$1
_log4sh_level_=$2
shift 2
[ -n "${_log4sh_lineno_:-}" ] && _log4sh_lineno_="[${_log4sh_lineno_}]"
_log4sh_message_="${_log4sh_level_}${_log4sh_lineno_} $@"
if [ -z "${LOG4SH_LOG_FILE}" ]; then
echo "log4sh:${_log4sh_message_}" >&2
else
echo "${_log4sh_message_}" >>"${LOG4SH_LOG_FILE}"
fi
unset _log4sh_level_ _log4sh_lineno_ _log4sh_message_
}
# DEBUG level logging function for log4sh.
#
# Args:
# message: string: message to log
_log4sh_debug()
{
${_LOG4SH_LINENO_}
_log4sh_log "${log4sh_lineno_}" ${__LOG4SH_LEVEL_DEBUG} "$@"
unset log4sh_lineno_
}
# INFO level logging function for log4sh.
#
# Args:
# message: string: message to log
_log4sh_info()
{
${_LOG4SH_LINENO_}
_log4sh_log "${log4sh_lineno_}" ${__LOG4SH_LEVEL_INFO} "$@"
unset log4sh_lineno_
}
# ERROR level logging function for log4sh.
#
# Args:
# message: string: message to log
_log4sh_error()
{
${_LOG4SH_LINENO_}
_log4sh_log "${log4sh_lineno_}" ${__LOG4SH_LEVEL_ERROR} "$@"
unset log4sh_lineno_
}
# Cleanup function to remove the temporary directory used by log4sh.
#
# If there was a previously defined trap for the given signal, log4sh will
# attempt to call the original trap handler as well so as not to break the
# parent script.
#
# Args:
# trap: string: a trap signal (e.g. EXIT)
_log4sh_cleanup()
{
_log4sh_trap_=$1
_log4sh_restoreTrap_=${LOG4SH_FALSE}
_log4sh_oldTrap_=''
# match trap to signal value
case "${_log4sh_trap_}" in
EXIT) _log4sh_signal_=0 ;;
INT) _log4sh_signal_=2 ;;
TERM) _log4sh_signal_=15 ;;
esac
# do we possibly need to restore a previous trap?
if [ -r "${__log4sh_trapsFile}" -a -s "${__log4sh_trapsFile}" ]; then
# yes. figure out what we need to do
if [ `grep "^trap -- " "${__log4sh_trapsFile}" >/dev/null; echo $?` -eq 0 ]
then
# newer trap command
${_LOG4SH_DEBUG_} 'newer POSIX trap command'
_log4sh_restoreTrap_=${LOG4SH_TRUE}
_log4sh_oldTrap_=`egrep "(${_log4sh_trap_}|${_log4sh_signal_})$" \
"${__log4sh_trapsFile}" |sed "s/^trap -- '\(.*\)' [A-Z]*$/\1/"`
elif [ `grep "[0-9]*: " "${__log4sh_trapsFile}" >/dev/null; echo $?` -eq 0 ]
then
# older trap command
${_LOG4SH_DEBUG_} 'older style trap command'
_log4sh_restoreTrap_=${LOG4SH_TRUE}
_log4sh_oldTrap_=`grep "^${_log4sh_signal_}: " "${__log4sh_trapsFile}" |\
sed 's/^[0-9]*: //'`
else
# unrecognized trap output
_log4sh_error 'unable to restore old traps! unrecognized trap command output'
fi
fi
# do our work
rm -fr "${__log4sh_tmpDir}"
# execute the old trap
if [ ${_log4sh_restoreTrap_} -eq ${LOG4SH_TRUE} -a -n "${_log4sh_oldTrap_}" ]
then
${_LOG4SH_DEBUG_} "'restoring previous trap for (${_log4sh_trap_}) signal'"
eval "${_log4sh_oldTrap_}"
fi
# exit for all non-EXIT signals
if [ "${_log4sh_trap_}" != 'EXIT' ]; then
${_LOG4SH_WARN_} "'trapped and now handling the (${_log4sh_trap}) signal'"
# disable the EXIT trap
trap 0
# add 128 to signal value and exit
_log4sh_signal=`expr ${_log4sh_signal_} + 128`
exit ${_log4sh_signal_}
fi
unset _log4sh_oldTrap_ _log4sh_signal_ _log4sh_restoreTrap_ _log4sh_trap_
return
}
# Create a secure temporary directory.
#
# This function honors the TMPDIR environment variable if set.
#
# Args:
# none
# Outputs:
# string: path to temporary directory
# Returns:
# integer: success of operation
_log4sh_mktempDir()
{
_log4sh_tmpPrefix_='log4sh'
# try the standard mktemp function
( exec mktemp -dqt ${_log4sh_tmpPrefix_}.XXXXXX 2>/dev/null ) && return
# the standard mktemp didn't work. doing our own.
if [ -r '/dev/urandom' ]; then
_log4sh_random_=`od -vAn -N4 -tx4 </dev/urandom |sed 's/^[^0-9a-f]*//'`
elif [ -n "${RANDOM:-}" ]; then
# $RANDOM works
_log4sh_random_=${RANDOM}${RANDOM}${RANDOM}$$
else
# could not get a random number; generating one as best we can
_log4sh_date_=`date '+%Y%m%d%H%M%S'`
_log4sh_random_=`expr ${_log4sh_date_} / $$`
unset _log4sh_date_
fi
_log4sh_tmpDir_="${TMPDIR:-/tmp}/${_log4sh_tmpPrefix_}.${_log4sh_random_}"
( umask 077 && mkdir "${_log4sh_tmpDir_}" ) || {
_log4sh_fatal 'could not create temporary directory! exiting'
exit 1
}
${_LOG4SH_DEBUG_} "'created temporary directory (${_log4sh_tmpDir_})'"
echo "${_log4sh_tmpDir_}"
unset _log4sh_random_ _log4sh_tmpDir_ _log4sh_tmpPrefix_
return ${LOG4SH_TRUE}
}
# Common appender registration.
#
# This function must be called to register an appender with the log4sh
# framework so that appender specific functionality can be used.
#
# Args:
# appender: string: name of the appender type
_log4sh_register_appender()
{
_log4sh_appender_=$1
__log4sh_appenders="${__log4sh_appenders} ${_log4sh_appender_}"
_appender_register_${_log4sh_appender_} # call registration callback
# TODO: handle failure
unset _log4sh_appender_
}
# Append an element to end of list stored in a variable.
#
# As this function is used only internally, it expects the variable to be
# present. No error checking is done.
#
# Args:
# varname: string: name of variable containing list to be appended to
# data: string: data to be appended
_log4sh_listAppend()
{
_log4sh_varName_=$1
_log4sh_newData_=$2
_log4sh_strToEval_="_log4sh_data_=\${${_log4sh_varName_}}"
eval "${_log4sh_strToEval_}"
eval ${_log4sh_varName_}="'${_log4sh_data_:+${_log4sh_data_} }${_log4sh_newData_}'"
unset _log4sh_data_ _log4sh_newData_ _log4sh_strToEval_ _log4sh_varName_
}
# Get internal dictionary value.
#
# Args:
# unnamed_key: string: dictionary key (no spaces allowed)
# Outputs:
# value: string: dictionary value
# Returns:
# integer: success of operation
_log4sh_getValue()
{
if [ $# -ne 1 ]; then
${_LOG4SH_ERROR_} "'_log4sh_getValue(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
# 0=true, 1=false
set -x
echo 'dict file:' >&2
cat "${__log4sh_dictFile}" >&2
awk 'BEGIN{found=1}$1==key{print $2;found=0}END{exit found}' key=$1 \
"${__log4sh_dictFile}"
log4sh_return=$?
set +x
return ${log4sh_return}
}
# Set internal dictionary value.
#
# Args:
# key: string: dictionary key
# value: string: dictionary value
# Returns:
# integer: success of operation
_log4sh_setValue()
{
if [ $# -ne 2 ]; then
${_LOG4SH_ERROR_} "'_log4sh_setValue(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
_log4sh_key_=$1
_log4sh_value_=$2
sed -i '' "/^${_log4sh_key_} /d" "${__log4sh_dictFile}"
echo "${_log4sh_key_} ${_log4sh_value_}" >>"${__log4sh_dictFile}"
unset _log4sh_key_ _log4sh_value_
return ${LOG4SH_TRUE} # TODO(20090216:kward): check for some errors?
}
# Add a new logger.
#
# Args:
# logger: string: name of logger
# Returns:
# integer: success of the operation
log4sh_addLogger()
{
if [ $# -ne 1 ]; then
${_LOG4SH_ERROR_} "'log4sh_addLogger(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
log4sh_logger_=$1
_logger_isValid "${log4sh_logger_}"
if [ $? -eq ${LOG4SH_FALSE} ]; then
__log4sh_loggers="${__log4sh_loggers} ${log4sh_logger_}"
eval __log4sh_logger_${log4sh_logger_}=''
log4sh_return=${LOG4SH_TRUE}
else
${_LOG4SH_ERROR_} "'logger already exists (${log4sh_logger_})'"
log4sh_return=${LOG4SH_FALSE}
fi
unset log4sh_logger_
return ${log4sh_return}
}
# Reset log4sh to initial defaults.
#
# This function leaves dangingling bits all over the place. It resets just
# enough of the environment so that log4sh forgets about its past.
#
# Args:
# none
log4sh_resetConfiguration()
{
if [ -n "${__log4sh_loggers:-}" ]; then
for log4sh_logger_ in ${__log4sh_loggers}; do
${_LOG4SH_DEBUG_} "log4sh_logger_=${log4sh_logger_}"
done
fi
cp /dev/null "${__log4sh_dictFile}" # purge dictionary
__log4sh_loggers=''
log4sh_addLogger "${__LOG4SH_LOGGER_ROOT}"
unset log4sh_logger_
}
#------------------------------------------------------------------------------
# logger functions
#
# Determine if named logger is valid.
#
# Note: if this function is called from a private function, it must be done
# inside a subshell like (...;) due to variable scoping.
#
# Args:
# logger: string: name of logger
# Returns:
# boolean: validity of logger
_logger_isValid()
{
_log4sh_logger_=$1
_log4sh_isValid_=${LOG4SH_FALSE}
for _log4sh_validLogger_ in ${__log4sh_loggers}; do
if [ "${_log4sh_logger_}" = "${_log4sh_validLogger_}" ]; then
_log4sh_isValid_=${LOG4SH_TRUE}
break
fi
done
log4sh_return=${_log4sh_isValid_}
unset _log4sh_logger_ _log4sh_isValid_ _log4sh_validLogger_
return ${log4sh_return}
}
# Add a new appender to a logger.
#
# Args:
# appender: string: name of appender
# logger: string: name of logger to add appender to (optional)
# Returns:
# integer: success of the operation
logger_addAppender()
{
if [ $# -eq 0 -o $# -gt 2 ]; then
${_LOG4SH_ERROR_} "'logger_addAppender(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
log4sh_appender_=$1
log4sh_logger_=${2:-${__LOG4SH_LOGGER_ROOT}}
( _logger_isValid "${log4sh_logger_}"; )
if [ $? -eq ${LOG4SH_TRUE} ]; then
log4sh_fqAppender_="${log4sh_logger_}.${log4sh_appender_}"
( _appender_isValid "${log4sh_fqAppender_}"; )
if [ $? -eq ${LOG4SH_FALSE} ]; then
# appender doesn't exist; add it
_log4sh_listAppend "__log4sh_logger_${log4sh_logger_}" \
"${log4sh_appender_}"
appender_setType ${log4sh_fqAppender_} ConsoleAppender
log4sh_return=${LOG4SH_TRUE}
else
${_LOG4SH_ERROR_} "'appender already exists (${log4sh_fqAppender_})'"
log4sh_return=${LOG4SH_FALSE}
fi
else
${_LOG4SH_ERROR_} "'invalid logger (${log4sh_logger_})'"
log4sh_return=${LOG4SH_FALSE}
fi
unset log4sh_appender_ log4sh_fqAppender_ log4sh_logger_
return ${log4sh_return}
}
# Retrieves the list of appenders from appropriate variable.
#
# Args:
# logger: string: name of logger
# Output:
# string: space separated list of appender names
# Returns:
# integer: undefined
_logger_getAppenders()
{
_log4sh_strToEval_="echo \"\${__log4sh_logger_${log4sh_logger_}}\""
eval "${_log4sh_strToEval_}"
unset _log4sh_strToEval_
}
# Gets the list of appenders for a logger.
#
# Args:
# logger: string: name of logger (optional)
# Output:
# string: space separated list of appender names
# Returns:
# integer: success of operation
logger_getAppenders()
{
if [ $# -gt 1 ]; then
${_LOG4SH_ERROR_} "'logger_getAppenders(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
log4sh_logger_=${1:-${__LOG4SH_LOGGER_ROOT}}
log4sh_return=${LOG4SH_FALSE}
( _logger_isValid "${log4sh_logger_}"; )
if [ $? -eq ${LOG4SH_TRUE} ]; then
_logger_getAppenders ${log4sh_logger_}
log4sh_return=${LOG4SH_TRUE}
fi
unset log4sh_logger_
return ${log4sh_return}
}
# Helper function to send an INFO priority message to the root logger.
#
# Args:
# msg: string: message to log
logger_info()
{
log ${__LOG4SH_LEVEL_INFO} "$@"
}
# The base logging function that sends a message to all appenders of a logger.
#
# Args:
# priority: string: the logging priority to limit message at
# STDIN|msg: string[]: the message to log
log()
{
if [ $# -ge 1 ]; then
${_LOG4SH_ERROR_} "'log(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
log4sh_priority_=$1
shift
[ $# -ne 0 ] && log4sh_msg_=$@ || log4sh_msg_=`cat`
# determine logger
[ -z "${log4sh_logger__}" ] \
&& log4sh_logger_=${__LOG4SH_LOGGER_ROOT} \
|| log4sh_logger_=${log4sh_logger__}
unset log4sh_msg_ log4sh_priority_
}
#------------------------------------------------------------------------------
# appender functions
#
# Determine if named appender is valid.
#
# Note: This function should always be called inside a subshell like (...;) due
# to variable scoping.
#
# Args:
# appender: string: name of [logger.]appender
# Returns:
# boolean: validity of logger
_appender_isValid()
{
${_LOG4SH_SPLIT_LOGGER_APPENDER_}
_log4sh_isValid_=${LOG4SH_FALSE}
( _logger_isValid "${log4sh_logger_}"; )
if [ $? -eq ${LOG4SH_TRUE} ]; then
_log4sh_appenders_=`_logger_getAppenders ${log4sh_logger_}`
for _log4sh_validAppender_ in ${_log4sh_appenders_}; do
${_LOG4SH_DEBUG_} "_log4sh_validAppender_=${_log4sh_validAppender_}"
if [ "${log4sh_appender_}" = "${_log4sh_validAppender_}" ]; then
_log4sh_isValid_=${LOG4SH_TRUE}
break
fi
done
fi
log4sh_return=${_log4sh_isValid_}
unset _log4sh_appenders_ _log4sh_isValid_ _log4sh_validAppender_
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${log4sh_return}
}
# Determine if appender type is valid.
#
# Note: if this function is called from a private function, it must be done
# inside a subshell like (...;) due to variable scoping.
#
# Args:
# type: string: appender type
# Returns:
# boolean: validity of appender type
_appender_isValidType()
{
_log4sh_type_=$1
_log4sh_isValid_=${LOG4SH_FALSE}
for _log4sh_validType_ in ${__log4sh_appenders}; do
if [ "${_log4sh_type_}" = "${_log4sh_validType_}" ]; then
_log4sh_isValid_=${LOG4SH_TRUE}
break
fi
done
log4sh_return=${_log4sh_isValid_}
unset _log4sh_isValid_ _log4sh_type_ _log4sh_validType_
return ${log4sh_return}
}
# Get the appender type for an appender.
#
# Args:
# appender: string: name of the [logger.]appender
# Outputs:
# string: appender type
# Returns:
# integer: success of the operation
appender_getType()
{
if [ $# -ne 1 ]; then
${_LOG4SH_ERROR_} "'appender_getType(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
${_LOG4SH_SPLIT_LOGGER_APPENDER_}
( _appender_isValid "${log4sh_fqAppender_}"; ) # subshell required
if [ $? -ne ${LOG4SH_TRUE} ]; then
${_LOG4SH_ERROR_} "'invalid appender (${log4sh_fqAppender_})'"
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${LOG4SH_FALSE}
fi
_log4sh_getValue "${log4sh_fqAppender_}.${__LOG4SH_KV_TYPE}"
log4sh_return=$?
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${log4sh_return}
}
# Set the appender type for an appender.
#
# Args:
# fqAppender: string: name of [logger.]appender
# type: string: appender type
# Returns:
# integer: success of the operation
appender_setType()
{
if [ $# -ne 2 ]; then
${_LOG4SH_ERROR_} "'appender_setType(): invalid argument count'"
return ${LOG4SH_ERROR}
fi
${_LOG4SH_SPLIT_LOGGER_APPENDER_}
log4sh_type_=$1
( _appender_isValid "${log4sh_fqAppender_}"; )
if [ $? -ne ${LOG4SH_TRUE} ]; then
${_LOG4SH_ERROR_} "'invalid appender (${log4sh_fqAppender_})'"
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${LOG4SH_FALSE}
fi
( _appender_isValidType "${log4sh_type_}"; )
if [ $? -ne ${LOG4SH_TRUE} ]; then
${_LOG4SH_ERROR_} "'invalid appender type (${log4sh_type_})'"
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${LOG4SH_FALSE}
fi
# if type valid, instantiate new appender
log4sh_return=${LOG4SH_FALSE}
while true; do # while instead of if/then so we can end early
_appender_new_${log4sh_type_} ${log4sh_fqAppender_} || break
_log4sh_setValue "${log4sh_fqAppender_}.${__LOG4SH_KV_TYPE}" ${log4sh_type_}
log4sh_return=${LOG4SH_TRUE}
break
done
unset log4sh_type_
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
return ${log4sh_return}
}
# Activate the options for an appender.
#
# Args:
# appender: string: name of [logger.]appender
appender_activateOptions()
{
${_LOG4SH_SPLIT_LOGGER_APPENDER_}
${_LOG4SH_CLEANUP_LOGGER_APPENDER_}
}
#-----------------------------------------------------------------------------
# main() code.
#
[ -z "${LOG4SH_DEBUG:-}" ] && _LOG4SH_DEBUG_=':' # disable debugging
__log4sh_tmpDir=`_log4sh_mktempDir`
__log4sh_dictFile="${__log4sh_tmpDir}/dictionary"
__log4sh_trapsFile="${__log4sh_tmpDir}/traps"
touch "${__log4sh_dictFile}" # prepare empty dictionary
trap >"${__log4sh_trapsFile}" # preserve old trap(s)
# configure traps
${_LOG4SH_DEBUG_} 'setting traps'
trap '_log4sh_cleanup EXIT' 0
trap '_log4sh_cleanup INT' 2
trap '_log4sh_cleanup TERM' 15
# setup default configuration
log4sh_resetConfiguration
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。