среда, 7 октября 2015 г.

Splunk. Введение в SPL


Приветствую тебя, уважаемый читатель!


Продолжая тему изучения возможностей системы Splunk, я решил рассказать про возможности встроенного языка запросов к данным. Описать все его возможности и команды я не смогу (да и не все знаю), но общее представление о логике запросов вы получите.
Экспериментировать мы будем с логом замечательной софтины – Fail to Ban. Итак поехали! :)

Долго думал с чего начать, решил, что начну с объяснения, куда вбивать запрос и что должно получиться в итоге.  Подразумевается, что журнал Fail to Ban вы уже подключили по аналогии с примером из прошлого поста, хотя можете поэкспериментировать с журналом ОС Linux. Для удобства я назвал sourcetype fail2ban. Сам файл лога лежит тут - /var/log/fail2ban.log.

Из коробки Splunk понимает формат данного лога и автоматом распарсит все события. Только незабываем выбрать опцию  -  continuously monitor ,  иначе события проиндексируются один раз.


Для начала перейдите в приложение «Search and Reporting», автоматом вы попадёте на вкладку «Search». Вбейте в строку поиска «sourcetype=fail2ban» и если всё получилось, то результат будут аналогичен скриншоте ниже.



В левой части окна будут поля (fields), которые Splunk автоматически распарсил из события. Заранее скажу, что помимо встроенных возможностей по парсингу событий, вы может доставать из события любые поля автоматически сгенерив для этого регулярное выражение, но об этом напишу как-нибудь позднее.   

Соответственно в центральной части представлены сами события, которые вы  можете представить в 3-х видах (Raw, List, Table). На скриншоте ниже переключатель выделен жёлтым цветом.

 
  
Но, я вам настоятельно советую довериться ребятам из Splunk и оставить формат отображения List, т.к. вы сразу видите метаданные события (Source, Sourcetype, Host). Теперь непосредственно к языку запросов.

Фильтрация данных


Вбейте в строке поиска следующее:
sourcetype=fail2ban Ban ssh



Для спланка это будет означать – покажи мне все события из типа данных fail2ban содержащие фразы – «ssh» и «Ban». Собственно полнотекстовый поиск по всем полям во всей красе :)

Если по каким-либо причинам вам привычнее использовать синтаксис SQL можете вбить запрос следующим образом:

sourcetype=fail2ban | where like(srcip,"182.%")



Однако, тут надо иметь ввиду, что такая конструкция сработает только в том случае, если или Splunk автоматически или вы ручками распарсите поле с именем «srcip».

Таким образом, отфильтровать события можно и следующим образом:
<имя распарсеного поля>=<значение>

sourcetype=fail2ban actions=ban srcip="104.168.56.*"




В запросах можно использовать логические операторы и усложнять тем самым фильтрацию событий. Например, запрос ниже выведет все события по всем адресам из диапазона 97.74.74.1/24, у которых в поле actions установлено значение Ban/Unban.

sourcetype=fail2ban (srcip=97.74.74.* AND (actions=Ban OR actions=Unban))


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

sourcetype=fail2ban (Ban OR Unban) NOT 97.74.74.94 


Составные запросы 


Запросы в Splunk могут быть произвольной длины и содержать много разных команд, но концепция написания любого запроса следующая:

Один запрос может состоять из множества подзапросов разделенных между собой pipe (|), и справа налево каждый следующий запрос оперирует данными полученными в результате выполнения предыдущего. Покажу лучше на примере :)

Разберем запрос представленный ниже: 

sourcetype=fail2ban | dedup srcip | table srcip

sourcetype=fail2ban - тип данных откуда получаем события
| dedup srcip  -  оператор dedup позволяет схлопнуть события, с одним и тем же  значением srcip
| table srcip   - указывает спланку, что необходимо вывести результат в табличном виде, и включить в вывод только поле srcip

Должен получиться, примерно, следующий результат:


 
Следующий запрос посложнее:

sourcetype=fail2ban actions=ban | head 10 | top srcip | fields - percent,count | rename srcip as "IP-источника"

sourcetype=fail2ban actions=ban , ну тут всё ясно, получаем список событий, у которых в поле actions находится значение - ban
| head 10 - оператор head возвращает 10 последних проиндексированных событий из множества событий полученного в результате предыдущего запроса 
| top srcip  - оператор top как понятно из названия позволяет получить топ значений какого-либо поля 
| fields - percent,count - оператор  fields позволяет исключить из запроса ненужные поля, в нашем случае percent, count (в первом поле процент событий с конкретным значением, а во втором количество событий)
| rename srcip as "IP-источника" - тут все очевидно, мы переименовываем поле для удобства чтения

Должен получится примерно следующий результат: 




Запрос ниже позволит получить список уникальных IP-адресов, сгруппированных по действию (Ban/Unban): 


sourcetype=fail2ban | stats values(srcip) as "Список IP-адресов" by actions | sort -count | rename actions as "Действие"





Замена данных в запросах


Не скажу что часто, но иногда бывает нужно на лету заменить значения пары полей из события, например, когда нужно вывести на дашборд показатель критичность равный не “1” ”2” ”3”, а «Критично», «Средне», «Некритично».
Для этого в Splunk есть оператор replace, пример работы ниже.

sourcetype=fail2ban | replace "Ban" with "Забанен", "Unban" with "Разбанен" in actions | table _time,srcip,actions | sort -_time


Тут я думаю всё очевидно, указываем что на что хотим поменять («value with «value 2»), и в каком поле (in «fields»). После этого строим таблицу и смотрим результат.


Группировка событий


Ну и напоследок немного о группировке событий. Запрос, представленный ниже, позволяет сгруппировать события по значению поля actions, и разделить на группы продолжительностью 1 день.

sourcetype=fail2ban | transaction actions maxspan=1d



В итоге получаем следующий результат:


На этом мы пока закончим, думаю, основной смысл вы уловили. Дополнительно почитать про поиск можно тут - http://docs.splunk.com/Documentation/Splunk/latest/SearchTutorial/Startsearching

Всем удачных экспериментов :)

Комментариев нет:

Отправить комментарий