2014-11-20 1 views
0

Мне нужно написать скрипт оболочки/perl для сканирования файла журнала за последние 30 минут. Требование состоит в том, чтобы запланировать запуск этого сценария в Cron каждые 30 минут и поиск строки ошибки.Сканирование файлов журнала за последние 30 минут данных

OS: Solaris 
Shell:Bash 

Я попытался ниже сценарий, но он был слишком длинным и неуклюжим, у нас есть другой способ сделать это немного короче?

blogs=/opt/docs/datapower/prod/business.log 
slogs=/opt/docs/datapower/prod/system.log 


starttime=$(date +'%H') 
currmin=$(date +'%M') 
curdate=`date|cut -d' ' -f5` 
echo $(date) 

if [ $currmin -le 29 ] && [ $starttime -ne 00 ] ; then 
starttime1=`echo "$(date +'%H') - 1" | bc` 
logtime="$starttime1" 
logtime="$logtime:[3-5][0-9]" 
echo $logtime 



elif [ $currmin -le 29 ] && [ $starttime -eq 00 ] ; then 
logtime="23:[3-5][0-9]" 
echo $logtime 



else 
logtime="$starttime" 
logtime="$logtime:[0-2][0-9]" 
echo $logtime 

fi 

if (grep "$logtime" $slogs | egrep "AAA Authentication Failure|AAA Authorization Failure") > dptest 2>&1;then 

     Do something 

fi 

ОБНОВЛЕНИЕ: Добавление примера ведения журнала. Ниже приведен пример журнала заявления: Nov 20 06:06:58 business-log-sta [DP-Domain-STAGING][0x80000001][business-log][info] mpgw(GenServiceMPG): trans(31513092)[request]: AAA Authentication failure/>

+1

Можете привести пример строки журнала? – Sobrique

+0

В вопросе добавлена ​​строка с примером журнала. – user2607367

+0

Просто дикая догадка, Solaris с perl '5.8.x', поэтому модуль 'Time :: Piece' не установлен. –

ответ

1

Я думаю, что вы делаете это немного назад - построение RE на Grep дату из лог-файла.

Приближаясь к этому в perl, я бы хотел прочитать весь файл журнала, tokenise it - извлечь временную метку - и затем оповестить на основе содержимого сообщения.

У Perl есть хороший модуль для первой части - Time::Piece. Это идет немного как это:

use strict; 
use warnings; 

use Time::Piece; 

my $HALF_HOUR = 30 * 60; 

while (<DATA>) { 
    #extract timestamp via regular expression 
    my ($timestamp, $message) = (m/\A(\w+\s+\d+\s+\d+:\d+:\d+) (.*)/); 

    #convert text timestamp to 'unix time'. 
    #need the year in here because your log doesn't include it. 
    my $t = localtime(); 
    $t = $t->strptime($timestamp . " " . $t->year, "%b %d %H:%M:%S %Y"); 


    #skip if parsed time is more than half an hour ago. 
    next if ($t < time() - $HALF_HOUR); 
    if ( $message =~ m/AAA Authentication failure/i 
     or $message =~ m/AAA Authorization failure/i) 
    { 
     print "Alert: ($t) $message\n"; 
    } 
} 

__DATA__ 
Nov 20 13:46:58 business-log-sta [DP-Domain-STAGING][0x80000001][business-log][info] mpgw(GenServiceMPG): trans(31513092)[request]: AAA Authentication failure/> 
Nov 20 13:00:58 business-log-sta [DP-Domain-STAGING][0x80000001][business-log][info] mpgw(GenServiceMPG): trans(31513092)[request]: AAA Authentication failure/> 
Nov 20 10:06:58 business-log-sta [DP-Domain-STAGING][0x80000001][business-log][info] mpgw(GenServiceMPG): trans(31513092)[request]: AAA Authentication failure/> 

Followup Q:

"Не могли бы вы объяснить, что делает это заявление, my ($timestamp, $message) = (m/\A(\w+\s+\d+\s+\d+:\d+:\d+) (.*)/);"

Это делает две вещи:

  • One из трюков в Perl, заключается в том, что вы можете захватывать части регулярного выражения, помещая их в скобки. Таким образом, \A(\w+\s+\d+\s+\d+:\d+:\d+) - будет совпадать с момента перекладки:
    • Одно или несколько символов 'word'.
    • Один или несколько цифр '
    • \d+:\d+:\d+ займет время. (Любое число, разделенное двоеточиями).

Другая часть, конечно, захватывает 'остальное'.

  • Затем мы присваиваем массив, возвращаемый сопоставления с образцом, в массив именованных переменных ($timestamp и $message).

Чистый результат - с учетом линии:

Nov 20 13:46:58  business-log-sta [DP-Domain-STAGING][0x80000001][business-log][info] mpgw(GenServiceMPG): trans(31513092)[request]: AAA Authentication failure/> 
(\w+ \d+ \d+:\d+:\d+) (.*) 

Наше регулярное выражение возвращает два «куски» по отдельности, а затем поместить их в двух переменных.

+0

Не могли бы вы объяснить, что делает этот оператор: 'my ($ timestamp, $ message) = (m/\ A (\ w + \ s + \ d + \ s + \ d +: \ d +: \ d +) (. *) /); ' – user2607367

+0

Обновленный ответ. – Sobrique

+0

Спасибо, теперь вместо поиска ошибки каждые полчаса в журналах, я должен найти строку и отправить ее в файл журнала. Что я сделал в сценарии оболочки. 'grep 'BIRCH' $ blogs | sed -e 's/BIRCH //'>/tmp/dp/ORIGO_CE_MI'. Как это можно сделать в perl? Я ищу строку под названием BIRCH в журналах и отправляю строку, содержащую строку, но не копируя эту конкретную строку (используя sed). – user2607367

0

Как вы думаете, использовать sqlite3 для фильтрования - преимущество, которое он анализирует для вас, может быть очень удобным. Единственная обратная сторона - это нормализация данных.

function sqlite-filter-time() { 
    if [ '0' = "$#" ]; then 
     echo "Usage: $FUNCNAME <file> <timespan> <where>" 
     return 
    fi 
    local year="$(date '+%Y')" 
    local ofs='___FS___' 
    sed "s,^\([^ ]* [^ ]*\) \([^ ]*\),\1 \2$ofs," "$1" | sed "s,Jan ,$year-01-,;s,Feb ,$year-02-,;s,Mar ,$year-03-,;s,Apr ,$year-04-,;s,May ,$year-05-,;s,June ,$year-06-,;s,July ,$year-07-,;s,Aug ,$year-08-,;s,Sep ,$year-09-,;s,Oct ,$year-10-,;s,Nov ,$year-11-,;s,Dec ,$year-12-," > "$1.tmp" # normalize data for sqlite - command to extract the date and the rest of the text 
    { 
     echo '.mode csv' 
     echo 'DROP TABLE IF EXISTS sft;' 
     echo 'CREATE TEMPORARY TABLE sft (' 
     echo ' sft_date TEXT,' 
     echo ' sft_text TEXT' 
     echo ');' 
     echo ".headers off" 
     echo ".nullvalue ''" 
     echo ".separator '$ofs'" 
     echo ".import $1.tmp sft" 
     echo ".separator ' '" 
     echo "SELECT *" 
     echo "FROM sft" 
     echo "WHERE sft_date > datetime('now', '$2')" 
     echo " AND (sft_text like '%AAA Authentication Failure%'" 
     echo " OR sft_text like '%AAA Authorization Failure%'" 
     echo ")" 
     echo ";" 
    } | sqlite3 
    rm "$1.tmp" 
} 

$ sqlite-filter-time "$slogs" '-30 minutes' 
"2014-11-20 16:01:58" " business-log-sta [DP-Domain-STAGING][0x80000001][business-log][info] mpgw(GenServiceMPG): trans(31513092)[request]: AAA Authentication failure/>" 
$ 

 Смежные вопросы

  • Нет связанных вопросов^_^