Rubix

<img src=“https://secure.travis-ci.org/infochimps-labs/rubix.png?branch=master” alt=“Build Status” />

Rubix is a Ruby client for Zabbix that makes it easier to programatically control Zabbix resources so that they can be coordinated in complex, dynamic, and distributed environments like clouds.

Rubix provides a wrapper for the Zabbix API documentation and an ORM for resources like Hosts, HostGroups, Templates, Items, &c.

Rubix also provides simple command line tools and Ruby classes that make it easier to query Zabbix and send it data.

There are a lot of other projects out there that connect Ruby to Zabbix. Here’s a quick list:

zabbix

zabbix aws templates, scripts, chef automations

zabbixapi

Ruby module for work with zabbix api

zabbix-rb

send data to zabbix from ruby

zabbix_pusher

zabbix_pusher is a gem to parse zabbix templates and push the data to the corresponding zabbix server

zabbix-trappers

Collection of ruby scripts for zabbix trappers

rzabbix

Zabbix API client for Ruby

zabboard

zabbix analytics

zabbix-web

Zabbix frontend

zabcon

Zabcon is a command line interface for Zabbix written in Ruby

Connections, Requests, & Responses

Getting connected to the Zabbix API is easy

require 'rubix'

# Provide API URL & credentials.  These are the defaults.
Rubix.connect('http://localhost/api_jsonrpc.php', 'admin', 'zabbix')

As per the Zabbix API documentation each request to the Zabbix API needs four values:

id

an integer identifying the request ID.

auth

a string confirming that the API request is authenticated.

method

the name of the API method you’re calling, e.g. - host.get, template.delete, &c.

params

parameters for the invocation of the method.

When you send a request, Rubix only requires you to specify the method and the params, handling the id and authentication quietly for you:

response = Rubix.connection.request('host.get', 'filter' => { 'host' => 'My Zabbix Host' })

case
when response.has_data?
  # Response is a success and "has data" -- it's not empty.  This
  # means we found our host.
  puts response.result
  #=> [{"hostid"=>"10017"}]
when response.success?
  # Response was succssful but doesn't "have data" -- it's empty, no
  # such host!
  puts "No such host"
else
  # Response was an error.  Uh oh!
  puts response.error_message
end

On the command line

Rubix comes with a command line utility zabbix_api which lets you issue these sorts of requests directly on the command line.

$ zabbix_api host.get '{"filter": {"host": "My Zabbix Host"}}'
[{"hostid"=>"10017"}]

zabbix_api lets you specify the credentials and will pretty-print responses for you. Try zabbix_api --help for more details.

Logging

Rubix produces log messages at the Logger::INFO level to a Logger instance by default. When the logger severity is Logger::DEBUG Rubix will log the request and response to every API call it makes against the Zabbix API. This can be useful when debugging why a particular interaction isn’t working as expected.

Besides programatically modifying the logger, the log level and path can be modified at runtime with the environment variables RUBIX_LOG_LEVEL and RUBIX_LOG_PATH.

ORM

If you don’t want to deal with the particulars of the Zabbix API itself, Rubix provides a set of classes that you can use instead.

The following example goes through setting up an item on a host complete with host groups, templates, applications, and so on.

require 'rubix'
Rubix.connect('http://localhost/api_jsonrpc.php', 'admin', 'zabbix')

# Ensure the host group we want exists.
host_group = Rubix::HostGroup.find_or_create(:name => "My Zabbix Hosts")

# Now the template -- created templates are empty by default!
template = Rubix::Template.new(:name => "Template_Some_Service")
template.save

# Now the host.
host = Rubix::Host.new(:name => "My Host", :ip => '123.123.123.123', :templates => [template], :host_groups => [host_group])
host.save

# Now for the application
app = Rubix::Application.new(:name => 'Some App', :host => host)
app.save

# Now the item
item = Rubix::Item.new(:host => host, :key => 'foo.bar.baz', :description => "Some Item", :value_type => :unsigned_int, :applications => [app])
item.save

You can also update and destroy resources as well as probe associations: host.items.

Monitors

Rubix also comes with some classes that make it easy to write simple monitors. The output of these monitors should match the expected input format of zabbix_pipe. This way they can be chained together. Here’s an example of a simple monitor that calculates the currently used memory in bytes.

# in memory_monitor.rb
require 'rubix'

class MemoryMonitor < Rubix::Monitor
  def measure
    write do |data|
      mem_used = `free | tail -n+2 | head -n1`.chomp.split[2].to_i
      data << [['mem.used', mem_used]]
    end
  end
end

MemoryMonitor.run if $0 == __FILE__

The file memory_monitor.rb can now be run on the command line in various ways. Most simply it will just output a measurement.

$ ruby memory_monitor.rb
'mem.used'	11595908

You can also have it loop after a number of seconds

$ ruby memory_monitor.rb --loop=30
'mem.used'	11595760
'mem.used'	11595800
'mem.used'	11596016
'mem.used'	11596008

You can pipe the results directly to Zabbix (uses Zabbix sender behind the scenes):

$ ruby memory_monitor.rb --loop=30 --send