Греп - главный инструмент администратора (с)Очень часто (и это действительно так) приходится что-то фильтровать. Это может быть все что угодно - логи, конфиги, проекты, чужие наработки - набор данных в которых нужно что-то найти, stdout... Умение пользоваться функционалом программ поиска\фильтрования может порой сэкономить вам кучу времени.
Какие инструменты используются для такой фильтрации?
1)
cat - вывести файл на stdout
2)
tail - вывести последие n строк из файла
3)
less - утилита для просмотра stdout\файла с большим спектром возможностей. как пример - поиск строк по паттерну, введя вот такую конструкцию:
/pattern
для поиска по документу.
4)
| - pipe, конвейер. ну, куда же без него. pipe - перенаправление стандартного потока вывода на стандартный поток ввода. В нашем случае это важный иструмент передачи данных между фильтрами.
5)
ack - красочный поиск
6)
grep - собственно самый главный инструмент. Тот самый инструмент, который и выполняет основную функцию фильтрования.
Искусство фильтрования кроется в умении объединять эти инструменты через pipe, правильной подаче входных данных на инструмент фильтрования и написание самих фильтров.
Что значит правильная подача данных?
Давайте сразу условимся, что работаем мы не с файлами на 50 строчек, а, например, с логами размером пару десятков гигабайт. Подача данных - это то, что мы отдадим фильтру на вход. Здесь есть несколько вариантов. Вариант первый - мы точно знаем что искать и вариант второй - мы не знаем, что на самом деле ищем. Второй случай - когда мы знаем, что-то происходило в такой-то период. За данный период у нас было несколько сотен тысяч записей. Что же делать? нужно пытаться подавать на вход фильтру ограниченное количество данных, а дальше смотреть глазами на получившийся вывод, стараясь понять какие записи в логах нам точно не нужны, снова фильтровать, исключая эти записи и так до тех пор, пока не останется вменяемо количество информации, которое можно анализировать.
Для подачи информации могут пригодиться команды cat, tail, head:
tail -n 1000 very_big_log | less
cat *.log | less
В первом случае мы подали ограниченное количество информации из конца файла, которую будем анализировать. Следующий этап - выкинуть лишние строчки из вывода. Кроме того, мы можем, например посчитать количество полученных строк после фильтрации, это можно сделать с помощью
wc -l
Например, это нужно, чтобы посчитать кол-во ошибок одного типа или просто знать сколько строк вы нагрепали:
bzcat error.log.201803290* | grep -v 'upstream prematurely closed connection' | wc -l
Есть еще одно правило, которое гласит "don't pipe cats" - не пропускайте кошек через трубы. Правильнее (и менее трудозатратно) писать так:
bzgrep -v 'upstream prematurely closed connection' error.log.201803290* | less
И так дальше, убирая все больше и больше лишних строк, приходим к нужному результату. За отбрасывание ненужного паттерна отвечает ключ -v.
bzcat error.log.201803290* | grep -v 'upstream prematurely closed connection' | grep -v 'overlimit resources' |less
Также полезно знать и помнить о том, что не всегда логи находятся в открытом виде - иногда могут быть и сжаты разными алгоритмами. Я уже писал про это ранее, но повторюсь:
bzcat, bzgrep, bzless - для алгоритма bzip
zcat, zgrep, zless - для gzip.
Вот простой пример использованая grep для фильтрования веб-трафика (ловим пакеты от нужных url):
tcpdump -i eth1 -A|grep example.com
Одна из немаловажных вещей - умение использовать регулярные выражения при осуществлении поиска. Самый банальный пример - поиск логов в указанный период. для этого нам вновь поможет grep, но здесь о нас заранее позаботились. можно использовать ключ, а можно написать egrep\fgrep. И они такж могут быть скомбинированы с bz\z, например
bzegrep
.
egrep = grep -E
Interpret PATTERN as an extended regular expression
fgrep = grep -F
Interpret PATTERN as a list of fixed strings (instead of regular expressions), separated by newlines, any of which is to be matched.
Ищем ip-адреса в логах:
egrep '(46.200.110.19|13.104.34.97)' /var/log/nginx/...
#grep