Шпаргалки по логам

Post Tag: techit

Прошло уже два года со времен прошлой статьи powershell для тестировщиков по парсингу логов. Теперь больше работаю с Linux серверами и можно переписать статью.

Основная цель - собрать наиболее часто используемые команды и “хитрые техники” для повседневной работы уитилит grep, find, sed, awk. И так, приступим.

Поиск по логам:

Find и Grep:

# Поиск по pattern в file. Для архивов удобно использовать zgrep
# Ключи: r - рекурсивный поиск, E - поддержка регулярных выражений (egrep), o - выводит только совпадений, v - все кроме указанного(invert-match), H - имя файла
grep -rEovH pattern file

# Найти файлы в директория
find . -path './web*/somethin/test.log*

# Найти все файлы, без учета регистра и искать в них pattern с перенаправлением ошибок
find . -type f -iname '*.log*' 2>/dev/null -exec grep -H 'pattern' {} \;

Sort и Uniq:

# Найдем общие строки между двумя файлам
sort file1 file2 | uniq -d

# Найдем частоту события pattern. 
# sort - сортируем (конкеретно в этом случае не обязательно)
# uniq -ci - удаляем подсчитываем и удаляем дубликаты, i - без учета регистра
# sort -rn - сортируем по числу появлений, по убыванию
grep -oh 'pattern \[.*\]' test.log* | sort | uniq -ci | sort -rn

Примеры из практики:

Часто возникает необходимость найти какое-то событие, узнать номер “thread” и дальше посмотреть всю историю. В этом поможет конструкция ниже:

grep "`grep 'pattern' test.log | grep -oh "\w\{0,\}.n11"`" test.log.

# Усложним ситуацию. Нам надо найти когда для пользователей в рамках одного "thread" случилось два события. Oдин из способов это сделать:
find . -path './2017-05-*/test.log*' | while read path; do zgrep "`zgrep 'TEST_EVENT 1'  $path | awk '{print $4}'`" $path | grep -H 'TEST_EVENT 1' -B 2 -A 2 | grep '"TEST_EVENT 2"'; done  

Кстати, здесь используется отображение строк до совпадения и после совпадения - grep 'TEST_EVENT 1' -B 2 -A 2, а также цикл по найденным файлам - while read path; do zgrep 'pattern' $path; done

При поиске регулярных выражений по маске '(pattern1|pattern2)' grep выводит результат в двух разных строках. Решить эту проблему нам поможет Perl.

# Две строки для каждого совпадения
find . -path './test*/test.log*' -exec zgrep -H 'login/email' {} \; | grep '\[received\]' | egrep -o '(.+\.gz|\w+-\w+-\w+ \d\d:\d\d:\d\d|"email":".+@.+\.\w+")'

# Одна строка
# Ключи -n - выполнение кода, -e - задает код, -l - обработка окончаний строк
find . -path './test*/test.log*' -exec zgrep -H 'login/email' {} \; | grep '\[received\]' | perl -lne 'print /(.+\.gz|\w+-\w+-\w+ \d\d:\d\d:\d\d|"email":".+@.+\.\w+")/g'

Полезные ссылки:

Sed:

Sed - потоковый текстовый редактор

Синтаксис:

# Печатать строки где есть pattern
sed -n ‘/pattern/p’ file

# Удалить все пустые строки
sed -i ‘/^$/d’ file – remove all blank lines from file

# Заменить word1 на word2, word3 на word4
sed ‘s/word1/word2/g; s/word3/word4/g’ file– replacement with multiple patterns in file

Примеры из практики:

# Заменить одно значение переменной на другое
find -type f -name "test.*" -exec sed -i 's/MaxSize=[0-9][0-9][0-9]/MaxSize=384/' {} \;\

# Рекурсивная замена по всем вхождениям
find /home/user/ -type f | xargs sed -i  ‘s/a.example.com/b.example.com/g’ – recursively substitute each mattern match in files located on /home/user

# Убираем из вывода все коменты и пустые строки.
cat /opt/local/etc/squid/squid.conf | sed '/ *#/d; /^ *$/d'

# Используем регулярные выражения в find. Без sed не работают
find ./_filestorage/ -regextype sed -regex ".*/[a-f0-9\-]\{36\}\.\(jpg\|JPG\|png\|PNG\|gif\|GIF\)"

Полезные ссылки:

Awk:

Синтаксис:

# F - разделитель 
# NF - число полей в текущей записи (number of fields)
# NR - номер текущей записи (record number)
# FNR - номер записи для текущего файла

# Печатаем первую колонку, разделитель - пробелы или табы
awk ‘{print $1}’ file

# Разделитель :
awk -F ‘:’ ‘{print $1}’ file

# Сумма всех строк для 3 колонки
awk ‘{sum+=$3} END {print sum}’ file

# Среднее для 2 колонки
awk ‘{avg+=$2}END{print avg/NR}’ file

# Вывести все после 3 строки
awk ‘NR>3’ file– print everything aftчисло полей в текущей записи the 3rd line

# Частота использования IP
awk '{ array[$2]++ } END {for (ip in array) print array[ip],ip}' access.log

Примеры из практики:

Необходимо посчитать разницу между получением и отменой офера, для этого использовалась функция mktime для работы с временем.

zgrep -E "(Quotation:.+ - notification for .+ cancelled|Quotation:.+ - offer is sent to .+)" ./test/offers.log.gz | awk ' {print ($14 == "" ? $1 " " $2 " " $7 " " $12 : $1 " " $2 " " $7 " " $14) };' | awk '{gsub("-", " ", $1); gsub(/,[0-9][0-9][0-9]/, "", $2); gsub(":", " ", $2); print mktime($1 " " $2) " " $3 " " $4;}' | awk '{
if (array[$3]==""&&q==""||(array[$3]=="" && q==$2)) {array[$3]=$1;q=$2}
else if (array[$3]!="" && q==$2) {array[$3]=$1-array[$3];}
else {for (i in array) {if (array[i]!="") print q, i, array[i];}; delete array;array[$3]=$1;q=$2;}
} END{for (i in array) print q, i, array[i];}'

Полезные ссылки:

comments powered by Disqus