Useful monitoring tools with riemann
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
app
bin
debian
examples
lib
tests
.gitignore
.travis.yml
CHANGELOG
Gemfile
LICENSE.txt
README.md
Rakefile
Vagrantfile
kurchatov.gemspec

README.md

Gem Version Build Status Code Climate

Kurchatov

Перед вами гем для мониторинга с помощью riemann. Я люблю chef и ohai, поэтому здесь есть немного первого и немного второго.

Юзкейз таков:

  • Kurchatov попадает в среду (окружение, приложения) которую не знает, и изучает ее с помощью ohai
  • Решает какие плагины запускать
  • Отсылает сообщения на riemann-хост со присвоеными статусами

DSL

Решено использовать dsl для написания плагинов, плагин выглядит так:

name "человеко читаемое имя" # по дефолту basename файла
interval 60 # с какой переодичностью будет запускаться плагин
always_start true # плагину не нужны дополнительные настройки

default[:nginx][:file] = "/etc/nginx/nginx.conf"
default[:nginx][:cmd] = "nginx -t" # дефолтные значение для Mashie: 'plugin'
default[:nginx][:url] = "http://127.0.0.1:133233/status" # данные значения смержаться со значениями
                                                         # полученными из конфига

run_if :os => 'linux' do # по умолчанию разрешено запускать все и везде
  File.exists? plugin.file # plugin - не что иное как проставленые значения из default
                           # доступно обращение plugin[:file], plugin["file"], plugin.file
end

collect :web_some_platform => true, :os => 'linux' do # значение полученные через ohai, 
                                                    # collect включиться ohai[:web_some_platform] == true и
                                                    # для ohai[:os] == 'linux'
  metric = rest_get(default[:nginx][:url]).split("\n").first.split("Active connections:").last.to_i
  event(
    :service => "nginx active connections",          # по дефолту name, если редиректим в graphite
    :metric => metric,                               # то service будет ключем для url
    :warning => 10,
    :critical => 20,
    :diff => true, # говорим что запоминать предыдущие значения и если разница между новым и старым
                   # меньше warning - получим статус 'ok', больше critical - 'critical' и так далее
                   # без :diff мы будем считать честные значения
                   # для того чтобы посчитать RPS мы просто делим метрику на interval
    :description => "Что-то для человека-монитора" # допустимо сокращения :desc
  )

  event(
    :service => "nginx test config #{plugin.file}",  # сервис должен быть человекочитаемым но уникальным!
    :state => shell_out("#{ohai[:nginx][:cmd]}").exitstatus == 0  # если :state == true стейт "ok", иначе - "critical"
                                              # shell_out! - сгенерит exception и riemann уйдет сообщение об ошибке
                                              # в плагине, также доступен просто shell() - он вернет только stdout и
                                              # действует как shell_out!
    :desc => "Ой, конфиг не валидный, наверно nginx -t его испортил :("
  )

end

Если плагин отправил event, это не означает что он попадает на riemann-server:

  • Эвенты группируются и отсылаются асинхронно пачками (все что накопилось за Kurchatov::Responders::Riemann::FLUSH_INTERVAL по дефолту 0.5 секунд)
  • При отсутвии метрики второй и последующий раз :state == "ok" не будет отсылаться

Helpers

  • stop! - останавливает запущенный плагин
  • rest_get("http://user:password@host/uri") - body
  • rest_get("/tmp/file") - body
  • http_get("http://ya.ru") - body и http_code. если http_code == 0 - возвращает на SocketError
  • runit_service_stat("service_name") - service status. unknown если неизвестный сервис
  • runit_service_running?("service_name") - true если сервис запущен
  • runit_service_uptime("service_name") - аптайм сервиса, -1 в случае ошибки

Больше примеров вы найдете тут.

Ohai

И в африке ohai. Минимальный пример:

provides "postgres"
postgres Mash.new
cmd = "psql -U postgres -tqc 'select version()'"
status, stdout, stderr = run_command(:command => cmd)
postgres[:version] = stdout.strip

Config

Это обычный yml-файл с настройками плагинов, eго удобно генерить chef'ом :)

plugin name:
  settings name:
  - 'bla-bla'

Есть небольшая магия, для того чтобы использовать плагин как провайдер (например следить за определенными портами):

web watcher:
  - url: http://localhost/ # создастся plugin с name == 'web watcher_0'
    status: 302
  - url: https://localhost/login # новый плагин name == 'web watcher_1'
    status: 200
    ua: Mozilla
robots txt watcher: # новый плагин name == 'robots txt watcher'
  parent: web watcher
  url: https://localhost/robots.txt
  status: 404
  ua: ^Yandex

Почему велосипед

Удобно писать плагины, использовать 1 процесс, 1 коннект, и проч.

Посмотрите официальную реализацию riemann-client, По сравнению с ней вы тут не найдете search и udp.