Thank you for reading this post, don't forget to subscribe!
Принцип работы fluentd очень простой. Он принимает данные от различных источников, проверяет есть ли соответствие по определенному критерию. После проверки отправляет полученное сообщение на хранение или обработку.
Конфигурационный файл находится по адресу /etc/td-agent/td-agent.conf
и состоит из 6ти так называемых секций. Основные мы сейчас рассмотрим.
- source — секция описывает источник данных. В этом разделе мы описываем то, откуда к нам поступают данные, их источник.
- match — эта секция описывает, что нам делать с данными, куда их направить. Будь это передача другому приложению или запись в файл.
- filter — не часто приходится использовать эту секцию, позволяет нам изменять полученные данные.
- system — содержит настройки приложения.
- label — позволяет объединить секции match и filter. Упрощает внутренний роутинг, грубо говоря, будем в конфигурации использовать меньше тегов.
- include — позволяет подключать конфигурационные файлы. Полезно при большом количестве источников.
Основное назначение разделов конфигурации разобрали, теперь приступим к настройке. Будем с одной машины отправлять логи при помощи rsyslog по tcp протоколу.
Создание файла конфигурации
Для упрощения редактирования я создал новый файл в директории /etc/td-agent
— host.conf
. В основном файле конфигурации td-agent.conf
, который расположен в этой же директории, добавил строчку в конце @include host.conf
. Теперь конфигурационный файл готов к правкам, откроем наш созданный host.conf
.
source
Как и писал выше, в этом разделе мы будем описывать источник данных для хранения. Мы будем принимать логи по сети от другого сервера и складывать их у себя в определенной папке. Для этого добавим в конфиг следующее:
[codesyntax lang="php"]
1 2 3 4 5 |
<source> type syslog port 42185 tag rsyslog </source> |
[/codesyntax]
Этот конфиг говорит нам, что мы будем использовать входящий плагин syslog
, слушать он будет порт 42185
, на этот порт мы будем отправлять логи из других машин и помечать тегом rsyslog
, этот тег мы будем использовать в секции match
.
Source: откуда брать данные
В блоке source содержится информация о том, откуда нужно брать данные. Fluentd может принимать данные из различных источников: это логи приложений на различных языках программирования (Python, PHP, Ruby, Scala, Go, Perl, Java), логи баз данных, логи с различных аппаратных устройств, данные утилит мониторинга…. С полным списком возможных источников данных можно ознакомиться здесь. Для подключение источников используются специализированные плагины.
В число стандартных плагинов вхoдят http (используется для приёма HTTP-сообщений) и forward (используется для приёма TCP-пакетов). Можно использовать оба этих плагина одновременно.
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 |
# Принимаем события с порта 24224/tcp <source> type forward port 24224 </source> # http://this.host:9880/myapp.access?json={"event":"data"} <source> type http port 9880 </source> |
Как видно из приведённого примера, тип плагина указывается в директиве type, а номер порта — в директиве port.
Количество источников данных ничем не ограничено. Каждый источник данных описывается в отдельном блоке <source>.
Все события, принятые из источников, передаются маршрутизатору сообщений. Каждое событие имеет три атрибута: tag, time и record. На основании атрибута tag принимается решение о том, куда должны быть перенаправлены события (подробнее об этом пойдёт речь ниже). В атрибуте time указывается время (это делается автоматически), а в атрибуте record — данные в формате JSON.
Приведём пример описания события:
1 2 3 4 |
# generated by http://this.host:9880/myapp.access?json={"event":"data"} tag: myapp.access time: (current time) record: {"event":"data"} |
match
Сообщения мы уже можем принимать, теперь нужно их обработать. Конфигурация обработчика:
[codesyntax lang="php"]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<match rsyslog.**> type copy <store> type file path /var/log/fluent/adminnotes append true time_slice_format %Y%m%d time_slice_wait 10m time_format %Y%m%dT%H%M%S%z compress gzip utc </store> </match> |
[/codesyntax]
Здесь я буду использовать плагин copy
, так как в будущем собираюсь не только сохранять логи в файл, но и отправлять в другие источники, поэтому type
указываем copy
. Далее внутри match
объявляем секцию store
в которой используем плагин file
. Этот плагин записывает поступающие сообщения в файл, в данной конфигурации есть опция time_slice_format %Y%m%d
, она говорит, что нужно сохранять один файл на в сутки. Другими словами, на одни сутки у нас будет один файл с логом.
Все, теперь мы готовы принимать логи. Перезапустим fluentd
(/etc/init.d/td-agent restart
) и приступим к настройке rsyslog
на машине-отправителе.
Match: что делать с данными
В секции Match указывается, по каком признаку будут отбираться события для последующей обработки. Для этого используются специализированные плагины.
К стандартным плагинам вывода относятся match и forward:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Получаем события с порта 24224 <source> type forward port 24224 </source> # http://this.host:9880/myapp.access?json={"event":"data"} <source> type http port 9880 </source> #Берём события, помеченные тэгами "myapp.access" #и сохраняем их в файле/var/log/fluent/access.%Y-%m-%d #данные можно разбивать на порции с помощью опции time_slice_format. <match myapp.access> type file path /var/log/fluent/access </match> |
В приведённом фрагменте указано, что все события, отмеченные тэгами myapp и access, нужно сохранять в файле, путь к которому указывается в директиве path. Обратим внимание на то, что события, которые помимо тэгов myapp и access отмечены ещё и другими тэгами, в файл отправлены не будут.
Кратко рассмотрим особенности синтаксиса директивы match:
- символ * означает соответствие любой части тэга (если указать <match a.*>, то a.b будет соответствовать заданному условию, а a.b.c — нет);
- ** означает соответствие любому тэгу (если указать <match **>, то заданному условию будут соответствовать и a, и a.b., и a.b.c);
- {x, y, z} означает соответствие по крайней мере одному из тэгов, указанных в фигурных скобках (если указать <match {a, b}>, то а и b будут соответствовать заданному условию, а с — нет);
- фигурные скобки можно использовать в сочетании с символами * и **, например: <match {a, b}. c.*> или <match {a.*, b}.c>*;
- <match a b> означает соответствие тэгам a и b одновременно;
- <match a.** b.*> означает соответствие тэгам a, a.b и a.b.c (первая часть) и b.d (вторая часть).
Fluentd проверяет события на соответствие тэгам в том порядке, в котором блоки match следуют друг за другом в конфигурационном файле. Сначала указываются соответствия частного характера, а затем — более общие соответствия. Если это правило нарушено, Fluentd корректно работать не будет. Так, фрагмент вида
1 2 3 4 5 6 7 8 9 10 |
<match **> type blackhole_plugin </match> <match myapp.access> type file path /var/log/fluent/access </match> |
содержит ошибку: сначала в нём указаны предельно общие совпадения (<match **> означает, что в файл нужно записывать события, отмеченные любым тэгом), а затем — частные. Допущенная ошибка приведёт к тому, что события с тэгами myapp и access записываться вообще не будут. Чтобы все работало так, как надо, фрагмент должен выглядеть так:
1 2 3 4 5 6 7 8 |
<match myapp.access> type file path /var/log/fluent/access </match> <match **> type blackhole_plugin </match> |
Include: объединяем конфигурационные файлы
Директивы можно импортировать из одного конфигурационного файла в другой и объединять. Эта операция осуществляется в блоке include:
1 2 |
include config.d/*.conf |
В этой директиве можно указывать путь к одному или нескольким файлам с указанием маски или URL:
1 2 3 4 5 6 7 8 9 10 11 12 |
# абсолютный путь к файлу include /path/to/config.conf # можно указывать и относительный путь include extra.conf # маска include config.d/*.conf # http include http://example.com/fluent.conf |
System: устанавливаем дополнительные настройки
В блоке System можно установить дополнительные настройки, например, задать уровень логгирования (подробнее см. здесь), включить ии отключить опцию удаления повторяющихся записей из логов и т.п.
Поддерживаемые типы данных
Каждый плагин для Fluentd обладает определённым набором параметров. Каждый параметр в свою очередь ассоциируется с определенным типом данных.
Приведём список типов данных, которые поддерживаются в Fluentd:
- string — строка;
- integer — целое число;
- float — число с плавающей точкой;
- size — число байт; возможны следующие варианты записи:
- <целое число>k — размер в килобайтах;
- <целое число>g — размер в гигабайтах;
- <целое число>t — размер терабайтах;
- если никакой единицы измерения не указано, то значение в поле size будет воспринято как число байт.
- time — время; возможны следующие варианты записи:
- <целое число>s — время в секундах;
- <целое число>m — время в минутах;
- <целое число>h — время в часах;
- <целое число>d — время в днях;
- если никакой единицы измерения не указано, что значение в поле time будет воспринято как количество секунд.
- array — массив JSON;
- hash — объект JSON.
Плагины Fluentd: расширяем возможности
В Fluentd используется 5 типов плагинов: плагины вывода, плагины ввода, плагины буферизации, плагины форм и плагины парсинга.
Плагины ввода
Плагины ввода используются для получения логов из внешних источников. Обычно такой плагин создает потоковый сокет (thread socket) и прослушивающий сокет (listen socket). Можно также настроить плагин так, что он будет получать данные из внешнего источника с определённой периодичностью.
К плагинам ввода относятся:
- in_forward — прослушивает TCP-сокет;
- in_http — принимает сообщения, передаваемые в POST-запросах;
- in_tail — считывает сообщения, записанные в последних строках текстовых файлов (работает так же, как команда tail -F);
- in_exec — с помощью этого плагина можно запускать стороннюю программу и получать её лог событий; поддерживаются форматы JSON, TSV и MessagePack;
- in_syslog — с помощью этого плагина можно принимать сообщения в формате syslog по протоколу UDP;
- in_scribe — позволяет получает сообщения в формате Scribe (Scribe — это тоже коллектор логов, разработанный Facebook).
Плагины вывода
Плагины вывода делятся на три группы:
- плагины без буферизации — не сохраняют результаты в буфере и моментально пишут их в стандартный вывод;
- с буферизацией — делят события на группы и записывают поочередно; можно устанавливать лимиты на количество хранимых событий, а также на количество событий, помещаемых в очередь;
- с разделением по временным интервалам — эти плагины по сути являются разновидностью плагинов с буферизацией, только события делятся на группы по временным интервалам.
К плагинам без буферизации относятся:
- out_copy — копирует события в указанное место (или несколько мест);
- out_null — этот плагин просто выбрасывает пакеты;
- out_roundrobin — записывает события в различные локации вывода, которые выбираются методом кругового перебора;
- out_stdout — моментально записывает события в стандартный вывод (или в файл лога, если он запущен в режиме демона).
В число плагинов с буферизацией входят:
- out_exec_filter — запускает внешнюю программу и считывает событие из её вывода;
- out_forward — передаёт события на другие узлы fluentd;
- out_mongo (или out_mongo_replset) — передаёт записи в БД MongoDB.
Плагины буферизации
Плагины буферизации используются в качестве вспомогательных для плагинов вывода, использующих буфер. К этой группе плагинов относятся:
- buf_memory — изменяет объём памяти, используемой для хранения буферизованных данных (подробнее см. в официальной документации);
- buf_file — даёт возможность хранить содержимое буфера в файле на жёстком диске.
Более подробно о том, как работают плагины буферизации, можно прочитать здесь.
Плагины форматирования
С помощью плагинов форматирования можно изменять формат данных, полученных из логов. К стандартным плагинам этой группы относятся:
- out_file — позволяет кастомизировать данные, представленные в виде «время — тэг — запись в формате json»;
- json — убирает из записи в формате json поле «время» или «тэг»;
- ltsv — преобразует запись в формат LTSV;
- single_value — выводит значение одного поля вместо целой записи;
- csv — выводит запись в формате CSV/TSV.
Более подробно о плагинах форматирования можно прочитать здесь.
Плагины парсинга
Эти плагины использутся для того, чтобы парсить специфические форматы данных на входе в случаях, когда это невозможно сделать при помощи штатных средств. С подробной информацией о плагинах парсинга можно ознакомиться здесь.
Естественно, что все плагины fluentd в рамках обзорной статьи описать невозможно — это тема для отдельной публикации. С полным списком всех существующих на сегодняшний день плагинов можно ознакомиться на этой странице.
Общие параметры для всех плагинов
Для всех плагинов указываются также следующие параметры:
- type — тип;
- id — идентификационный номер;
- log_level — уровень логгирования (см. выше).
На официальном сайте fluentd выложены готовые конфигурационные файлы, адаптированные под различные сценарии использования (см. здесь).
Вывод данных и интеграция с другими решениями
Собранные с помощью Fluentd могут быть переданы для хранения и дальнейшей обработки в базы данных (MySQL, PostgreSQL, CouchBase, CouchDB, MongoDB, OpenTSDB, InfluxDB) распределенные файловые системы (HDFS — см. также статью об интеграции Fluentd c Hadoop) облачные сервисы (AWS, Google BigQuery), поисковые инструменты (Elasticsearch, Splunk, Loggly).
Для обеспечения возможности поиска и визуализации данных довольно часто используется комбинация Fluentd+Elasticsearc+Kibana (подробную инструкцию по установке и настройке см., например, здесь).
Полный список сервисов и инструментов, которым Fluentd может передавать данные, размещён здесь. На официальном сайте опубликованы также инструкции по использованию Fluentd в связке с другими решениями.
Rsyslog
Rsyslog — популярный, быстрый, гибкий сервис для управления логами. Нам он нужен в частности, чтобы отдавать логи на машину с установленным fluentd.
Установка rsyslog
Установка очень тривиальна и проста, запуск одной команды сделает всё за вас:
yum install rsyslog
Настройка отправки логов
Открываем файл конфигурации nano /etc/rsyslog.conf
и вносим правки(под sudo разумеется):
1
|
*.* @10 .0.2.15:42185 |
Я добавил эту строку вначале файла, естественно адрес и порт указываем того хоста, который будет принимать логи. Теперь все логи которые описаны в конфигурационных файлах будут успешно доставлены на машину с fluentd демоном. Перезапускаем service rsyslog restart
и через некоторое время по указанному пути, который мы указали в конфиге fluentd, обнаружим файлы с логами от удаленного сервера.
Вот таким простым способом мы можем сделать самую элементарную схему отправки и хранения логов на специальном сервере.
======================================================