shell脚本如何优雅的记录日志信息,下面让我们一步一步,让shell脚本的日志也变得高端起来,实现如下功能
①设定日志级别,实现可以输出不同级别的日志信息,方便调试
②日志格式类似为:[日志级别] 时间 funcname:函数名 [lineno:行号] 日志信息
③不同级别,设定不同颜色
④让其变为函数库文件,重用代码
下面看看我用shell记录日志的进化之路
1.最简单的日志记录方式
对于刚入门的同学,记录日志一般用echo加重定向方式,这应该是最原始的方式了^_^
echo "log message" > file
2.简单函数封装,简化重复写重定向到日志文件
当你想记录的日志变多,你得重复的写echo “”>$logfile,这也是件挺麻烦的事情,于是我就写了个log函数,这样修改的时候也比较方便。
log() {
msg=
$1
echo
$msg >
log.
file
}
3.实现日志的级别不同颜色输出
某天使用某脚本的时候,报错了确没发现,于是就想将报错信息用不同颜色字体,这样会稍微友好一点,请看下面函数
function
log {
local text;
local logtype
logfile=./
log.txt
logtype=
$1
text=
$2
#其实可以再将日志的格式定义为一个字符串,这样就不用重复写`date +'%F %H:%M:%S'`\t$1\t$2\033[0m,又可以省好多代码。
case
$logtype in
error)
echo -e
"\033[31m`date +'%F %H:%M:%S'`\t$1\t$2\033[0m" | tee -a
$logfile;;
info)
echo -e
"\033[32m`date +'%F %H:%M:%S'`\t$1\t$2\033[0m" | tee -a
$logfile;;
warn)
echo -e
"\033[33m`date +'%F %H:%M:%S'`\t$1\t$2\033[0m" | tee -a
$logfile;;
esac
}
4.实现设定日志级别,输出不同级别以上的日志,方便调试
学了Python的日志模块后,想着如何像python那样,可以设定日志级别,比如设定debug,那么只有debug级别以上的日志会输出,而且日志的格式也支持定义,常见格式 如下:[日志级别] 时间 funcname:函数名 [lineno:行号] 日志信息
请看如下的log函数:大家可以将log函数放到一个单独文件,称为函数库文件,然后写脚本的时候,通过source或 . 命令引入,就想python的导入模块一样,重用log的代码
#!/bin/bash
#可将log函数单独放一个文件,通过.命令引入,这样就可以共用了
#. log.sh
#设置日志级别
loglevel=
0 #debug:0; info:1; warn:2; error:3
logfile=
$0".log"
function log {
local msg;local logtype
logtype=
$1
msg=
$2
datetime=`date +
'%F %H:%M:%S'`
#使用内置变量$LINENO不行,不能显示调用那一行行号
#logformat="[${logtype}]\t${datetime}\tfuncname:${FUNCNAME[@]} [line:$LINENO]\t${msg}"
logformat=
"[${logtype}]\t${datetime}\tfuncname: ${FUNCNAME[@]/log/}\t[line:`caller 0 | awk '{print$1}'`]\t${msg}"
#funname格式为log error main,如何取中间的error字段,去掉log好办,再去掉main,用echo awk? ${FUNCNAME[0]}不能满足多层函数嵌套
{
case $logtype in
debug)
[[
$loglevel -le
0 ]] &&
echo -e "\033[30m${logformat}\033[0m" ;;
info)
[[
$loglevel -le
1 ]] &&
echo -e "\033[32m${logformat}\033[0m" ;;
warn)
[[
$loglevel -le
2 ]] &&
echo -e "\033[33m${logformat}\033[0m" ;;
error)
[[
$loglevel -le
3 ]] &&
echo -e "\033[31m${logformat}\033[0m" ;;
esac
} | tee
-a $logfile
}
#以下为测试
debug () {
log debug
"there are $# parameters:$@"
}
info() {
log info
"funcname:${FUNCNAME[@]},lineno:$LINENO"
}
warn() {
log warn
"funcname:${FUNCNAME[0]},lineno:$LINENO"
}
error() {
log error
"the first para:$1;the second para:$2"
}
set -x
debug first second
set +x
info first second
warn first second
error first second