shell脚本获取最后10分钟日志的问题

时间:2019-05-06 09:17:08

标签: bash apache shell logging awk

我编写了一个脚本,用于检查最近10分钟内的最后一个httpd错误日志,但我收到一个错误,它会继续循环:问题是该脚本的输出是一个错误循环,直到日志文件结束 我试图获取日期-通过运行cmd date --date ='-10min'来获取10分钟,然后逐行解析日志文件,然后检查日志文件中每行的小时和分钟数是否大于或等于日期-10分钟的小时和分钟 这是输出的一部分:

./test2.sh: line 26: [: -ge: unary operator expected
./test2.sh: line 26: [Mon: command not found
./test2.sh: line 26: [: -ge: unary operator expected
./test2.sh: line 26: [Mon: command not found
./test2.sh: line 26: [: -ge: unary operator expected
./test2.sh: line 26: [Mon: command not found
./test2.sh: line 26: [: -ge: unary operator expected
./test2.sh: line 26: [Mon: command not found

当我尝试在此处进行调试时,这是问题的一部分,并且在日志文件的每一行中都会重复出现:

+ IFS=
+ read -r line
+ errorBool=0
+ [[ [Sun Apr 28 03:52:39.791442 2019] [autoindex:error] [pid 15012] 
[client 127.0.0.1:49054] AH01276: Cannot serve directory /var/www/html/: 
No matching DirectoryIndex (index.html,index.php) found, and server- 
generated directory index forbidden by Options directive == *:error* ]]
++ awk -F : '{printf $1}'
++ '[Sun' Apr 28 03:52:39.791442 '2019]' '[autoindex:error]' '[pid' 
'15012]' '[client' '127.0.0.1:49054]' AH01276: Cannot serve directory 
/var/www/html/: No matching DirectoryIndex '(index.html,index.php)' found, 
and server-generated directory index forbidden by Options directive
test2.sh: line 26: [Sun: command not found
++ awk '{printf $4}'
+ '[' -ge 12 ']'
test2.sh: line 26: [: -ge: unary operator expected

这是代码:

#!/bin/bash


#SCRIPT TO CHECK THE ERROR LOGS IN THE LAST 10 MINS

#VARIABLES

#NUMBER OF ERROR LOGS
errorCount=0
DATE_10_MIN=$(date --date='-10min' | awk '{print $4}' )
DATE_10_MIN_HOURS=$(date --date='-10min' | awk '{print $4}' | awk -F : 
'{print $1} ')
DATE_10_MIN_MIN=$(date --date='-10min' | awk '{print $4}' | awk -F : 
'{print $2} ')

#_______________________#

while IFS= read -r  line ; do


#BOOLEAN TO CHECK IF THE LINE HAVE THE EXPRESSION
errorBool=0


#if [[ $($line | awk '{print $4 }' | cut -c-8) -gt $DATE_10_MIN   ]] ; 
then

    if [[ $line  == *:error*  ]] ; then
            if [ [ $($line  | awk  '{print $4}' | awk -F : '{print $1}' )  
-ge $DATE_10_MIN_HOURS ] && [ $($line | awk  '{print $4}' | awk -F : 
'{print $2}')  -ge $DATE_10_MIN_MIN ] ]; then
            errorBool=1
            (( errorCount++ ))
            echo $line
            fi
    fi
 done < /var/log/httpd/error_log

 echo "There were $errorCount error logs in the last 10 mins "

2 个答案:

答案 0 :(得分:1)

这适用于我的测试系统。为了正确测试它,您必须更改输入数据中的日期:)。

代码

#!/bin/bash
#Script to check the error logs in the last 10 mins

#Variables.  Note: user variables should not be all uppercase.
errorCount=0
    # Number of error logs found
date_10_min_ago="$(date --date='-10min' +'%s')"
    # Time in seconds so it can be compared.
    # See https://unix.stackexchange.com/a/170982/63804 .

#_______________________#

while IFS= read -r line ; do
    if [[ $line  == *:error*  ]] ; then
        line_timestamp="$(awk -F '[][]' '{print $2}' <<<"$line")"
            # Get the date string, which is between brackets
        record_time="$(date --date="$line_timestamp" +'%s')"
            # Convert the date string to seconds.
            # Thanks to https://stackoverflow.com/a/1842754/2877364

        if (( record_time > date_10_min_ago)) ; then
            (( ++errorCount ))
            echo $line
        fi
    fi
done < 178.txt

echo "There were $errorCount error logs in the last 10 mins "

# vi: set ts=4 sts=4 sw=4 et ai:

样本输入

[Mon May 6 07:35:39.791442 2019] [autoindex:error] [pid 15012] [client 127.0.0.1:49054] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html,index.php) found, and server-generated directory index forbidden by Options directive - this error is older than 10 min
[Mon May 6 08:35:39.791442 2019] [autoindex:error] [pid 15012] [client 127.0.0.1:49054] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html,index.php) found, and server-generated directory index forbidden by Options directive
[Mon May 6 08:35:40.123456 2019] [autoindex:success] [pid 15012] [client 127.0.0.1:1337] Example input that doesn't contain the word "e r r o r"

输出

[Mon May 6 08:35:39.791442 2019] [autoindex:error] [pid 15012] [client 127.0.0.1:49054] AH01276: Cannot serve directory /var/www/html/: No matching DirectoryIndex (index.html,index.php) found, and server-generated directory index forbidden by Options directive
There were 1 error logs in the last 10 mins

说明

  • 比较日期(如果是数字)会容易得多。 date +'%s' format给出每个日期的秒数 *
  • 您可以使用awk -F '[][]'从一行中提取时间戳。 [][]是与[]匹配的正则表达式。因此,awk -F '[][]' '{print $2}'获取错误日志时间戳的文本。然后使用dateconvert that date text数秒以进行比较。
  • 一般注释:如果我希望将所有输​​出汇总在一起,则我希望将所有$()都包装为"$()"。我认为这更清楚。
  • 正如@lojza也提到的那样,通常,任何bash命令都必须完全在一行上。所以DATE_10_MIN_HOURS=$(some random code)很好,但是

    DATE_10_MIN_HOURS=$(some random code
    and more code on a different line)
    

    将导致错误。

*这可能在leap秒内不起作用。

答案 1 :(得分:0)

我在awk -F :之后看到换行符,我会写:

DATE_10_MIN=`date --date='-10min' '+%H:%M:%S'` 
DATE_10_MIN_HOURS=`date --date='-10min' '+%H'`
DATE_10_MIN_MIN=`date --date='-10min' '+%M'`