基於終端的日誌工具logview

概述

logview是一個Shell腳本編寫的基於終端的日誌工具, 具備終端通知, email通知, 錯誤信息顏色配置, 以及靈活強大的監控配置. 還能夠靈活的配置腳本監控的時間, 以及錯誤發生時須要進行的處理等. 該工具所使用的算法很適合監控大型日誌。

詳細

1、功能簡介

logview 是一個Shell腳本編寫的基於終端的日誌工具, 具備終端通知, email通知, 錯誤信息顏色配置, 以及靈活強大的監控配置. 還能夠靈活的配置腳本監控的時間, 以及錯誤發生時須要進行的處理等. 該工具所使用的算法很適合監控大型日誌。該工具,竟然有以下功能:html

 

  • 腳本所採用的算法很是適合用來監視大型日誌文件算法

  • 將所監視出的錯誤信息發送給指定的郵件列表shell

  • 能夠設置監視頻率,好比30s/1h掃描一第二天志文件bash

  • 將錯誤信息發送到指定的tty,達到出現錯誤當即知曉的目的服務器

  • 自動指定腳本從什麼時候開始監視日誌文件,以及什麼時候結束監視函數

  • 自由指定錯誤發生時,腳本所要執行的操做,好比kill掉產生日誌文件的進程等.工具

  • 給錯誤信息配色學習

  • 日誌文件分析及生成日誌報告的功能字體

  • 能夠自由指定所要監控的報錯信息ui

  • 只要你有bash以及mail命令便可運行此工具

2、實現方法

程序開始,global_variables用來定義一些全局變量和默認值,def_colors用來定義顏色

 

# load global variables
global_variables
def_colors
cat /dev/null > /tmp/logview_password.$$.log

用while來循環解析命令行參數,用shell case語法來判斷不一樣的參數格式,不一樣格式不一樣處理:

 

### read cli options
# separate groups of short options. replace --foo=bar with --foo bar
while [[ -n $1 ]]; do
    case "$1" in
        -- )
            for arg in "$@"; do
                ARGS[${#ARGS[*]}]="$arg"
            done
            break
            ;;
        --debug )
            set -v
            DEBUG=0
            ;;
        --*=?* )
            ARGS[${#ARGS[*]}]="${1%%=*}"
            ARGS[${#ARGS[*]}]="${1#*=}"
            ;;
        --* )
            #die "$0: option $1 requires a value"
            ARGS[${#ARGS[*]}]="$1"
            ;;
        -* )
            for shortarg in $(sed -e 's|.| -&|g' <<< "${1#-}"); do
                ARGS[${#ARGS[*]}]="$shortarg"
            done
            ;;
        * )
            ARGS[${#ARGS[*]}]="$1"
    esac
    shift
done

set -- "${ARGS[@]}" 爲解析後的最終格式:logview -a --mail-time 5h (...),這種格式能夠被以下代碼解析並處理:

 

[ "$DEBUG" -eq 0 ] && echo "DEBUG: ARGS[@]: ${ARGS[@]}"
while [[ -n $1 ]]; do
    ((args=1))
    case "$1" in
        -- )
            shift && getfilenames "$@" && break
            ;;
        -h | --help )
            Usage
            exit 0
            ;;
        -a )
            getawkfile
            exit 0
            ;;
        -m | --mail-list )
            requiredarg "$@"
            maillist="$2"
            ;;
        --max-record )
            requiredarg "$@"
            maxrecord=$2
            ;;
        -s | --scan-time )
            requiredarg "$@"
            delay=$(conv2seconds "$2")
            [ "$delay" == "unknow" ] && die "$0: Unavailable time format."
            ;;
        -l | --log-file )
            requiredarg "$@"
            loglist=$2
            ;;
        -n | --notice )
            requiredarg "$@"
            notice=$2
            ;;
        --mail-time )
            requiredarg "$@"
            mail_time=$(conv2seconds "$2")
            [ "$mail_time" == "unknow" ] && die "$0: Unavailable time format."
            ;;
        --start-time )
            requiredarg "$@"
            start_time=$2
            ;;
        --end-time )
            requiredarg "$@"
            end_time=$2
            ;;
        -r | --report )
            requiredarg "$@"
            reprot=$2
            ;;
        --format )
            requiredarg "$@"
            format=$2
            ;;
            --parse )
                requiredarg "$@"
                parse="$2"
                ;;
            --timeout-start )
                requiredarg "$@"
                timeout_start=$(conv2seconds "$2")
                [ "$timeout_start" == "unknow" ] && die "$0: Unavailable time format."
                ;;
            --timeout-end )
                requiredarg "$@"
                timeout_end=$(conv2seconds "$2")
                [ "$timeout_end" == "unknow" ] && die "$0: Unavailable time format."
                ;;
            --back-color )
                requiredarg "$@"
                back_color=\${b$2}
                ;;
            --font-color )
                requiredarg "$@"
                font_color=\${$2}
                ;;
            --font )
                requiredarg "$@"
                font=\${$2}
                ;;
            -f )
                requiredarg "$@"
                [ "$2" == "" ] && die "$0: no input file for '-f' option."
                awkfile="$2"
                ;;
            -e )
                requiredarg "$@"
                [ "$2" == "" ] && die "$0: no input file for '-f' option."
                errorfile="$2"
                ;;
            -c | --command-message )
                requiredarg "$@"
                command_message="$2"
                ;;
            -p | --print )
                print_colors
                exit 0
                ;;
            -v | --version )
                echo "$version"
                exit 0
                ;;
            -* )
                die "$0: unrecognized option '$1'"
                ;;
            *)
                getfilenames "$1"
                ;;
        esac
        shift $args
    done
    # Get log file list
    [ "$loglist" != "" ] && {
    for f in $(cat $loglist|grep -v ^#) 
    do
        #[[ -f $f ]] || die "$0: $f No such file found."
        f="$(deal_remote $f)"
        FILES[${#FILES[*]}]="$f"
    done
}

不一樣選項,調用不一樣的函數進行處理,好比:-a,會調用getawkfile函數來生成awk文件。經過調用requiredarg函數來檢查--mail-time這類參數是否提供一個值,若是沒有提供則報錯。若是提供則把,--mail-time的值賦值給maillist變量

 

        -m | --mail-list )
            requiredarg "$@"
            maillist="$2"
            ;;

上面是整個腳本最核心處理複雜命令行參數的代碼。接下來是監控腳本的核心代碼:

logview會轉存錯誤信息到一個文件,若是沒有提供該文件,logview會打印監控到的錯誤信息到stdout:

[ -z "$errorfile" ] && notice=no

logview是經過調用tellb函數來通知出錯信息的,若是notice=no,則不通知,若是notice=one,則調用Linux write命令將錯誤信息寫到當前終端,若是notice=all,則logview會調用Linux wall命令將錯誤信息輸出到全部終端。

接下來是監控腳本的核心邏輯:

經過:

 

while true
do
    ...
done

來循環的監控文件。

 

    for ((i=0;i<FILENUM;i++))
    do
        if [ "$(eval echo '$COUNT'$i)" = "" ];then
            [ -f "${MONFILES[i]}" ] &&
                eval BASE$i=$(wc -l ${MONFILES[i]} 2>/dev/null| awk '{print $1}') ||
                eval BASE$i=0
        fi
    done

該代碼塊功能主要是循環全部的待監控文件,並作處理。

下面的代碼主要功能是:

  1. 記住上次掃描的行數

  2. 計算:下次掃描時用文件總行數 - 上次掃描的函數 = 此次須要掃描的行數。開始掃描行爲上次掃描的最後一行的行number。

  3. 調用awk腳原本判斷當前行是不是錯誤信息。

代碼會調用tail -$LINES ${MONFILES[i]}| eval "$GrepAwk"來執行指定的awk腳本,經過awk腳本判斷當前行是否知足awk編寫的規則。

 

    for ((i=0;i<FILENUM;i++))
    do
        sync_file "${MONFILES[i]}" #KONG
        [ -f "${MONFILES[i]}" ] &&
            eval COUNT$i=$(wc -l ${MONFILES[i]} | awk '{print $1}') ||
            eval COUNT$i=0
    
        #eval declare -i comp$i=0
        comp=$(($(eval echo '$COUNT'$i) - $(eval echo '$BASE'$i)))
    
        if [ $comp -gt 0 ];then
            LINES=$(eval expr '$COUNT'$i - '$BASE'$i)
            eval  BASE$i='$COUNT'$i
            IFS=$'\n'
    
            for MSGS in $(tail -$LINES ${MONFILES[i]}| eval "$GrepAwk")
            do
                [ $DEBUG -eq 0 ] && echo "DEBUG: \"error\" message is: [$MSGS]"
    
                [ -n "$MSGS" ] && {
                deal "$MSGS" "${MONFILES[i]}"
                tellb
            }
            done
        fi
    done

3、安裝方法

一、準備工做

1. 1臺Linux服務器

二、安裝步驟

1. 解壓logview.zip包

unzip logview.zip

2. 進入logview目錄

cd logview

3. 複製logview文件到你的$PATH路徑中

三、使用方法

 

1. 獲取awk過濾文件,腳本用該文件過濾錯誤信息,若是僅想過濾帶error/failed的行,你能夠執行:

logview -a

該命令會在當前目錄生成名爲awk.example的文件,你能夠在該文件的基礎上進行修改

2. 運行./logview腳本

./logview awk.example -f test.log

3. 更多使用方法,執行:

logview -h

4. 舉例:

  • logview awk.example -f logfile

該命令會每隔3s掃描一第二天志文件,並將包含error或者failed單詞的行輸 出到標準輸出.

  • 運行命令監視日誌文件 - 例1

 

logview awk.example -f logfile --font-color=red --font=bold -s 5s -c ./command.sh -mlkong@tecent.com --mail-time=5m參數解釋:

參數解釋

-f:指定你所要監視的日誌文件

--font-color=red:將錯誤信息以紅色字體打印

--font=bold:字體格式爲bold

-s5s:每隔5s掃描一第二天志文件

-m:將錯誤信息發送給 -m參數後的maillist

--mail-time=5m:每隔5分鐘發送一次email

  • 運行命令監視日誌文件 - 例2

 logview awk.example -f logfile --font-color=red --font=bold -s 5s -c ./command.sh -m lkong@redhat.com --mail-time=5m errorfile.txt --notice=one

--notice=one:當有錯誤信息時,logview會將錯誤信息發送到你當前的tty
--notice=all:當有錯誤信息時,logview會將錯誤信息發送到你全部的tty

4、運行效果

blob.png

blob.pngblob.png

 

5、壓縮包文件截圖

image.png

 

6、其餘補充

其實該腳本的功能遠不止這些,至於其餘功能你能夠參考logview -h並結合腳本源碼獲知其用法。該腳本很適合高頻率的監視大型日誌文件,倘若剛啓動監視腳本時是日誌文件總共有10000行,設置監頻率爲3s,那麼假設在這3s內日誌文件新心曾800行,則該腳本查找錯誤字符串範圍爲10000-10800而不是0-10800,試想倘若所監視的日誌文件是個大型的日誌文件,超過10W行,並且要不停聽的監測,那麼該腳本會節省不少資源和時間.並且腳本中的一些實現方法也值得學習和借鑑。當你將錯誤信息輸出到標準輸出而非文件時是,notice功能會自動被禁止掉,即便你指定了--notice參數。

注:本文著做權歸做者,由demo大師發表,拒絕轉載,轉載須要做者受權

相關文章
相關標籤/搜索