shell脚本实现分日志级别输出

http://blog.csdn.net/qq_19646075/article/details/51236199


shell脚本如何优雅的记录日志信息,下面让我们一步一步,让shell脚本的日志也变得高端起来,实现如下功能 
①设定日志级别,实现可以输出不同级别的日志信息,方便调试 
②日志格式类似为:[日志级别] 时间 funcname:函数名 [lineno:行号] 日志信息 
③不同级别,设定不同颜色 
④让其变为函数库文件,重用代码 
下面看看我用shell记录日志的进化之路 
1.最简单的日志记录方式 
对于刚入门的同学,记录日志一般用echo加重定向方式,这应该是最原始的方式了^_^

echo "log message" > file
 
 
  • 1
  • 1

2.简单函数封装,简化重复写重定向到日志文件 
当你想记录的日志变多,你得重复的写echo “”>$logfile,这也是件挺麻烦的事情,于是我就写了个log函数,这样修改的时候也比较方便。

log() {
    msg=$1
    echo $msg > log.file
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

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
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

输出如下: 
这里写图片描述
在写这个函数的遇到一个问题就是不能用内建变量$LINENO来取得调用的行号,只能取得log函数中定义$LINENO那一行,搜了许久找到的解决办法是利用caller命令,关于caller命令的用法,如下: 
5.caller的用法 
caller命令放到函数中, 将会在stdout上打印出函数的调用者信息.,caller命令也可以在一个被source的脚本中返回调用者信息. 当然这个调用者就是source这个脚本的脚本. 就像函数一样, 这是一个”子例程调用”.你会发现这个命令在调试的时候特别有用.

 #!/bin/bash

 function1 ()
 {
   # 在 function1 () 内部.
   caller 0   # 显示调用者信息.
 }

 function1    # 脚本的第9行.

 # 9 main test.sh
 # ^                 函数调用者所在的行号.
 #   ^^^^            从脚本的"main"部分开始调用的.
 #        ^^^^^^^    调用脚本的名字.

 caller 0     # 没效果, 因为这个命令不在函数中.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值