Chinaunix首页 | 论坛 | 博客
  • 博客访问: 220941
  • 博文数量: 42
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 420
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-09 10:55
个人简介

每天改变一点点,生活充满了惊喜。

文章分类

全部博文(42)

文章存档

2016年(8)

2015年(29)

2014年(5)

我的朋友

分类: LINUX

2015-04-29 14:31:19

平时Shell写的比较多,而Shell的库都比较少见,一直希望整理一份自己常用的Shell库,先从日志开始。
在功能比较复杂,代码行较多的脚本中,良好的日志能使定位问题事半功倍。
下面的日志库代码实现的功能:

1.格式化输出日志,日志行打印级别、时间、执行的脚本名、代码行、用户自动定义信息,方便问题定位和跟踪。
2.按级别输出日志,支持五个级别的日志输出。
3.支持输出到终端、日志文件,这两种方式都支持按照级别输出,如只想把fatal日志打印到终端。

  1. ##! @TODO : Shell 日志库
  2. ##! @VERSION : 1.0.1
  3. ##! @FILE : log.sh
  4. ##! @AUTHOR : SunnyChan
  5. ##! @Date : 2015/07/20

  6. #################################################################################
  7. # 日志级别
  8. # 1:只打印fatal级别日志
  9. # 2:打印 fatal warning
  10. # 4:打印 fatal warning notice
  11. # 8:打印 fatal warning notice trace
  12. # 16:打印 fatal warning notice trace debug
  13. # 打印到日志文件的日志级别默认设置为16,打印到终端的日志级别默认为2
  14. # 可以在初始化时重置
  15. #################################################################################

  16. # 打印到日志中的各个级别的标识
  17. LOG_DEBUG_STR="DEBUG"
  18. LOG_TRACE_STR="TRACE"
  19. LOG_NOTICE_STR="NOTICE"
  20. LOG_WARNING_STR="WARNING"
  21. LOG_FATAL_STR="FATAL"

  22. # 日志级别
  23. LOG_LEVEL_DEBUG=16
  24. LOG_LEVEL_TRACE=8
  25. LOG_LEVEL_NOTICE=4
  26. LOG_LEVEL_WARNING=2
  27. LOG_LEVEL_FATAL=1

  28. # 打印到日志文件的日志级别
  29. LOG_FILE_LEVEL='16'
  30. # 打印到终端的日志级别
  31. LOG_TERM_LEVEL='2'
  32. # 日志文件路径
  33. LOG_DIR=''
  34. # 日志文件名
  35. LOG_NAME=''
  36. # 日志记录ID
  37. LOG_ID=''

  38. # 普通日志文件 和 错误日志文件
  39. LOG_FILE=''
  40. LOG_FILE_WF=''

  41. ##! @TODO : initialize log.
  42. ##! 初始化日志配置,设置日志文件路径和名称、需要打印至日志文件和终端的的日志级别。
  43. ##! 如果日志级别设置为空,则不打印。
  44. ##! @IN : $1 => directory to write log
  45. ##! @IN : $2 => log file name
  46. ##! @IN : $3 => log level (write to file) : 1,2,4,8,16
  47. ##! @IN : $4 => log level (ouput to terminal) : 1,2,4,8,16
  48. function log_init(){
  49.     LOG_DIR="$1"
  50.     if ! [ -d "${LOG_DIR}" ] && ! mkdir -p "${LOG_DIR}"
  51.     then
  52.         echo 'Error: log directory set error.'
  53.         return 1
  54.     fi
  55.     
  56.     LOG_NAME="$2"
  57.     [ -z "$LOG_NAME" ] && { echo "Error: log file name not set." >&2; return 1; }
  58.     LOG_FILE="${LOG_DIR}""/""${LOG_NAME}"".log"
  59.     LOG_FILE_WF="${LOG_DIR}""/""${LOG_NAME}"".wf.log"

  60.     LOG_ID=$(date '+%s')"_"$$

  61.     [[ "1" != "${3}" ]] && [[ "2" != "${3}" ]] && [[ "4" != "${3}" ]] \
  62.         && [[ "8" != "${3}" ]] && [[ "16" -ne "${3}" ]] && [[ "" != "${3}" ]] \
  63.         && { echo "Error: log level (write to log file) set invalid." >&2; return 1; }
  64.     LOG_FILE_LEVEL="$3"

  65.     [[ "1" != "${4}" ]] && [[ "2" != "${4}" ]] && [[ "4" != "${4}" ]] \
  66.         && [[ 8 != "${4}" ]] && [ 16 != "${4}" ]] && [[ "" != "${4}" ]] \
  67.         && { echo "Error: log level (output to terminal) set invalid." >&2; return 1; }
  68.     LOG_TERM_LEVEL="$4"

  69.     return 0
  70. }

  71. ##! @TODO : write debug log.
  72. function log_debug(){
  73.     log_write "${LOG_LEVEL_DEBUG}" "${LOG_DEBUG_STR}" "$1" "$2" "$3"
  74. }

  75. ##! @TODO : write trace log.
  76. function log_trace(){
  77.     log_write "${LOG_LEVEL_TRACE}" "${LOG_TRACE_STR}" "$1" "$2" "$3"
  78. }

  79. ##! @TODO : write notice log.
  80. function log_notice(){
  81.     log_write "${LOG_LEVEL_NOTICE}" "${LOG_NOTICE_STR}" "$1" "$2" "$3"
  82. }

  83. ##! @TODO : write warning log.
  84. function log_warning(){
  85.     log_write "${LOG_LEVEL_WARNING}" "${LOG_WARNING_STR}" "$1" "$2" "$3"
  86. }

  87. ##! @TODO : write fatal log.
  88. function log_fatal(){
  89.     #fatal 级别日志打印到标准错误
  90.     log_write "${LOG_LEVEL_FATAL}" "${LOG_FATAL_STR}" "$1" "$2" "$3" >&2
  91. }

  92. ##! @TODO : write log,比较当前日志级别和初始化设置的日志级别,判断是否写入日志文件和打印至终端。
  93. ##! 如果初始化时,未设置日志级别,则不打印
  94. ##! @IN : $1 => log level
  95. ##! @IN : $2 => log level string to print
  96. ##! @IN : $3 => script file which running
  97. ##! @IN : $4 => code line where write this log
  98. ##! @IN : $5 => log info which user define
  99. function log_write(){
  100.     local l_level="$1"
  101.     local l_level_str="$2"
  102.     local script_file="$3"
  103.     local code_line_no="$4"
  104.     local format_info="$5"
  105.     
  106.     # log format:
  107.     # [日志级别标识]: [log ID]: 当前时间: 当前执行的脚本文件: 打印日志的代码的行数: 用户自定义信息
  108.     local log_str="[${l_level_str}]: logid[${LOG_ID}]:"" $(date "+%Y-%m-%d %H:%M:%S")"" ${script_file}"" ${code_line_no}:"
  109.     log_str="$log_str"" $(eval printf ${format_info})"

  110.     # 判断日志级别,如果需要,写入到日志文件
  111.     if [ -n "${LOG_FILE_LEVEL}" ] && [ ${l_level} -le "${LOG_FILE_LEVEL}" ]
  112.     then
  113.         if [ ${l_level} -le 2 ]
  114.         then
  115.             echo "${log_str}" >> ${LOG_FILE_WF}
  116.         else
  117.             echo "${log_str}" >> ${LOG_FILE}
  118.         fi
  119.     fi
  120.     
  121.     # 判断日志级别,如果需要,则打印到终端
  122.     [ -n "${LOG_TERM_LEVEL}" ] && [ ${l_level} -le ${LOG_TERM_LEVEL} ] && echo "${log_str}"

  123.     return 0
  124. }
怎么使用上面的库?例如我需要写一个test.sh脚本,

首先
source 'log.sh'
初始化日志:
log_init "/home/users/test" "test" "8" "2"
写日志:
log_trace "$0" "$LINENO" "'this line is trace log: %s' 'test log'"
log_warning "$0" "$LINENO" "'this line is trace log: %s' 'test log'"

参数一:
$0 表示当前执行的脚本

注意:如果test.sh还调用了其他脚本,例如source了一个functions.sh,
functions.sh这个脚本中也需要写日志,这时第一个参数我们肯定希望写入“functions.sh”,
但使用$0,得到的还是test.sh,这时你需要使用环境变量${BASH_SOURCE[0]}。
兼容两种情况的写法就是,${BASH_SOURCE[0]-$0}(当然这里运行的环境是bash)。
参数二:
$LINENO 表示当前执行的代码行,这两个参数只传这两个值即可。
参数三:

 "'this line is trace log: %s' 'test log'"  作为第三个参数,采用的格式是C语言printf函数使用的格式,不过参数以空格分隔。
注意:由于Shell传参的原因,第三个参数的一定要以单引号包含起来,里面的格式化输出字符串,以及参数要以双引号包含起来,并且之间以空格分隔。


最终写入到日志文件或终端的日志信息为:
[TRACE]: logid[1437385728_18020]: 2015-07-20 17:48:48 test_log.sh 6:this line is trace log: test log

[WARNING]: logid[1437385728_18020]: 2015-07-20 17:48:48 test_log.sh 7:this line is trace log: test log

结束之前有一点需要提醒:
由于在Shell中,除了在function 中以local关键字申明的变量外(有些语句结构也是,如for等)其它都是全局变量,
所以在编写自己的脚本时,变量名要区别于库文件中的变量,一个比较好的方法的给变量加上一致的前缀或者后缀。
阅读(2282) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~