
Этот скрипт отслеживает файл журнала на наличие шаблона "ora", извлекает сведения об ошибке и отправляет электронное письмо. В этом случае я хочу извлечь только последнюю ошибку, которая попала в файл журнала. Я установил crontab на каждые 5 минут, поэтому grep извлекает те же старые ошибки, которые вызывают ложные оповещения. Скрипт должен получать ошибки с текущим временем и избегать поиска старых ошибок.
mailto=xyz.email.com
logdirectory=/location/to/logfile
cd $logdirectory
grep "ORA" logfile
if [ $? = 0 ]; then
mailx -s "errors" $mailto
fi
Мой лог-файл:
Fri Jun 07 05:09:32 2019 Archived Log entry 93 added for thread 1 sequence 59 ID 0xf10d426f dest 1:
Fri Jun 07 11:08:20 2019 07-JUN-19 ORA-1100: Testing, Please Ignore
решение1
Показан вариант 2 измой комментарийкакпо запросу ОП:
awk -v parseLog='/some/where/filename' '
BEGIN {
prevNR=( (getline line < parseLog) > 0 ? line : 0 )
}
(NR>prevNR) && /ORA/{ print; found=1 }
END {
print NR > parseLog
exit !found
}
' /location/to/logfile
или в оболочке:
parseLog='/some/where/filename'
IFS= read -r line < "$parseLog"
if [[ -n "$line" ]]; then
prevNR="$line"
else
prevNR=0
fi
nr=$(wc -l < /tmp/logfile)
head -"$nr" /location/to/logfile |
tail +"$(( "$prevNR" + 1 ))" |
grep ORS
rslt=$?
printf '%d\n' "$nr" > "$parseLog"
Обратите внимание, что вам нужно получить количество строк wc
, сначала выполните head
для этого количества строк и передайте ЭТО в tail, а затем в grep, в противном случае файл журнала может вырасти между grep
и , wc
и тогда вы пропустите строку на следующей итерации, или если вы поменяете их порядок, то вы можете проанализировать одну и ту же строку дважды.
Обратите внимание, что вышесказанное предполагает, что запись в файл журнала выполняется за одну атомарную операцию на строку. Если же запись выполняется по частям строк по отдельности с последующим присоединением новой строки по завершении, то для приведенного выше анализа необходимо проигнорировать последнюю, возможно частичную, строку файла журнала.