Logstash: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
Строка 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 запущен:
- netstat -nat |grep 11111
Если порт 11111 присутствует, значит Logstash готов принимать логи.
В новом терминальном окне пишем: echo "Logs are cool!" | nc localhost 11111
Смотрим результат в окне где запущен Logstash. Если там появилось секретное послание, значит всё работает.