基于终端的日志工具logview
概述
详细
一、功能简介
logview 是一个Shell脚本编写的基于终端的日志工具, 具有终端通知, email通知, 错误信息颜色配置, 以及灵活强大的监控配置. 还可以灵活的配置脚本监控的时间, 以及错误发生时需要进行的处理等. 该工具所使用的算法很适合监控大型日志。该工具,居然有如下功能:
-
脚本所采用的算法非常适合用来监视大型日志文件
-
将所监视出的错误信息发送给指定的邮件列表
-
可以设置监视频率,比如30s/1h扫描一次日志文件
-
将错误信息发送到指定的tty,达到出现错误立即知晓的目的
-
自动指定脚本从何时开始监视日志文件,以及何时结束监视
-
自由指定错误发生时,脚本所要执行的操作,比如kill掉产生日志文件的进程等.
-
给错误信息配色
-
日志文件分析及生成日志报告的功能
-
可以自由指定所要监控的报错信息
-
只要你有bash以及mail命令即可运行此工具
二、实现方法
程序开始,global_variables用来定义一些全局变量和默认值,def_colors用来定义颜色
1 2 3 4 | # load global variables global_variables def_colors cat /dev/null > /tmp/logview_password .$$.log |
用while来循环解析命令行参数,用shell case语法来判断不同的参数格式,不同格式不同处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ### 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 (...),这种格式可以被如下代码解析并处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | [ "$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变量
1 2 3 4 | -m | --mail-list ) requiredarg "$@" maillist= "$2" ;; |
上面是整个脚本最核心处理复杂命令行参数的代码。接下来是监控脚本的核心代码:
logview会转存错误信息到一个文件,如果没有提供该文件,logview会打印监控到的错误信息到stdout:
1 | [ -z "$errorfile" ] && notice=no |
logview是通过调用tellb函数来通知出错信息的,如果notice=no,则不通知,如果notice=one,则调用Linux write命令将错误信息写到当前终端,如果notice=all,则logview会调用Linux wall命令将错误信息输出到所有终端。
接下来是监控脚本的核心逻辑:
通过:
1 2 3 4 | while true do ... done |
来循环的监控文件。
1 2 3 4 5 6 7 8 | 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 |
该代码块功能主要是循环所有的待监控文件,并做处理。
下面的代码主要功能是:
-
记住上次扫描的行数
-
计算:下次扫描时用文件总行数 - 上次扫描的函数 = 这次需要扫描的行数。开始扫描行为上次扫描的最后一行的行number。
-
调用awk脚本来判断当前行是否是错误信息。
代码会调用tail -$LINES ${MONFILES[i]}| eval "$GrepAwk"来执行指定的awk脚本,通过awk脚本判断当前行是否满足awk编写的规则。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 |
三、安装方法
1、准备工作
1. 1台Linux服务器
2、安装步骤
1. 解压logview.zip包
1 | unzip logview.zip |
2. 进入logview目录
1 | cd logview |
3. 复制logview文件到你的$PATH路径中
3、使用方法
1. 获取awk过滤文件,脚本用该文件过滤错误信息,如果仅想过滤带error/failed的行,你可以执行:
1 | logview -a |
该命令会在当前目录生成名为awk.example的文件,你可以在该文件的基础上进行修改
2. 运行./logview脚本
1 | . /logview awk .example -f test .log |
3. 更多使用方法,执行:
1 | logview -h |
4. 举例:
-
logview awk.example -f logfile
该命令会每隔3s扫描一次日志文件,并将包含error或者failed单词的行输 出到标准输出.
-
运行命令监视日志文件 - 例1
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
1 | 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
四、运行效果
五、压缩包文件截图
六、其他补充
其实该脚本的功能远不止这些,至于其他功能你可以参考logview -h并结合脚本源码获知其用法。该脚本很适合高频率的监视大型日志文件,假若刚启动监视脚本时是日志文件总共有10000行,设置监频率为3s,那么假设在这3s内日志文件新心曾800行,则该脚本查找错误字符串范围为10000-10800而不是0-10800,试想假若所监视的日志文件是个大型的日志文件,超过10W行,而且要不停听的监测,那么该脚本会节省很多资源和时间.而且脚本中的一些实现方法也值得学习和借鉴。当你将错误信息输出到标准输出而非文件时是,notice功能会自动被禁止掉,即使你指定了--notice参数。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?