Собираем, Парсим И Отправляем Логи С Помощью Logstash.

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

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

Наши программы, сервисы и серверы генерируют ОЧЕНЬ большое количество логов в день.

А необходимость копаться в бревнах постоянно растет. У меня была возможность работать с коммерческими продуктами управления журналами, такими как ArcSight, RSA Envision, Q1 Labs. У этих продуктов есть как плюсы, так и минусы.

Но в этой статье речь пойдет не о них.

Речь пойдет о Логсташ .

Что такое Логсташ? Зачем это нужно? Что он может сделать? Logstash — инструмент для сбора, фильтрации и нормализации логов.

Это бесплатное приложение с открытым исходным кодом.

Тип лицензии Apache 2.0. Мое первое знакомство с LS (Logstash) произошло больше года назад, и с тех пор я очень им подсел.

Мне нравится его идея и возможности.

Для меня Logstash — это мясорубка.

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

Формат файла конфигурации Logstash прост и понятен.

Он состоит из трех частей:

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   

input { .

} filter { .

} output { .

}

Может быть любое количество блоков ввода, фильтрации и вывода (или вывода?).

Все зависит от ваших потребностей и возможностей оборудования.

Пустые строки и строки, начинающиеся с # — Логсташ игнорирует. Так что комментирование файлов конфигурации не вызовет никаких проблем.



1. ВВОД

Этот метод является точкой входа для журналов.

Он определяет, по каким каналам логи будут поступать в Logstash. В этой статье я попытаюсь познакомить вас с основными типами, которые я использую — файловыми, tcp и udp. 1.1 файл Пример конфигурации для работы с локальными файлами журналов:

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"

тип/описание журнала.

При использовании нескольких входных блоков их удобно разделить для последующих действий в фильтре или выводе.



path => [ "/var/log/vs01/*.

log", "/var/log/vs02/*.

log" ]

указывает путь к файлам журналов, которые необходимо обработать.

Путь должен быть абсолютным (/path/to/logs/), а не относительным (.

/.

/some/other/path/).



exclude => [ "*.

gz", "*.

zip", "*.

rar" ]

исключает из обработки файлы с соответствующими расширениями.



start_position => "end"

ждет появления новых сообщений в конце файла.

При обработке существующих логов можно установить «начало», тогда логи будут обрабатываться построчно с начала файлов.



stat_interval => 1

как часто (в секундах) проверять файлы на наличие изменений.

При больших значениях частота системных вызовов уменьшится, но время чтения новых строк также увеличится.



discover_interval => 30

время (в секундах), по истечении которого список обработанных файлов, указанный в путь .

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

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

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

type => "webserver_prod"

тип/описание журнала.



data_timeout => 10

время (в секундах), по истечении которого неактивное TCP-соединение будет закрыто.

Значение -1 — соединение всегда будет открыто.



mode => "server" host => "192.168.3.12" port => 3337

в этом случае Logstash становится сервером и начинает прослушивать адрес 192.168.3.12:3337. При установке режим => "клиент" Logstash подключится к удаленному IP-порту для сбора журналов.

1.3 удап Для UDP настройки, аналогичные TCP:

input { udp { type => "webserver_prod" buffer_size => 4096 host => "192.168.3.12" port => 3337 } }



2. ФИЛЬТР

В этом блоке настраиваются основные манипуляции с логами.

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

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

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

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"

тип/описание журнала.

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



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

путь к каталогу, содержащему шаблоны обработки журналов.

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



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

указан шаблон для разбора логов.

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

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

Подробнее о шаблонах Используя грок фильтр может быть структурирован b О Большинство журналов — это системные журналы, apache, nginx, mysql и т. д., записанные в определенном формате.

Logstash имеет более 120 готовых шаблонов регулярных выражений.

Поэтому написание фильтров для обработки большинства журналов не должно вызывать особого страха или замешательства.

Формат шаблона относительно прост – ШАБЛОН НАЗВАНИЯ , то есть построчно указывается имя шаблона и соответствующее ему регулярное выражение.

Пример:

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

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

В этом примере журнала достаточно написать шаблон в виде " %{IP:клиент} %{СЛОВО:метод} %{URIPATHPARAM:запрос} %{NUMBER:байты} %{NUMBER:длительность} ", в этом случае все логи данного формата уже будут иметь определенную логическую структуру.

После обработки наша строка будет выглядеть так:

клиент: 55.3.244.1 метод: ПОЛУЧИТЬ запрос: /index.html байт: 15824 продолжительность: 0.043
Вы можете посмотреть список готовых шаблонов гроков Здесь .

2.2 мутировать Пример файла конфигурации для изменения/удаления записей из журналов:

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

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

type => "apache_access"

тип/описание журнала.

Указывает тип журналов, которые будут обрабатываться.



remove => [ "client" ]

удаление всех данных с именем поля клиент .

Можно указать несколько имен полей.



rename => [ "HOSTORIP", "client_ip" ]

переименование имени поля ХОСТОРИП В client_ip .



gsub => [ "message", "\\/", "_" ]

замена всех «/» на «_» в поле Сообщения .



add_field => [ "sample1", "from %{clientip}" ]

добавление нового поля «sample1» со значением «from %{clientip}».

Допускаются имена переменных.

2.3 дата Пример файла конфигурации:

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

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

type => "apache_access"

тип/описание журнала.

Указывает тип журналов, которые будут обрабатываться.



match => [ "timestamp", "MMM dd HH:mm:ss" ]

временный А Я лейбл мероприятия.

Важная настройка для дальнейшей возможности сортировки или выбора логов.

Если время в логах указано в формате unix timestamp (squid), то следует использовать match => ["timestamp", "UNIX"] 2,4 кВ Пример файла конфигурации для обработки логов в формате ключ=значение:

filter { kv { type => "custom_log" value_split => "=:" fields => ["reminder"] field_split => "\t?&" } }

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

type => "custom_log"

тип/описание журнала.

Указывает тип журналов, которые будут обрабатываться.



value_split => "=:"

используйте символы «=" и «:» для разделения ключей и значений.



fields => ["reminder"]

имя поля, в котором нужно искать ключ=значение.

По умолчанию разделение будет происходить по всей строке журнала.



field_split => "\t?&"

используйте символы «\t?&» для разделения клавиш.

\t — знак табуляции 2,5 многострочный Пример конфигурационного файла для «склеивания» многострочных логов (на примере трассировки стека Java):

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

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

type => "java_log"

тип/описание журнала.

Указывает тип журналов, которые будут обрабатываться.



pattern => "^\s"

регулярное выражение

what => "previous"

если шаблон «шаблон» совпадает, строка принадлежит предыдущей строке.



3. ВЫХОД

Название этого блока/метода говорит само за себя — оно задает настройки исходящих сообщений.

Как и в предыдущих блоках, здесь можно указать любое количество исходящих подблоков.

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

output { stdout { type => "custom_log" message => "IP - %{clientip}.

Full message: %{@message}.

End of line." } }



type => "custom_log"

тип/описание журнала.



message => "clIP - %{clientip}.

Full message: %{@message}.

End of line."

указывает формат исходящего сообщения.

Допустимо использование переменных после грок-фильтрации.

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

output { file { type => "custom_log" flush_interval => 5 gzip=> true path => "/var/log/custom/%{clientip}/%{type}" message_format => "ip: %{clientip} request:%{requri}" } }



type => "custom_log"

тип/описание журнала.



flush_interval => 5

интервал записи исходящих сообщений.

Значение 0 будет записывать каждое сообщение.



gzip=> true

Файл исходящего сообщения будет сжат с помощью Gzip.

path => "/var/log/custom/%{clientip}/%{type}"

путь и имя файла, в котором будут сохраняться исходящие сообщения.

Можно использовать переменные.

В этом примере для каждого уникального IP-адреса будет создана своя папка и сообщения будут записываться в файл, соответствующий переменной %{type}.



message_format => "ip: %{clientip} request:%{requri}"

формат исходящего сообщения.

3.3 поиск эластиков Пример файла конфигурации для записи логов в базу данных Elasticsearch:

output { elasticsearch { type => "custom_log" cluster => "es_logs" embedded => false host => "192.168.1.1" port => "19300" index => "logs-%{+YYYY.MM.dd}" } }



type => "custom_log"

тип/описание журнала.



cluster => "es_logs"

имя кластера, указанное в кластер.

имя в файле конфигурации Elasticsearch.

embedded => false

указывает, какую базу данных Elasticsearch использовать: внутреннюю или стороннюю.



port => "19300"

транспортный порт Elasticsearch.

host => "192.168.1.1"

IP-адрес Elasticsearch

index => "logs-%{+YYYY.MM.dd}"

имя индекса, куда будут записываться логи.

3.4 электронная почта Этот плагин можно использовать для оповещений.

Минус в том, что любые изменения уведомлений (в принципе, как и любые другие настройки) требуют перезапуска программы logstash, но разработчик говорит, что, возможно, в будущем этого делать не придется.

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

output { email { type => "custom_log" from => "[email protected]" to => "[email protected]" cc => "[email protected]" subject => "Found '%{matchName}' Alert on %{@source_host}" body => "Here is the event line %{@message}" htmlbody => "<h2>%{matchName}</h2><br/><br/><h3>Full Event</h3><br/><br/><div align='center'>%{@message}</div>" via => "sendmail" options => [ "smtpIporHost", "smtp.gmail.com", "port", "587", "domain", "yourDomain", "userName", "yourSMTPUsername", "password", "PASS", "starttls", "true", "authenticationType", "plain", "debug", "true" ] match => [ "response errors", "response,501,,or,response,301", "multiple response errors", "response,501,,and,response,301" ] } }



type => "custom_log"

тип/описание журнала.



from => "[email protected]" to => "[email protected]" cc => "[email protected]"

Если у вас есть силы дочитать до этих строк, то смысл этих 3-х настроек вы сможете определить сами :)

subject => "Found '%{matchName}' Alert on %{@source_host}"

тема электронного письма с уведомлением.

Можно использовать переменные.

Например, %{matchName} — это имя условия соответствия из настройки «match».



body => "Here is the event line %{@message}" htmlbody => "<h2>%{matchName}</h2><br/><br/><h3>Full Event</h3><br/><br/><div align='center'>%{@message}</div>"

основная часть письма.



via => "sendmail"

способ отправки письма.

Возможен один из двух вариантов — smtp или sendmail.

options => .



стандартные настройки почты.



match => [ "response errors", "response,501,,or,response,301", "multiple response errors", "response,501,,and,response,301" ]

«ошибки ответа» — имя оповещения (записано в переменной %{matchName}).

«response,501,,or,response,301» — критерии срабатывания оповещений.

В этом примере, если поле ответа содержит значение 501 или 301, оповещение считается сработавшим.

Во второй строке используется логика AND, т.е.

должны быть выполнены оба условия.



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}" } }

Запускаем Логсташ:

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. Если там появится секретное сообщение, значит все работает. P.s. Последнюю версию Logstash можно скачать.

отсюда .

Спасибо за внимание, Теги: #*nix #Системное администрирование #анализ #logstash #syslog-ng #logserver #управление журналами

Вместе с данным постом часто просматривают: