shell腳本如何優(yōu)雅的記錄日志信息,下面讓我們一步一步,讓shell腳本的日志也變得高端起來,實(shí)現(xiàn)如下功能
①設(shè)定日志級(jí)別,實(shí)現(xiàn)可以輸出不同級(jí)別的日志信息,方便調(diào)試
②日志格式類似為:[日志級(jí)別] 時(shí)間 funcname:函數(shù)名 [lineno:行號(hào)] 日志信息
③不同級(jí)別,設(shè)定不同顏色
④讓其變?yōu)楹瘮?shù)庫文件,重用代碼
下面看看我用shell記錄日志的進(jìn)化之路
1.最簡(jiǎn)單的日志記錄方式
對(duì)于剛?cè)腴T的同學(xué),記錄日志一般用echo加重定向方式,這應(yīng)該是最原始的方式了^_^
echo "log message" > file
2.簡(jiǎn)單函數(shù)封裝,簡(jiǎn)化重復(fù)寫重定向到日志文件
當(dāng)你想記錄的日志變多,你得重復(fù)的寫echo “”>$logfile,這也是件挺麻煩的事情,于是我就寫了個(gè)log函數(shù),這樣修改的時(shí)候也比較方便。
log() {
msg=$1
echo $msg > log.file
}
3.實(shí)現(xiàn)日志的級(jí)別不同顏色輸出
某天使用某腳本的時(shí)候,報(bào)錯(cuò)了確沒發(fā)現(xiàn),于是就想將報(bào)錯(cuò)信息用不同顏色字體,這樣會(huì)稍微友好一點(diǎn),請(qǐng)看下面函數(shù)
function log {
local text;local logtype
logfile=./log.txt
logtype=$1
text=$2
#其實(shí)可以再將日志的格式定義為一個(gè)字符串,這樣就不用重復(fù)寫`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.實(shí)現(xiàn)設(shè)定日志級(jí)別,輸出不同級(jí)別以上的日志,方便調(diào)試
學(xué)了Python的日志模塊后,想著如何像python那樣,可以設(shè)定日志級(jí)別,比如設(shè)定debug,那么只有debug級(jí)別以上的日志會(huì)輸出,而且日志的格式也支持定義,常見格式 如下:[日志級(jí)別] 時(shí)間 funcname:函數(shù)名 [lineno:行號(hào)] 日志信息
請(qǐng)看如下的log函數(shù):大家可以將log函數(shù)放到一個(gè)單獨(dú)文件,稱為函數(shù)庫文件,然后寫腳本的時(shí)候,通過source或 . 命令引入,就想python的導(dǎo)入模塊一樣,重用log的代碼
#!/bin/bash
#可將log函數(shù)單獨(dú)放一個(gè)文件,通過.命令引入,這樣就可以共用了
#. log.sh
#設(shè)置日志級(jí)別
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'`
#使用內(nèi)置變量$LINENO不行,不能顯示調(diào)用那一行行號(hào)
#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]}不能滿足多層函數(shù)嵌套
{
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
}
#以下為測(cè)試
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
輸出如下:
![](/d/20211017/c291da9213c00a627a37e7e68c93c6db.gif)
在寫這個(gè)函數(shù)的遇到一個(gè)問題就是不能用內(nèi)建變量$LINENO來取得調(diào)用的行號(hào),只能取得log函數(shù)中定義$LINENO那一行,搜了許久找到的解決辦法是利用caller命令,關(guān)于caller命令的用法,如下:
5.caller的用法
caller命令放到函數(shù)中, 將會(huì)在stdout上打印出函數(shù)的調(diào)用者信息.,caller命令也可以在一個(gè)被source的腳本中返回調(diào)用者信息. 當(dāng)然這個(gè)調(diào)用者就是source這個(gè)腳本的腳本. 就像函數(shù)一樣, 這是一個(gè)”子例程調(diào)用”.你會(huì)發(fā)現(xiàn)這個(gè)命令在調(diào)試的時(shí)候特別有用.
#!/bin/bash
function1 ()
{
# 在 function1 () 內(nèi)部.
caller 0 # 顯示調(diào)用者信息.
}
function1 # 腳本的第9行.
# 9 main test.sh
# ^ 函數(shù)調(diào)用者所在的行號(hào).
# ^^^^ 從腳本的"main"部分開始調(diào)用的.
# ^^^^^^^ 調(diào)用腳本的名字.
caller 0 # 沒效果, 因?yàn)檫@個(gè)命令不在函數(shù)中.
以上這篇shell腳本實(shí)現(xiàn)分日志級(jí)別輸出的方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
您可能感興趣的文章:- shell將腳本輸出結(jié)果記錄到日志文件的實(shí)現(xiàn)
- 輸出執(zhí)行操作和打印日志的shell腳本實(shí)例
- Linux shell腳本輸出日志筆記整理(必看篇)