У меня есть следующий фильтр, который удовлетворяет большинство моих потребностей:
filter {grok {
match => { "message" => [ "%{IPORHOST:clientip} - %{NGUSER:user} \[%{HTTPDATE:timestamp}\] (?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest}) %{NUMBER:response} (?:%{NUMBER:bytes}|-) (-|(%{DATA:referrer})) ] }
Однако некоторые (не все) журналы, которые я анализирую, содержат имя канала, который пользователь использует на моем сервере Apache.
Обычный журнал, включающий слово «канал», будет выглядеть так:
10.40.80.11 - [email protected] [03/янв/2014:13:08:21 +0000] "GET /cgi-bin/feed/epg?channel=Bloomberg%20English&date=2016-01-03 HTTP/1.1" 200 368 "http://example.net/cgi-bin/feed/epg" "Мозилла/5.0"
Поле «rawrequest» сохраняется в отдельном поле, например:
"GET /cgi-bin/feed/epg?channel=Bloomberg%20English&date=2016-04-04 HTTP/1.1"
Вопрос: Как сохранить названия каналов в отдельном поле, ведь не во всех логах в поле «rawrequest» есть слово «канал»?
Я видел много примеров, но ничего подобного. Символ, отделяющий канал от остальной части строки, - "&". Буду признателен за любую помощь.
Решение:
match => { "request" => [ "channel=(?<Channels>[^&]+)" ] }