Система сбора, анализа, уведомлений и визуализации логов на syslog-ng, elasticsearch, kibana, grafana, elasticalert

**Что мы получим после этой статьи:**

Систему сбора и анализа логов на syslog-ng, elasticsearch в качестве хранилища данных, kibana и grafana в качестве систем визуализации данных, kibana для удобного поиска по логам, elasticalert для отправки уведомлений по событиям. Приготовьтесь, туториал объемный.

Какие логи будем собирать:
— все системные логи разложенные по индексам в зависимости от их facility(auth,syslog,messages и т.д.);
— логи nginx — access и error;
— логи pm2;
— и др.

**Обоснование выбора системы**

Почему я выбрал связку с syslog-ng в качестве отправителя, парсера и приемщика логов? Да потому что он очень быстрый, надежный, не требовательный к ресурсам(да да — logstash в качестве агентов на серверах и виртуальных машинах просто убожество в плане пожирания ресурсов и требованием java), с внятным синтаксисом конфигов(вы видели rsyslog? — это тихий ужас), с широкими возможностями — парсинг, фильтрация,большое количество хранилищ данных(postgresql,mysql,elasticsearch,files и т.д.),буферизация(upd не поддерживает буферизацию), сторонние модули и другие фишки.

**Требования:**

— Ubuntu 16.04 или debian 8-9;
— vm для развертывания;
— Прямые руки.

**Приступим или добро пожаловать под кат**

Небольшое пояснение.
Только кластер elasticsearch можно использовать в production, система из одной ноды просто загнется. В production используем кластер из master ноды и нескольких датанод. Отказоустойчивый кластер здесь рассматривать не будем. Кому интересно — вперед гуглить. Elastic рекомендует использовать одинаковую конфигурацию для нод кластера, так как кластер все равно будет работать со скоростью самой медленной ноды. Я использую ноды по 4 cpu и 12 gb озу и 700 gb ssd.

Наша система логов будет состоять из нескольких виртуальных машин — головного сервера(elasticnode1) и датанод elasticsearch(elasticnode2-9), на которых будут только храниться данные.

Сразу поправим файл /etc/hosts, если у вас нет настроенного dns сервера.

Меняем планировщика — у нас же ssd

Компоненты головного сервера
(elasticnode1):

— syslog-ng — наш главный приемщик, обработчик и отправитель логов;
— docker — в нем мы поднимем grafana, kibana,elasticalert;
— kibana — визуализация и поиск логов;
— grafana — визуализация и отправка уведомлений(на данный момент нельзя слать уведомления используя elasticsearch в качестве хранилища данных);
— elasticalert(через него и будем слать уведомления из elasticsearch в telegram — куда же без него );
— elasticsearch — собственно сюда и будем слать все наши данные с нод и отпарсенных файликов;
— ubuntu 16.04 в качетве ос.

Компоненты датанод(elasticнode2-elasticnode7):

— elasticsearch;
— ubuntu 16.04 в качестве ос.

Компоненты отправителей логов:

— ubuntu или debian;
— syslog-ng.

На данный момент появилась версия 6 продуктов elasticsearch, kibana и т.д., я же в production использую 5.6.3 — пока не было возможности мигрировать на последнюю версию.

**Настраиваем отправители логов.**

Устанавливаем syslog-ng последней версии. Ставить будем из репозитория. Здесь установка для Ubuntu 16.04.

Тюним sysctl.conf

Затираем

Вставляем

Применяем

**Настраиваем syslog-ng для парсинга и отправки логов с клиента на сервер.**

Приводим /etc/syslog-ng/syslog-ng.conf к такому виду.

Создаем конфиг отправки логов на сервер.

Вставляем сюда следующее содержимое

Таким образом мы все логи будем отправлять по udp на 514 порт сервера. Там он с ними разберется — разложит по индексам, отфильтрует и т.д.

**Настройка отправки nginx access и error логов через вывод содержимого лога и отправки по udp на обозначенные порты.**

Почему я выбрал вывод содержимого из файла и отправку по udp, а не прямую отправку из nginx на порт? У меня возникали непонятные баги при отправке логов напрямую из nginx(сервер начинал возвращать много 500 и 502 ошибок).

Настройка логов для отправки в nginx. Отредактируем конфиг nginx.conf.

Делаем рестарт nginx. Все логи будут падать(если у вам не переопределено в конфигах) в папку /var/log/nginx/ в 2 файла указанных выше.

Настраиваем syslog-ng на чтение файлов и отправку по udp.

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

**Настраиваем головной сервер с syslog-ng,elasticsearch,kibana,grafana и elasticalert.**

Для начала «тюним»» систему.

Тюним limits.conf

Затираем

Вставляем

* hard memlock unlimited
* soft memlock unlimited
root soft nproc unlimited
root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536
* — nofile 999999
elasticsearch soft nofile 65535
elasticsearch hard nofile 65535
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited

Проверяем

Тюним sysctl.conf

Затираем

Вставляем

Применяем

Отключаем swap.

Удаляем rsyslog

Собираем syslog-ng из исходников со всеми модулями последней версии для нашего сервера.

Зависимости:

Устанавливаем granle

Ставим java8 и экспортируем пути

Клонируем репозиторий syslog-ng, собираем и устанавливаем

Добавляем init.d скрипт — если вы ничего не меняли при сборке(пути) то все будет работать.

Даем ему права и делаем unmask

Устанавливаем elasticsearch из пакета deb.

Еще небольшие манипуляции. Создадим каталог для данных и сделаем автозапуск elasticsearch после рестарта системы.

Настроим elasticsearch на максимальное использование памяти. Для этого elasticsearch.service приводим к такому виду.

Релоадим systemctl после изменения

Отредактируем файл /etc/elasticsearch/jvm.options

Даем половину озу — у меня 12 гигабайт на VM — в heap space поставил 6g, по рекомендациям разработчиков elasticsearch.

Редактируем конфиг elasticsearch на нашем головном сервере. Приводим к виду

Здесь мы поменяли путь для данных, задали имя кластера, указали что он у нас является мастер нодой(управляет распределением данных в кластере), не является дата нодой(не хранит данные),указали список всех нод кластера, отключили swap для elasticsearch(bootstrap.memory_lock: true), указали минимальное количество мастер нод для нашего кластера — 1 (мы здесь не делаем HA).

Запускаем кластер elasticsearch, предварительно почистив старую дата директорию.

Смотрим здоровье кластера из консоли

**Настраиваем датаноды elasticsearch — elasticnode2-9**

Правим файл /etc/hosts как указано выше

Устанавливаем elasticsearch(не забываем про /usr/lib/systemd/system/elasticsearch.service и /etc/elasticsearch/jvm.options) и тюнингуем систему аналогично мастеру. Важно — обязательно должны быть одинаковые версии elasticsearch на всех нодах.

Конфиг elasticsearch на датаноде.

Здесь конфиг аналогично мастеру — мы поменяли путь для данных, задали имя кластера, указали что он у нас является датанодой(хранит данные),указали список всех нод кластера, отключили swap для elasticsearch(bootstrap.memory_lock: true), указали минимальное количество мастернод для нашего кластера — 1.

Стартуем ноды, предварительно стерев /var/lib/elasticsearch/ иначе будет выдавать ошибку, так как мы поменяли путь хранения данных.

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

Просто добавляем новую ноду в конфиги на все ноды кластера в строку discovery.zen.ping.unicast.hosts, при этом рестарт elasticsearch в текущем кластере делать не надо.

Запускаем процесс ребалансировки на головном сервере с помощью запроса через командную строку

Так же сразу потюним еще одну вещь cluster.routing.allocation.disk.watermark.

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

**Установка kibana и grafana на головной сервер.**

Kibana и grafana можно спокойно запускать через docker-compose, что мы и сделаем ниже. В принципе всю систему можно поднять через docker-compose. Ниже я выложу ссылку на репозиторий где все можно поднять одной командой, что в принципе для небольших систем и для тестирования вполне приемлимо. Докер это наше всё.

Ставим докер и docker-compose на ubuntu 16.04

Создаем файл docker-compose.yml с таким содержанием. Обратите внимание в enviroment kibana.local прописал

Содержимое docker-compose.yml

Запускаем docker-compose

В grafana по-умолчанию пользователь и пароль admin admin.

Заходим в kibana — видим что все ок.


Идем далее.

**Настройка приема системных логов syslog-ng, их обработки и отправки в kibana.**

Скачаем сразу базу данных geoip2 maxmind для построения в дальнейшем geoip карты. Анализатор(парсер) geoip2 syslog-ng 2 использует библиотеку maxminddb для поиска географической информации. По заверениям разработчиков он значительно быстрее, чем его предшественник, а также предоставляет более подробную информацию.

Скачаем и распакуем.

Сразу проверим на примере.

Окей. Идем далее.

Создадим симлинк каталога в который мы установили syslog-ng в /etc/syslog-ng — так удобнее, для тех кто привык к стандартному расположению конфигов syslog-ng.

Отредактируем главный конфиг — приведем к такому виду:

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

Теперь вставим конфиги по приему системных логов с других машин и отправку их в elasticsearch c разбиением по индексам.

Конфиги syslog-ng легко читаемы и понятны с первого раза. Не устану это повторять.

Теперь создадим конфиг для приема других логов — nginx access и error(php errors логи так же будем слать в error.log), nodejs.

Сохраняемся.

Поясню, какого вида имя index будет создаются в elasticsearch — формат имени будет иметь вид «базовоеимяиндекса-год.месяц», например nginx-access-geo-2018.01. В принципе здесь всё понятно, так как добавляется год и месяц после индекса — nginx-access-geo-${YEAR}.${MONTH}.

Подготовливаем индекс elasticsearch для примема логов nginx access — сделаем mapping для нашего первого индека nginx-access-geo-2018.01:

— поля nginx.upstream_response_time и nginx.request_time типом float вместо string, для возможности нахождения среднего значения по времени ответа сервера и ответа upstreams;
— создадим mapping в elasticsearch для geoip, чтобы можно было строить карту с помощью геолокации.

Важно. Всё это делает для индекса nginx-access-geo-2018.01(у нас так настроен формат в syslog-ng), т.е. после окончания месяца необходимо заново выполнить этот запрос, только вместо nginx-access-geo-2018.01 сделать nginx-access-geo-2018.02 и т.д.

Все эти манипуляции необходимо проделать до начала отправки логов в elasticsearch. Мы создадим шаблон для индекса nginx-access-geo-*, все данные для этого индекса будут маппиться.

Mapping для elasticsearch6

Увидели что все что нужно создано.

Проверяем syslog-ng, запускаем с выводом в консоль

Если ошибок нет — стартуем как демон

После определенного времени — когда к нам упадут логи заходим в elasticsearch и создаем наш индекс.

Получить список всех индексов elasticsearch и добавить» -*» в конце, для дальнейшего быстрого их добавления, можно командой:

Вывод

Обратите внимание что там окажутся некоторые ненужные для добавления индексы, такие как .kibana, elasticalert.

Индекс для kibana можно создать из консоли, что гораздо удобней. Для версии elasticsearch 5.6.3 это делается так:

Так мы создали наш индекс kern, с wildcard, т.е. для всех подиндексов.

**Сбор и отправка логов pm2 c помощью syslog-ng.**

Pm2 должен быть запущен со следующими опциями.

Создадим конфиг отправки на клиенте или допишем в существующий. Будем отсылать на отдельный порт.

На сервере создаем конфиг на принятие данного лога и его отправку в elasticsearch.

Перезапускаем syslog-ng на сервере и клиенте и добавляем индекс в kibana.

На этом настройка syslog-ng закончена.

**Поиск логов в kibana и построение визуализаций.**

Перейдем в наш индекс и сразу для проверки наших настроек попробуем найти все ответы сервера nginx, c временем ответа больше 2 секунд, для этого в поле делаем запрос nginx.request_time: [2 TO *].

Сверху выбираем период за который мы хотим получить события и частоту обновления данных. В данном случаем мы выбраои период 24 часа с частотой обновления данных 30 секунд.

Как мы видим на выдало 14 событий(hits).

Рассмотрим какие поля у нас доступны в нашем индексе. Раскрываем событие и выбираем там json представление.

Так же поля доступны слева на панели

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

У меня получился примерно такой вывод:

Добавляем индекс auth-*, в нем все события с авторизацией, sudo и др.

Перейдем к поиску и увидим события, связанные с авторизацией.

Таким же образом добавим другие индексы.

Настройки визуализации в kibana по логам.

Теперь сделаем визуализацию с помощью kibana логов nginx, например построим графики по среднему ответу сервера.

Выбираем visualize >> new >> line и выбираем наш index nginx-access-geo-*

В появившемся конструкторе делаем следующее:

— в «Metrics» — Y-Axis выбираем «Aggregation» >> «Average» и «Field» >> «nginx.request_time»;
— в «Buckets» — X-Axis Aggregation >> Date Histogram и Field >> @timestamp;
— в «Split series» в «Sub Aggregation» >> «Terms» «Field» >> «nginx.http_host.keyword» «Order by «>> «metric: Average nginx.request_time».

Нажимаем «Apply Changes»

Получаем такую картину.

Подобным образом и с помощью фильтров можно настроить графики по любым событиям и метрикам. Далее графики объединяются в дашборды.

**Настройка оповещений elasticalert в телеграмм.**

Устанавливаем elasticalert, поставим на наш головной сервер или куда угодно.

Создаем файл конфига

Создаем индекс elastalert-create-index, он нужен для работы сервиса.

Создадим тестовое правило срабатывания и отпраки уведомлений в телеграмм

В данном конфиге мы указали что будем использовать индекс nginx-access-geo-*, и что при получении в поле nginx.status значения 502 с хоста 10.12.1.39 и при методе GET 20 раз в течении 2 минут нам будет приходить уведомление в телеграмм.
Пробуем.

Запускаем elasticalert

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

Сообщение отправлено чего и требовалось добиться.
Делаем проверку среднего ответа сервера

Проверяем

Все работает.

Подробная документация по elasticalert здесь:

[https://github.com/Yelp/elastalert](https://github.com/Yelp/elastalert)

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

Как и обещал ранее — репозиторий с настроеной системой для тестирования в обертке docker-compose

[
https://github.com/galushkoav/ESKG](https://github.com/galushkoav/ESKG)

**Краткий справочник по командам elasticsearch.**

Смотрим список всех индексов в elasticsearch

Как удалить индекс из elasticsearch

Получить информацию об индексе elasticsearch

Настройка полей в elasticsearch. Данная команда уже была выше, но все равно оставим ее здесь.

Для elasticsearch6 маппинг делается так

Исправление ошибки

unexpected error while indexing monitoring document
elasticsearch6master_1 | org.elasticsearch.xpack.monitoring.exporter.ExportException

**Используемые источники**

2 thoughts on “Система сбора, анализа, уведомлений и визуализации логов на syslog-ng, elasticsearch, kibana, grafana, elasticalert

  1. Добрый.
    Спасибо ) Оч развернуто и наглядно.

Добавить комментарий

Войти с помощью: 

Ваш e-mail не будет опубликован. Обязательные поля помечены *

 

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.