Я использую сценарий оболочки в течение ~ 3 лет, который запускает tail -F -n0 /path/to/LOGFILE
, анализирует и форматирует вывод и выгружает его в файл с разделителями каналов. Однако мы перешли от нескольких тысяч строк журнала в день к нескольким миллионам строк журнала в день, и скрипт начал потреблять огромное количество памяти и ЦП.
Недавно я заменил всю логику разбора данных на awk
, который при тестировании кажется на МНОГО порядков быстрее при анализе данных. Чтобы протестировать новый код awk, я попытался прокачать журналы за целый день через логику (~ 6 миллионов строк), используя как код awk, так и код оболочки, и неудивительно, что код awk вытащил ~ 92 000 соответствующих строк за ~ 10 секунд, в то время как Шелл-коду потребовалось более 15 минут, чтобы сделать то же самое. Однако, если я использую точно такой же код, но вместо cat /path/to/file|awk '...
' я делаю tail -F -n0 /path/to/file|awk '...
, возникает ОГРОМНАЯ задержка, когда текст записывается в файл, до ~ 2-3 минут, а не ~ 0,5-1,0 секунды, когда он проходит через шелл-код.
Шелл-код (да, я знаю, насколько уродлив шелл-код):
outDir="/opt/redacted/logs/allerrors/"
tail -F -n0 /opt/redacted/logs/manager.log|while read -a logLine;do
if [[ "${logLine[2]}" == "E" ]];then
if [[ "${logLine[7]:0:1}" == "@" ]];then
echo "${logLine[0]}|${logLine[1]}|${logLine[6]}|${logLine[7]}|${logLine[@]:8:${#logLine[@]}}" >> ${outDir}allerrors.${logLine[0]//\//.}.log
else
echo "${logLine[0]}|${logLine[1]}|${logLine[6]}|NULL|${logLine[@]:7:${#logLine[@]}}" >> ${outDir}allerrors.${logLine[0]//\//.}.log
fi
fi
Выполнено
авк-код:
outDir="/opt/redacted/logs/allerrors/"
tail -F -n0 /opt/redacted/logs/manager.log|awk -v dir=$outDir '{OFS="|"}
{
if ($3 == "E")
{
file="allerrors."$1".log"
gsub("/",".",file)
if ($8 ~ /@/)
print $1,$2,$7,$8,substr($0, index($0,$9)) >> dir file
else {if ($8 !~ /@/)
print $1,$2,$7,"NULL",substr($0, index($0,$8)) >> dir file
}
}
}'
Чтобы было ясно, оба набора кода работают и создают идентичный вывод, если я использую cat вместо хвоста файла, но с кодом awk я не вижу результатов в своем выходном файле до тех пор, пока ~ 2-3 минуты после того, как он появляется в журнале в то время как версия оболочки занимает всего несколько секунд.
awk
буферизует ввод, аread
нет. Почему вы используетеtail -F
вместо того, чтобы просто предоставить файл в качестве входных данных дляawk
(т.е. ни кота, ни хвоста, а просто читать):awk ... /opt/redacted/logs/manager.log
- person rici   schedule 27.11.2013