This library is similar to Log library for Python or Java. Here its code:
#!/bin/sh
# Simple logging facility for Unix /bin/sh
# ========================================
#
# Configuration
# -------------
#
# _LOGGING_DATEFMT, _LOGGING_FMT variables are used for format of datetime
# and log record
#
# * _LOGGING_DATEFMT : uses the same format as date(1) and Python Lib
#
# * _LOGGING_FMT : uses format similar to Python logging Lib
#
# Available fields for _LOGGING_FMT are:
# asctime, filename, levelname, levelno, message, name, pathname,
# process, processName, user
#
# Example
# -------
#
# getLogger prg1
# getLogger prg2
#
# addLogHandler prg1 FileHandler /dev/stderr
# addLogHandler prg2 ConsoleHandler
# addLogHandler prg2 FileHandler /var/log/somefile
# addLogHandler prg2 FileHandler /var/log/somefile_copy
#
# setLogLevel prg1 DEBUG
#
# prg1_debug DebugMessage
# prg1_error ErrorMessage
# echo InfoMessage|prg2_info
#
# will produces on STDERR console:
# ...
# 2014-07-18T17:09:52+0300 prg1 DEBUG DebugMessage
# ...
#
# will produces on console:
# ...
# 2014-07-18T17:09:52+0300 prg1 ERROR ErrorMessage
# 2014-07-18T17:09:52+0300 prg2 INFO InfoMessage
# ...
#
# and in /var/log/somefile:
# ...
# 2014-07-18T17:09:52+0300 prg2 INFO InfoMessage
# ...
#
# and in /var/log/somefile_copy:
# ...
# 2014-07-18T17:09:52+0300 prg2 INFO InfoMessage
# ...
# TODO: log levels per handlers
############################## Settings #####################################
# Global log record format and date format:
_LOGGING_DATEFMT="%Y-%m-%dT%H:%M:%S%z"
_LOGGING_FMT="%asctime %name %levelname %message"
################################### Code #####################################
_log_SCRIPT=`readlink -f $0`
_log_getLogAttr() {
name=$1; attr=${1}_$2
eval echo $`echo $attr`
}
################################### Handlers #################################
# SYNOPSIS: ...
#
# Nothing to do, all args are ignored
_log_NullHandler() {
:
}
# SYNOPSIS: $name $level $msg
#
# Logs $msg with $level via logger(1) utility
_log_SyslogHandler() {
local name level msg syslog_level
name="$1"; level="$2"; msg="$3"
syslog_level=`_log_syslogLevel $level`
logger -p "local0.${syslog_level}" -t $name "$msg"
}
# SYNOPSIS: $name $level $msg
#
# Logs message $msg on console
_log_ConsoleHandler() {
local name level msg
name="$1"; level="$2"; msg="$3"
echo "$msg"
}
# SYNOPSIS: $subject $address $msg
#
# If mail(1) exists, call it to send $msg via EMail
_log_MailHandler() {
command -v mail >/dev/null 2>&1 || return 1
local subj addr name level msg
subj="$1"; addr="$2"; name="$3"; level="$4"; msg="$5"
echo "$msg"|mail -s "${subj}${level}: $name" $addr
}
# SYNOPSIS: $filename $msg
#
# Append message $msg to file $filename
_log_FileHandler() {
local filename name level msg
filename="$1"; name="$2"; level="$3"; msg="$4"
touch "$filename"
echo "$msg" >> "$filename"
}
_log_syslogLevel() {
case $1 in
CRITICAL)
echo crit;;
FATAL)
echo panic;;
ERROR)
echo error;;
WARNING)
echo warning;;
INFO)
echo info;;
DEBUG)
echo debug;;
*)
echo notice;;
esac
}
_log_levelNo() {
case $1 in
CRITICAL|FATAL)
echo 50;;
ERROR)
echo 40;;
WARNING)
echo 30;;
INFO)
echo 20;;
DEBUG)
echo 10;;
*)
echo 0;;
esac
}
_log() {
local name level msg handlers h closure_args skip no_closure_args levelno enabled_levelno
name="$1"; level="$2"; msg="$3"
levelno=`_log_levelNo $level`
enabled_levelno=`_log_getLogAttr $name level`
[ $levelno -lt $enabled_levelno ] && return
handlers=`_log_getLogAttr $name handlers`
handlers=`echo "$handlers"|sed 's/__COMMA__/\\ /g'`
for h in $handlers; do
echo $skip|grep $h >/dev/null && continue
closure_args=`_log_getLogAttr $name ${h}_handler_args`
closure_args=`echo "$closure_args"|sed 's/__COMMA__/\\ /g'`
no_closure_args=1
for ca in $closure_args; do
eval "$h $ca $name $level \"$msg\""
no_closure_args=0
done
[ $no_closure_args ] && eval "$h $name $level \"$msg\""
skip="$h $skip"
done
}
# SYNOPSIS: $name $h [$args...]
#
# Adds handler $h for logger $name with possible arguments
# (see handlers' implementations for concrete args)
addLogHandler() {
local name handler oldhandlers exthandler args oldargs
name=$1; exthandler="$2"; handler=_log_"$exthandler"; shift 2; args="$*"
oldhandlers=`_log_getLogAttr $name handlers`
oldargs=`_log_getLogAttr $name ${handler}_handler_args`
# __COMMA__ is used to separate items in lists
eval "${name}_handlers=${handler}__COMMA__${oldhandlers:-_log_NullHandler}"
eval "${name}_${handler}_handler_args=\"$args\"__COMMA__$oldargs"
}
# SYNOPSIS: $name | $name $longname
#
# No return and no output but setups logger for this $name. In 2nd form $longname
# is used in message substitution
getLogger() {
local asctime filename levelname levelno message name pathname process processName _lv user longname
asctime=$_LOGGING_DATEFMT
filename=`getScriptName`
message='${1:-`tee`}'
name="$1"
longname=${2:-$name}
pathname=`echo "$_log_SCRIPT"|sed 's/\\//\\\\\//g'`
process='$$'
processName=`ps -A -opid,comm | awk -v PID=$$ '$1 == PID { print $2 }'`
processName=`echo "$processName"|sed 's/\\//\\\\\//g'`
user="$USER"
for _lv in debug info warning error fatal critical; do
levelname=`echo -n $_lv|tr '[:lower:]' '[:upper:]'`
levelno=`_log_levelNo $levelname`
fmt=`echo $_LOGGING_FMT | \
sed 's/%asctime/\`date +$_LOGGING_DATEFMT\`/g' | \
sed "s/%filename/$filename/g" | \
sed "s/%levelname/$levelname/g" | \
sed "s/%levelno/$levelno/g" | \
sed "s/%message/$message/g" | \
sed "s/%pathname/$pathname/g" | \
sed "s/%processName/$processName/g" | \
sed "s/%process/$process/g" | \
sed "s/%user/$user/g" | \
sed "s/%name/$longname/g"`
eval "${name}_${_lv} () { _log $name $levelname \"$fmt\"; }"
done
setLogLevel $name INFO
}
# SYNOPSIS: $name $level
#
# Sets the threshold for $name logger to $level (INFO, ERROR, etc.). Logging
# messages which are less severe than $level will be ignored.
# Default is INFO
setLogLevel() {
local name level levelno
name="$1"; level=`echo -n $2|tr '[:lower:]' '[:upper:]'`
levelno=`_log_levelNo $level`
eval "${name}_level=$levelno"
}
# SYNOPSIS:
#
# Echos name of script
getScriptName() {
echo `basename "$_log_SCRIPT"`
}
Example of usage:
#!/bin/sh
. ./logging.sh
getLogger prg1 `getScriptName`
addLogHandler prg1 ConsoleHandler
addLogHandler prg1 FileHandler ./lll1.log
addLogHandler prg1 FileHandler ./lll2.log
setLogLevel prg1 DEBUG
prg1_debug Debugggg
prg1_error Errrrror
echo 'Message-INFO!!!!
1111
2222'|prg1_info
Комментариев нет:
Отправить комментарий
Thanks for your posting!