您好,登錄后才能下訂單哦!
這篇文章主要介紹shell腳本怎么實現分日志級別輸出,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
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
輸出如下:
在寫這個函數的遇到一個問題就是不能用內建變量$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 # 沒效果, 因為這個命令不在函數中.
以上是“shell腳本怎么實現分日志級別輸出”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。