Статьи

Сенсу и Графит

Это было довольно интересно увидеть число людей вовлекаются с Sensu в последнее время, так как , судя по увеличению активности на #sensu канале на Freenode. Один из самых распространенных вопросов — как интегрировать Sensu и Graphite. В этой статье я расскажу о двух подходах к переносу метрик из Sensu в Graphite.

Помните: думайте о Sensu как о «маршрутизаторе мониторинга». В то время как мы собираемся показать, как перенести метрики в Graphite, точно так же легко перенести метрики в любую другую систему — Librato, Cube, OpenTSDB и т. Д. На самом деле, совсем не сложно будет перенести метрики в несколько графиков. бэкэнды в стиле разветвления.

Установить плагин vmstat-metrics

Для этого примера мы собираемся использовать плагин vmstat-metrics, который можно найти в репозитории sensu-community-plugins на github. Плагины в этом репо предназначены для черри, поэтому давайте просто возьмем тот, который нам интересен:

cd /etc/sensu/plugins/
sudo wget https://raw.github.com/sonian/sensu-community-plugins/master/plugins/system/vmstat-metrics.rb
sudo chmod +x vmstat-metrics.rb

Большинство, но не все плагины в хранилище sensu-community-plugins используют вспомогательные классы из sensu-plugin , поэтому нам нужно установить этот гем на узлах, на которых будет работать плагин vmstat-metrics.

sudo gem install sensu-plugin --no-rdoc --no-ri

Откройте vmstat-metrics.rb, и мы увидим, что он наследует большую часть сантехники от класса Sensu :: Plugin :: Metric :: CLI :: Graphite. Помните об этом при написании собственных плагинов для сбора метрик, это может сэкономить вам время

Давайте запустим плагин вручную, чтобы увидеть результат.

./vmstat-metrics.rb 
stats.swap.in   0   1328153991
stats.swap.out  0   1328153991
stats.memory.active 122160  1328153991
stats.memory.swap_used  8   1328153991
stats.memory.free   48556   1328153991
stats.memory.inactive   73704   1328153991
stats.cpu.waiting   1   1328153991
stats.cpu.idle  95  1328153991
stats.cpu.system    4   1328153991
...

Мы хотим настроить путь перед отправкой этих данных в Graphite, включая добавление имени хоста, чтобы отличать его от других хостов. Это можно сделать с помощью ключа –scheme:

./vmstats-metrics.rb --scheme stats.`hostname -s`
stats.host01.swap.in    0   1328155423
stats.host01.swap.out   0   1328155423
stats.host01.memory.active  122512  1328155423
stats.host01.memory.swap_used   8   1328155423
stats.host01.memory.free    43856   1328155423
stats.host01.memory.inactive    75120   1328155423
stats.host01.cpu.waiting    1   1328155423
stats.host01.cpu.idle   95  1328155423
stats.host01.cpu.system 4   1328155423
...

Если вы знакомы с Graphite, это должно выглядеть знакомо. Эти данные соответствуют формату Graphite «stat.name value timestamp», и мы можем передать их непосредственно в Graphite с помощью нескольких различных методов.

Создать чек .json

Давайте передадим определение проверки нашим узлам, работающим на узлах sensu-client и sensu-server. Не забудьте установить плагин и драгоценный камень sensu-plugin.

Файл: /etc/sensu/conf.d/metrics_vmstat.json:

{
  "checks": {
    "vmstat_metrics": {
      "type": "metric",
      "handlers": ["graphite"], 
      "command": "/etc/sensu/plugins/vmstat-metrics.rb --scheme stats.:::name:::",
      "interval": 60,
          "subscribers": [ "webservers" ]
    }
  }  
}

В этом определении проверки есть два новых элемента, которые мы еще не рассмотрели:

  • Первый — это новый атрибут: «тип»: «метрика». Это очень важно. Он сообщает Sensu-серверу отправлять вывод каждого вызова этой проверки указанным обработчикам. Обычно, только проверки, которые возвращают ненулевое состояние завершения, указывающее, что неудачная проверка передается на обработчики Однако для метрик мы всегда хотим отправлять вывод обработчикам.
  • Вторым является использование «пользовательской переменной» в команде: ::: name :::. Sensu заменит это во время выполнения атрибутом name из клиентского раздела конфигурации Sensu. Есть много других вещей, которые мы можем сделать с пользовательскими переменными, которые будут рассмотрены в будущих блогах.

Далее нам нужно создать обработчик, чтобы что-то делать с этими данными. Поскольку в этом примере мы используем Graphite, мы рассмотрим два метода для переноса этих данных в графит: прямой TCP и AMQP.

Метод 1 — прямой TCP (через netcat) обработчик

Первый способ — просто отправить эти данные в Graphite через сокет TCP с помощью netcat. Это очень простой подход, который должен работать на большинстве компьютеров (с установленным netcat) и не требует настройки Graphite для использования AMQP.

Извлеките graphite_tcp.rb из репозитория sensu-community-plugins и скопируйте в / etc / sensu / handlers.

Затем создайте /etc/sensu/conf.d/graphite_tcp.json файл конфигурации:

{
  "graphite": {
    "server":"graphite.example.com",
    "port":"2003"
  }
}

Создайте /etc/sensu/conf.d/handler_graphite.json:

{
  "handlers": {
    "graphite": {
      "type": "pipe",
      "command": "/etc/sensu/handlers/graphite_tcp.rb"
    }
  }
}

Перезапустите sensu-сервер, и вы должны увидеть метрики vmstat, отображаемые в Graphite.

Однако у этого подхода есть и обратная сторона — масштабируемость. Для каждой полученной метрики sensu-сервер будет разветвляться и выполнять этот обработчик. При большом количестве узлов, множестве проверок, генерирующих метрики, и небольшом интервале, это может быстро привести к тому, что десятки или сотни недолговечных процессов будут разветвлены на Sensu-сервере.

Способ 2 — встроенный обработчик AMQP

Помните, что я продолжаю называть Sensu «маршрутизатором мониторинга»? Поскольку Sensu и Graphite оба используют протокол обмена сообщениями AMQP, мы можем настроить sensu-server таким образом, чтобы он выводил результаты проверки непосредственно из очереди rabbitmq и копировал ее в новую очередь в формате для Graphite. Этот подход должен быть очень быстрым и очень масштабируемым.

Сконфигурируйте углеродный кэш Graphite для AMQP:

/opt/graphite/conf/carbon.conf:

ENABLE_AMQP = True
# AMQP_VERBOSE = True
AMQP_HOST = sensu.example.com
AMQP_PORT = 5672
AMQP_VHOST = /sensu
AMQP_USER = sensu
AMQP_PASSWORD = mypass
AMQP_EXCHANGE = metrics
AMQP_METRIC_NAME_IN_BODY = True

Важной частью этой конфигурации является AMQP_METRIC_NAME_IN_BODY = True, что означает, что Graphite будет определять имя метрики из содержимого сообщения, а не через ключ маршрутизации. Смотрите здесь для получения дополнительной информации.

Далее мы настраиваем обработчик на сервере sensu, который будет отправлять метрики в очередь, которую прослушивает Graphite:

Отредактируйте /etc/sensu/conf.d/handler_graphite.json:

{
  "handlers": {
    "graphite": {
      "type": "amqp",
      "exchange": {
        "type": "topic",
        "name": "metrics",
        "passive": "true"
      },
      "send_only_check_output": true
    }
  }
}

Несколько вещей, чтобы отметить здесь:

  • «type»: «amqp»: мы говорим sensu-server, что этот обработчик перенаправит вывод проверки на обмен AMQP.
  • «passive»: «true»: мы говорим Sensu пассивно подключиться к обмену. Мы делаем это, потому что мы предполагаем, что Graphite уже создал обмен.
  • «send_only_check_output»: true: это указывает Sensu-серверу отправлять только необработанный вывод (из stdout), возвращенный проверкой, в обмен AMQP. По умолчанию sensu-server отправляет весь документ JSON с другими метаданными, но Graphite не знает, что делать с этими данными.

Советы по отладке:

Для отладки стороны Graphite может быть полезно включить AMQP_VERBOSE = True в carbon.conf. Если эта опция включена, в listener.log будет видно следующее, когда метрика успешно получена из rabbitmq в Graphite:

02/02/2012 10:11:11 :: Message received: Method(name=deliver, id=60) ('graphite_consumer', 8, False, 'metrics', '') content = <Content instance: body='test.sensu-server.swap.in\t0\t1328195471\ntest.sensu-server.swap.out\t0\t1328195471\ntest.sensu-server.memory.active\t126856\t1328195471\ntest.sensu-server.memory.swap_used\t8\t1328195471\ntest.sensu-server.memory.free\t52528\t1328195471\ntest.sensu-server.memory.inactive\t57952\t1328195471\ntest.sensu-server.cpu.waiting\t1\t1328195471\ntest.sensu-server.cpu.idle\t95\t1328195471\ntest.sensu-server.cpu.system\t4\t1328195471\ntest.sensu-server.cpu.user\t0\t1328195471\ntest.sensu-server.system.interrupts_per_second\t89\t1328195471\ntest.sensu-server.system.context_switches_per_second\t476\t1328195471\ntest.sensu-server.io.received\t8\t1328195471\ntest.sensu-server.io.sent\t17\t1328195471\ntest.sensu-server.procs.waiting\t4\t1328195471\ntest.sensu-server.procs.uninterruptible\t0\t1328195471\n', children=[], properties={'priority': 0, 'content type': 'application/octet-stream', 'delivery mode': 1}>
02/02/2012 10:11:11 :: Metric posted: test.sensu-server.swap.in 0 1328195471
02/02/2012 10:11:11 :: Metric posted: test.sensu-server.swap.out 0 1328195471
02/02/2012 10:11:11 :: Metric posted: test.sensu-server.memory.active 126856 1328195471
...