zoukankan      html  css  js  c++  java
  • 基于终端的日志工具logview

    概述

    logview是一个Shell脚本编写的基于终端的日志工具, 具有终端通知, email通知, 错误信息颜色配置, 以及灵活强大的监控配置. 还可以灵活的配置脚本监控的时间, 以及错误发生时需要进行的处理等. 该工具所使用的算法很适合监控大型日志。

    详细

    一、功能简介

    logview 是一个Shell脚本编写的基于终端的日志工具, 具有终端通知, email通知, 错误信息颜色配置, 以及灵活强大的监控配置. 还可以灵活的配置脚本监控的时间, 以及错误发生时需要进行的处理等. 该工具所使用的算法很适合监控大型日志。该工具,居然有如下功能:

    • 脚本所采用的算法非常适合用来监视大型日志文件

    • 将所监视出的错误信息发送给指定的邮件列表

    • 可以设置监视频率,比如30s/1h扫描一次日志文件

    • 将错误信息发送到指定的tty,达到出现错误立即知晓的目的

    • 自动指定脚本从何时开始监视日志文件,以及何时结束监视

    • 自由指定错误发生时,脚本所要执行的操作,比如kill掉产生日志文件的进程等.

    • 给错误信息配色

    • 日志文件分析及生成日志报告的功能

    • 可以自由指定所要监控的报错信息

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

    二、实现方法

    程序开始,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=$'
    '
        
                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

    三、安装方法

    1、准备工作

    1. 1台Linux服务器

    2、安装步骤

    1. 解压logview.zip包

    unzip logview.zip

    2. 进入logview目录

    cd logview

    3. 复制logview文件到你的$PATH路径中

    3、使用方法

    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

    四、运行效果

    blob.png

    blob.pngblob.png

     

    五、压缩包文件截图

    image.png

     

    六、其他补充

    其实该脚本的功能远不止这些,至于其他功能你可以参考logview -h并结合脚本源码获知其用法。该脚本很适合高频率的监视大型日志文件,假若刚启动监视脚本时是日志文件总共有10000行,设置监频率为3s,那么假设在这3s内日志文件新心曾800行,则该脚本查找错误字符串范围为10000-10800而不是0-10800,试想假若所监视的日志文件是个大型的日志文件,超过10W行,而且要不停听的监测,那么该脚本会节省很多资源和时间.而且脚本中的一些实现方法也值得学习和借鉴。当你将错误信息输出到标准输出而非文件时是,notice功能会自动被禁止掉,即使你指定了--notice参数。

    注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

  • 相关阅读:
    话说Hibernate和ADO.NET —练习随笔小记
    二次开发WinWebMail邮件系统接口 企业邮件服务器解决方案
    一个Windows后台服务(.Net的C#版) 定时访问数据库循环发送手机短信
    SQL UPDATE 联合表更新的问题
    2009新的篇章,惠海→时代财富→广佛都市网
    在WebService中使用Session或Cookie实现WebService身份验证(客户端是Flex)
    门户网站的形成—CMS内容管理系统
    CSS实现0.5px的边框或线
    《后人诗》
    CentOS6下docker的安装和使用
  • 原文地址:https://www.cnblogs.com/demodashi/p/9452897.html
Copyright © 2011-2022 走看看