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[31mdate +'%F %H:%M:%S'\t$1\t$2\033[0m" | tee -a $logfile;;
info)
echo -e "\033[32mdate +'%F %H:%M:%S'\t$1\t$2\033[0m" | tee -a $logfile;;
warn)
echo -e "\033[33mdate +'%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

输出如下:

在写这个函数的遇到一个问题就是不能用内建变量$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 # 没效果, 因为这个命令不在函数中.

转载:http://www.jb51.net/article/108721.htm

shell脚本实现分日志级别输出的更多相关文章

  1. Linux下添加shell脚本使得nginx日志每天定时切割压缩

    Linux下添加shell脚本使得nginx日志每天定时切割压缩一 简介 对于nginx的日志文件,特别是access日志,如果我们不做任何处理的话,最后这个文件将会变得非常庞大 这时,无论是出现异常 ...

  2. shell脚本分析nginx日志

    shell脚本分析nginx日志: name=`awk -F ',' '{print $13":"$32}' $file | awk -F ':' '{print $4}'`ech ...

  3. shell脚本调试打印日志问题

    shell脚本调试打印日志问题 1. 需求 我们在编写脚本的时候,有时候需要做调试,便于我们定位问题,有时候等脚本上线之后,我们需要保留脚本执行过程中的记录.便于我们在出问题的时候,定位问题. 2. ...

  4. shell脚本备份nginx日志

    vim /data/runlog.sh                                                  #编辑一个 shell 脚本 #!/bin/bash LOGP ...

  5. liunx 使用crontab定时任务+shell脚本删除tomcat日志elasticsearch日志索引

    由于过多的日志很占用磁盘空间,今天经理让我写一个脚本删除多余的日志.和es索引 定时删除试根据crontab+shell脚本实现的 crontab配置目录 /var/spool/cron/ 该目录下存 ...

  6. [shell脚本]在Linux终端可视化输出表格数据

    最终效果 1. 自定义表格样式 2. 自定义主题颜色 支持三系普通颜色 支持16色彩虹色 支持单颜色 回顾一下shell语法 1. shell传递参数 我们可以在执行shell脚本时实时传递参数从而指 ...

  7. shell脚本删除log日志

    删除log文件简单shell脚本 经常会遇到日志把磁盘占满的情况,引起低级故障.我个人在实际工作中,尝试了如下的方法,比较简单,而且快捷有效. #!/bin/bash # /root/log_dele ...

  8. shell脚本分析 nginx日志访问次数最多及最耗时的页面

    当服务器压力比较大,跑起来很费力时候.我们经常做站点页面优化,会去查找那些页面访问次数比较多,而且比较费时. 找到那些访问次数高,并且比较耗时的地址,就行相关优化,会取得立竿见影的效果的. 下面是我在 ...

  9. log4j2按日志级别输出到指定文件

    在项目中,可能会产生非常多的日志记录,为了方便日志分析,一般可以将日志按级别输出到指定文件,本次就先说说log4j2的实现吧: 1.先加入log4j2依赖包 2.写一个java类进行测试,类文件中仅仅 ...

随机推荐

  1. 【Java】提取JSON数值时遇到数组集合时使用的K-V方式转换

    1.实体类转换方法 参照文章:http://www.cnblogs.com/dflmg/p/6933811.html 2.K-V方法(此方法比较笨,但是没有办法,我现在不知道有没有相关的简单API,只 ...

  2. BZOJ1064 NOI2008假面舞会(dfs树)

    将图中的环的长度定义为正向边数量-反向边数量,那么答案一定是所有环的环长的共同因子.dfs一下就能找到图中的一些环,并且图中的所有环的环长都可以由这些环长加加减减得到(好像不太会证).如果有环长为1或 ...

  3. Day22-中间件

    1.中间件,在其它程序中,有的叫管道,有的叫http handler.下面是原生的中间件 2.自己也可以写中间件 2.1 写中间件,新建文件夹Middle,新建m1.py 2.2 在setting里注 ...

  4. Rotting Oranges - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Rotting Oranges - LeetCode 注意点 解法 解法一:bfs.首先先统计所有新鲜的橘子数目fresh,如果fresh大于0则一直执行 ...

  5. Palindrome Number - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Palindrome Number - LeetCode 注意点 负数肯定是要return false的 数字的位数要分奇数和偶数两种情况 解法 解法一: ...

  6. 小技巧--tab键自动补齐Git命令

    Git是什么,你不清楚? 好吧,那么该篇内容对你也木有帮助,请绕道而行.. 我们在使用Git命令时,可以通过tab键,自动补齐Git,特别是在切换分支时特别有用. 如下,当我们想将当前分支切换到bug ...

  7. 【整体二分】【P3834】 【模板】可持久化线段树 1(主席树)

    Description 给定一个长度为 \(n\) 的序列, \(m\) 次操作静态查询区间第 \(k\) 大 Input 第一行是 \(n,m\) 下一行描述这个序列 下面 \(m\) 行描述操作 ...

  8. 基于Java visualvm的可视化监控的使用

    1 Java visualVM可视化监控工具打开方式 ctrl + r 快捷键调出运行窗口,输出 jvisualvm指令,即可打开java visualVM工具.详情如下图: 2 Java Visua ...

  9. set.seed(7)什么意思

    以前虽然在每个程序都看见过,但是没注意过这个问题,也不理解是什么意思,去搜了一些帖子才明白. 其实,很好理解,就是如果你不加set.seed(7),当然代码也可以执行这个命令,但是每次执行的结果都会不 ...

  10. C++实现两个大整数的相加(考虑到负数异常情况)

    实现两个大整数的相加,首先应该排除直接使用int和long long的方法,这些方法很容易溢出,这里为了方便(是否可以使用更精简的结构存储?)采用char来存储整数,整体思路如下: 1. 对于整数n和 ...