Skip to content

Fluentd

Sayapin Alexander edited this page Jan 17, 2016 · 18 revisions

Fluentd logo Fluentd ( http://www.fluentd.org/ ) - система для сбора и обработки данных, основная задача которой построение единого унифицированного слоя журналирования.

Fluent schema

Fluentd написан на ruby и имеет множество плагинов для интеграции со сторонними сервисами.

Жизненный цикл сообщения в Fluentd можно разделить на 4 этапа.

  • Получение данных
  • Поиск соответствий
  • Фильтрация
  • Вывод данных

Структурно можно представить Fluentd так: Fluent structure

Fluent представляет данные как записи с набором полей, основными из которых являются:

  • tag - тэг записи для группировки
  • time - дата время
  • message - сообщение

Внутри fluentd использует message pack ( http://msgpack.org/ ), но вывод осуществляется в JSON. Таким образом, набор полей в записи может быть любым.

Архитектура Fluentd основана на плагинах, что позволяет расширять нужные части системы.

Шаг 0. Установка Fluentd

Установим fluentd на машину и напишем простой конфиг для обработки логов. Пример установки будет описан в Docker'е, хотя можно устанавливать и без него.

$ docker run --rm -it debian /bin/bash
# apt-get update
# apt-get install wget curl vim
# wget 'http://packages.treasuredata.com.s3.amazonaws.com/2/debian/jessie/pool/contrib/t/td-agent/td-agent_2.3.0-0_amd64.deb'
# dpkg -i td-agent_2.3.0-0_amd64.deb

Fluentd будет установлен в директорию /opt/td-agent. Init.d-скрипт будет находиться в /etc/init.d/td-agent, а конфиг по адресу: /etc/td-agent/td-agent.conf.

Перепишем конфиг таким образом, чтобы fluentd принимал логи по http на порту 8888 с использованием JSON, а также читал сообщения из файла /var/log/mylog.log (по аналогии с tail -F) и записывал их в файлы /tmp/myapp.*

/etc/td-agent/td-agent.conf

# Http приёмник
<source>
  @type http                      # тип источника - HTTP
  port 8888                       # порт
</source>


# Приёмник из файла
<source>
  @type tail                      # тип источника - tail -F
  path /var/log/mylog.log         # путь к файлу для слежения
  format none                     # тип формата - строка целиком без форматирования
  tag log                         # тэг для записи
</source>


# обработчик. ** -- обрабатывать все тэги
<match **>
  @type file                      # тип вывода в файл
  path /tmp/myapp                 # путь к файлу

  time_slice_format %Y%m%d        # формат даты в имени файла
  time_slice_wait 10m             # время ожидания после закрытия файла
  time_format %Y%m%dT%H%M%S%z     # формат даты для вывода в файле
</match>

перезапутим fluentd и попробуем что-то записать в приёмники и посмотрим результат.

# /etc/init.d/td-agent restart
[ ok rting td-agent: [....] td-agent.

# curl -X POST -d 'json={"action":"login","user":2}' http://localhost:8888/test.tag.here
# curl -X POST -d 'json={"key1":"value 1"}' http://localhost:8888/log          

# echo "test test" >> /var/log/mylog.log 
# date >> /var/log/mylog.log 
# date >> /var/log/mylog.log 

# cat /tmp/myapp.20160116.b52975f223f0805c7 
20160116T162353+0000	test.tag.here	{"action":"login","user":2}
20160116T162407+0000	log	{"key1":"value 1"}
20160116T162419+0000	log	{"message":"test test"}
20160116T162425+0000	log	{"message":"Sat Jan 16 16:24:25 UTC 2016"}
20160116T162425+0000	log	{"message":"Sat Jan 16 16:24:25 UTC 2016"}

Как видно записи из HTTP и из файла попадают в файл /tmp/myapp.20160116.b52975f223f0805c7. После того, как запись в файл будет завершена файл будет переименован в /tmp/myapp.20160116.log.

<source>
  @type http
  port 8888
</source>

<source>
  @type tail
  path /var/log/mylog.log
  format none
  tag myapp.error
</source>

<match **>
  @type router
  router_state_file /tmp/router_state.json
  inactivity_timeout 1000

  <config>
    type file
    path /tmp/<%=key[0]%>_<%=key[1]%>

    time_slice_format %Y%m%d%H%M
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%z

    host_param "#{Socket.gethostname}"
    format json
  </config>
</match>