Logstash: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
Строка 5: Строка 5:
 
=Logstash=
 
=Logstash=
 
Заметки по Logstash с примерами конфигов
 
Заметки по Logstash с примерами конфигов
  +
  +
<PRE>
  +
input {
  +
...
  +
}
  +
</PRE>
  +
<PRE>
  +
filter {
  +
...
  +
}
  +
</PRE>
  +
<PRE>
  +
output {
  +
...
  +
}
  +
</PRE>
  +
  +
==INPUT==
  +
Данный метод является входной точкой для логов
  +
  +
===File===
  +
</PRE>
  +
input {
  +
file {
  +
type => "some_access_log"
  +
path => [ "/var/log/vs01/*.log", "/var/log/vs02/*.log" ]
  +
exclude => [ "*.gz", "*.zip", "*.rar" ]
  +
start_position => "end"
  +
stat_interval => 1
  +
discover_interval => 30
  +
}
  +
}
  +
</PRE>
  +
<PRE>
  +
type => "some_access_log"
  +
тип/описание лога. При использовании нескольких входных блоков, удобно их разделять для последующих действий в filter или output.
  +
</PRE>
  +
<PRE>
  +
path => [ "/var/log/vs01/*.log", "/var/log/vs02/*.log" ]
  +
</PRE>
  +
указывается путь к лог-файлам, которые подлежат обработке. Путь должен быть абсолютным
  +
<PRE>
  +
exclude => [ "*.gz", "*.zip", "*.rar" ]
  +
исключает из обработки файлы с соответствующими расширениями.
  +
</PRE>
  +
<PRE>
  +
start_position => "end"
  +
ждёт появления новых сообщений в конце файла. При обработки уже имеющихся логов, можно выставить «beginning», тогда обработка логов будет происходить построчно с начала файлов.
  +
</PRE>
  +
<PRE>
  +
stat_interval => 1
  +
как часто (в секундах) проверять файлы на изменения. При больших значения, уменьшится частота системных вызовов, но так же увеличится время чтения новых строк.
  +
</PRE>
  +
<PRE>
  +
discover_interval => 30
  +
время (в секундах) через которое будет обновлён список обрабатываемых файлов указанных в path.
  +
</PRE>
  +
  +
===tcp===
  +
Пример конфигурации, для работы с логами удалённых сервисов:
  +
<PRE>
  +
input {
  +
tcp {
  +
type => "webserver_prod"
  +
data_timeout => 10
  +
mode => "server"
  +
host => "192.168.3.12"
  +
port => 3337
  +
}
  +
}
  +
</PRE>
  +
  +
Построчное описание настроек:
  +
<PRE>
  +
type => "webserver_prod"
  +
тип/описание лога.
  +
</PRE>
  +
<PRE>
  +
data_timeout => 10
  +
<PRE>
  +
время (в секундах), по истечении которого не активное tcp соединение будет закрыто. Значение -1 — соединение всегда будет открыто.
  +
<PRE>
  +
mode => "server"
  +
host => "192.168.3.12"
  +
port => 3337
  +
</PRE>
  +
в этом случае Logstash становится сервером, и начинает слушать на 192.168.3.12:3337. При установке mode => «client» Logstash будет присоединятся к удалённому ip:port для забора логов.
  +
  +
===udp===
  +
<PRE>
  +
Для udp настройки аналогичные tcp:
  +
input {
  +
udp {
  +
type => "webserver_prod"
  +
buffer_size => 4096
  +
host => "192.168.3.12"
  +
port => 3337
  +
}
  +
}
  +
</PRE>
  +
==FILTER==
  +
В данном блоке настраиваются основные манипуляции с логами. Это может быть и разбивка по key=value, и удаление ненужных параметров, и замена имеющихся значений, и использование geoip или DNS запросов для ип-адресов или названий хостов.
  +
  +
На первый взгляд применение фильтров может показаться сложным и нелогичным, но это не совсем так.
  +
===grok===
  +
Пример конфигурационного файла для основной нормализации логов:
  +
<PRE>
  +
filter {
  +
grok {
  +
type => "some_access_log"
  +
patterns_dir => "/path/to/patterns/"
  +
pattern => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"
  +
}
  +
}
  +
</PRE>
  +
  +
Построчное описание настроек:
  +
<PRE>
  +
type => "apache_access"
  +
</PRE>
  +
тип/описание лога. Здесь надо указать тот тип (type), который прописан в блоке input для которого будет происходить обработка.
  +
<PRE>
  +
patterns_dir => "/path/to/patterns/"
  +
</PRE>
  +
путь к каталогу, содержащим шаблоны обработки логов. Все файлы находящиеся в указанной папке будут загружены Logstash, так что лишние файлы там не желательны.
  +
<PRE>
  +
pattern => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"
  +
</PRE>
  +
указывается шаблон разборки логов. Шаблон можно использовать либо в конфигурационном файле, либо из файла шаблонов. Что бы не путаться, я для каждого формата логов создаю отдельный шаблонный файл.
  +
  +
==Подробнее про шаблоны==
  +
С помощью grok фильтра можно структурировать большую часть логов — syslog, apache, nginx, mysql итд, записанных в определённом формате.
  +
Logstash имеет более 120 шаблонов готовых регулярных выражений (regex). Так что написание фильтров для обработки большинства логов не должно вызвать особого страха или недопонимания.
  +
  +
Формат шаблонов относительно простой — NAME PATTERN, то есть построчно указывается имя шаблона и ему соответствующее регулярное выражение. Пример:
  +
NUMBER \d+
  +
WORD \b\w+\b
  +
USERID [a-zA-Z0-9_-]+
  +
  +
Можно использовать любой ранее созданный шаблон:
  +
USER %{USERID}
  +
  +
Шаблоны можно так же и комбинировать:
  +
CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4})
  +
WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})
  +
MAC (?:%{CISCOMAC}|%{WINDOWSMAC})
  +
  +
  +
Допустим формат логов у нас следующий:
  +
55.3.244.1 GET /index.html 15824 0.043
  +
  +
Среди готовых шаблонов, к счастью уже имеются некоторые регулярные выражения и не надо придумывать колёсное транспортное средство, приводимое в движение мускульной силой человека через ножные педали или через ручные рычаги (это я про велосипед если что).
  +
С данным примером лога достаточно pattern записать в виде "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}", в этом случае все логи с данным форматом будут уже иметь некую логическую структуру.
  +
После обработки наша строка будет выглядеть следующим образом:
  +
client: 55.3.244.1
  +
method: GET
  +
request: /index.html
  +
bytes: 15824
  +
duration: 0.043
  +
  +
  +
Со списком готовых grok-шаблонов можно познакомиться здесь.
  +
  +
  +
  +
==mutate==
  +
Пример конфигурационного файла для изменения/удаления записей из логов:
  +
filter {
  +
mutate {
  +
type => "apache_access"
  +
remove => [ "client" ]
  +
rename => [ "HOSTORIP", "client_ip" ]
  +
gsub => [ "message", "\\/", "_" ]
  +
add_field => [ "sample1", "from %{clientip}" ]
  +
}
  +
}
  +
  +
Построчное описание настроек:
  +
type => "apache_access"
  +
тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.
  +
  +
remove => [ "client" ]
  +
удаление всех данных имеющих название поля client. Возможно указание нескольких названий полей.
  +
  +
rename => [ "HOSTORIP", "client_ip" ]
  +
переименование название поля HOSTORIP в client_ip.
  +
  +
gsub => [ "message", "\\/", "_" ]
  +
замена всех "/" на "_" в поле messages.
  +
  +
add_field => [ "sample1", "from %{clientip}" ]
  +
добавление нового поля «sample1» со значением «from %{clientip}». Допускается использование названий переменных.
  +
  +
2.3 date
  +
Пример конфигурационого файла:
  +
filter {
  +
date {
  +
type => "apache_access"
  +
match => [ "timestamp", "MMM dd HH:mm:ss" ]
  +
}
  +
}
  +
  +
Построчное описание настроек:
  +
type => "apache_access"
  +
тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.
  +
  +
match => [ "timestamp", "MMM dd HH:mm:ss" ]
  +
временная метка события. Важная настройка для дальнейшей возможности сортировки или выборки логов. Если в логах время указано в unix timestamp (squid), то следует использовать match => [ «timestamp», «UNIX» ]
  +
  +
2.4 kv
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
2.5 multiline
  +
Пример конфигурационного файла для «склеивания» многострочных логов (например Java stack trace):
  +
filter {
  +
multiline {
  +
type => "java_log"
  +
pattern => "^\s"
  +
what => "previous"
  +
}
  +
}
  +
  +
Построчное описание настроек:
  +
type => "java_log"
  +
тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.
  +
  +
pattern => "^\s"
  +
регулярное выражение
  +
  +
what => "previous"
  +
при соответствии шаблону «pattern» строка принадлежит предыдущей (previous) строке.
  +
  +
  +
  +
3. OUTPUT
  +
Название этого блока/метода говорит само за себя — в нём указываются настройки для исходящих сообщений. Аналогично предыдущим блокам, здесь можно указывать любое количество исходящих подблоков.
  +
3.1 stdout
  +
  +
  +
  +
  +
  +
  +
  +
3.2 file
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
3.3 elasticsearch
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
3.4 email
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
  +
4. Итого
  +
  +
Создаём файл habr.conf:
  +
input {
  +
tcp {
  +
type => "habr"
  +
port => "11111"
  +
}
  +
}
  +
filter {
  +
mutate {
  +
type => "habr"
  +
add_field => [ "habra_field", "Hello Habr" ]
  +
}
  +
}
  +
output {
  +
stdout {
  +
type => "habr"
  +
message => "%{habra_field}: %{@message}"
  +
}
  +
}
  +
  +
  +
Запускаем Logstash:
  +
java -jar logstash-1.1.9-monolithic.jar agent -f ./habr.conf
  +
  +
Проверяем, что Logstash запущен:
  +
# netstat -nat |grep 11111
  +
Если порт 11111 присутствует, значит Logstash готов принимать логи.
  +
  +
В новом терминальном окне пишем:
  +
echo "Logs are cool!" | nc localhost 11111
  +
  +
Смотрим результат в окне где запущен Logstash. Если там появилось секретное послание, значит всё работает.

Версия 19:09, 7 августа 2021

Logstash

Заметки по Logstash с примерами конфигов

input {
  ...
}
filter {
  ...
}
output {
  ...
}

INPUT

Данный метод является входной точкой для логов

File

input {

 file {
   type => "some_access_log"
   path => [ "/var/log/vs01/*.log", "/var/log/vs02/*.log" ]
   exclude => [ "*.gz", "*.zip", "*.rar" ]
   start_position => "end"
   stat_interval => 1
   discover_interval => 30
 }

}

type => "some_access_log"
тип/описание лога. При использовании нескольких входных блоков, удобно их разделять для последующих действий в filter или output.
path => [ "/var/log/vs01/*.log", "/var/log/vs02/*.log" ]

указывается путь к лог-файлам, которые подлежат обработке. Путь должен быть абсолютным

exclude => [ "*.gz", "*.zip", "*.rar" ]
исключает из обработки файлы с соответствующими расширениями.
start_position => "end"
ждёт появления новых сообщений в конце файла. При обработки уже имеющихся логов, можно выставить «beginning», тогда обработка логов будет происходить построчно с начала файлов.
stat_interval => 1
как часто (в секундах) проверять файлы на изменения. При больших значения, уменьшится частота системных вызовов, но так же увеличится время чтения новых строк.
discover_interval => 30
время (в секундах) через которое будет обновлён список обрабатываемых файлов указанных в path.

tcp

Пример конфигурации, для работы с логами удалённых сервисов:

input {
  tcp {
    type => "webserver_prod"
    data_timeout => 10
    mode => "server"
    host => "192.168.3.12"
    port => 3337
  }
}

Построчное описание настроек:

type => "webserver_prod"
тип/описание лога.
data_timeout => 10
<PRE>
время (в секундах), по истечении которого не активное tcp соединение будет закрыто. Значение -1 — соединение всегда будет открыто.
<PRE>
mode => "server"
host => "192.168.3.12"
port => 3337

в этом случае Logstash становится сервером, и начинает слушать на 192.168.3.12:3337. При установке mode => «client» Logstash будет присоединятся к удалённому ip:port для забора логов.

udp

Для udp настройки аналогичные tcp:
input {
  udp {
    type => "webserver_prod"
    buffer_size => 4096
    host => "192.168.3.12"
    port => 3337
  }
}

FILTER

В данном блоке настраиваются основные манипуляции с логами. Это может быть и разбивка по key=value, и удаление ненужных параметров, и замена имеющихся значений, и использование geoip или DNS запросов для ип-адресов или названий хостов.

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

grok

Пример конфигурационного файла для основной нормализации логов:

filter {
  grok {
    type => "some_access_log"
    patterns_dir => "/path/to/patterns/"
    pattern => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"
  }
}

Построчное описание настроек:

type => "apache_access"

тип/описание лога. Здесь надо указать тот тип (type), который прописан в блоке input для которого будет происходить обработка.

patterns_dir => "/path/to/patterns/"

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

pattern => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"

указывается шаблон разборки логов. Шаблон можно использовать либо в конфигурационном файле, либо из файла шаблонов. Что бы не путаться, я для каждого формата логов создаю отдельный шаблонный файл.

Подробнее про шаблоны

С помощью grok фильтра можно структурировать большую часть логов — syslog, apache, nginx, mysql итд, записанных в определённом формате. Logstash имеет более 120 шаблонов готовых регулярных выражений (regex). Так что написание фильтров для обработки большинства логов не должно вызвать особого страха или недопонимания.

Формат шаблонов относительно простой — NAME PATTERN, то есть построчно указывается имя шаблона и ему соответствующее регулярное выражение. Пример: NUMBER \d+ WORD \b\w+\b USERID [a-zA-Z0-9_-]+

Можно использовать любой ранее созданный шаблон: USER %{USERID}

Шаблоны можно так же и комбинировать: CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4}) WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2}) MAC (?:%{CISCOMAC}|%{WINDOWSMAC})


Допустим формат логов у нас следующий: 55.3.244.1 GET /index.html 15824 0.043

Среди готовых шаблонов, к счастью уже имеются некоторые регулярные выражения и не надо придумывать колёсное транспортное средство, приводимое в движение мускульной силой человека через ножные педали или через ручные рычаги (это я про велосипед если что). С данным примером лога достаточно pattern записать в виде "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}", в этом случае все логи с данным форматом будут уже иметь некую логическую структуру. После обработки наша строка будет выглядеть следующим образом: client: 55.3.244.1 method: GET request: /index.html bytes: 15824 duration: 0.043


Со списком готовых grok-шаблонов можно познакомиться здесь.


mutate

Пример конфигурационного файла для изменения/удаления записей из логов: filter {

 mutate {
   type => "apache_access"
   remove => [ "client" ]
   rename => [ "HOSTORIP", "client_ip" ]
   gsub => [ "message", "\\/", "_" ]
   add_field => [ "sample1", "from %{clientip}" ]
 }

}

Построчное описание настроек: type => "apache_access" тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.

remove => [ "client" ] удаление всех данных имеющих название поля client. Возможно указание нескольких названий полей.

rename => [ "HOSTORIP", "client_ip" ] переименование название поля HOSTORIP в client_ip.

gsub => [ "message", "\\/", "_" ] замена всех "/" на "_" в поле messages.

add_field => [ "sample1", "from %{clientip}" ] добавление нового поля «sample1» со значением «from %{clientip}». Допускается использование названий переменных.

2.3 date Пример конфигурационого файла: filter {

 date {
   type => "apache_access"
   match => [ "timestamp", "MMM dd HH:mm:ss" ]
 }

}

Построчное описание настроек: type => "apache_access" тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.

match => [ "timestamp", "MMM dd HH:mm:ss" ] временная метка события. Важная настройка для дальнейшей возможности сортировки или выборки логов. Если в логах время указано в unix timestamp (squid), то следует использовать match => [ «timestamp», «UNIX» ]

2.4 kv






2.5 multiline Пример конфигурационного файла для «склеивания» многострочных логов (например Java stack trace): filter {

 multiline {
   type => "java_log"
   pattern => "^\s"
   what => "previous"
 }

}

Построчное описание настроек: type => "java_log" тип/описание лога. Указывается тип (type) логов с которыми будет происходить обработка.

pattern => "^\s" регулярное выражение

what => "previous" при соответствии шаблону «pattern» строка принадлежит предыдущей (previous) строке.


3. OUTPUT Название этого блока/метода говорит само за себя — в нём указываются настройки для исходящих сообщений. Аналогично предыдущим блокам, здесь можно указывать любое количество исходящих подблоков. 3.1 stdout




3.2 file







3.3 elasticsearch








3.4 email











4. Итого

Создаём файл habr.conf: input {

 tcp {
   type => "habr"
   port => "11111"
 }

} filter {

 mutate {
   type => "habr"
   add_field => [ "habra_field", "Hello Habr" ]
 }

} output {

 stdout {
   type => "habr"
   message => "%{habra_field}: %{@message}"
 }

}


Запускаем Logstash: java -jar logstash-1.1.9-monolithic.jar agent -f ./habr.conf

Проверяем, что Logstash запущен:

  1. netstat -nat |grep 11111

Если порт 11111 присутствует, значит Logstash готов принимать логи.

В новом терминальном окне пишем: echo "Logs are cool!" | nc localhost 11111

Смотрим результат в окне где запущен Logstash. Если там появилось секретное послание, значит всё работает.