rrd-ffi is a gem for using rrd actions in your ruby code.
You may use it in the raw format, as many rrd libs in languages like perl or python, or you can use it through the dsl we provide.
rrd-ffi uses ffi to wrap the librrd C bindings, not system calls.
IMPORTANT: You need librrd installed (version 1.3.1 or above, version 1.4.2 RECOMMENDED) in your system for this gem to work
Here’s what you need to know before starting.
To install rrd-ffi, you will need to have librrd in your system.
Then, run sudo gem install rrd-ffi
If you are using Mac Ports you will have problems, so add the following to your .profile|.bashrc|.bash_profile file:
export RRD_LIB=/opt/local/lib/librrd.dylib
or
export LD_LIBRARY_PATH=/opt/local/lib
If you are not using MAC OS and still having problems, export the RRD_PATH variable with the path to your librrd file.
Debian/Ubuntu: apt-get install librrd-dev
Fedora/Red Hat: yum install rrdtool-devel
Mac: port install rrdtool
From source:
cd rrdtool-${rrdtool_version} ./configure --disable-ruby --prefix=/usr/local make make install
require "rrd" rrd = RRD::Base.new("myrrd.rrd") # Restoring a rrd file from xml # Notice that all '-' on flags become '_' like --force-overwrite => :force_overwrite rrd.restore("myrrd.xml", :force_overwrite => true) # Fetching data from rrd rrd.fetch(:average).each {|line| puts line.inspect} # Collecting information from rrd puts rrd.info.to_yaml # Updating rrd (this rrd example has 3 datasources) rrd.update Time.now, 500, nil, 30 # Looking for the first and last entered dates puts rrd.starts_at puts rrd.ends_at # Growing or Shrinking a rrd_file (create a resize.rrd file) # You need to know the RRA number (starting from 0) rrd.resize(0, :grow => 10.days) rrd.resize(0, :shrink => 10.days) # Error handling rrd.fetch(:unknown_function) # should return false puts rrd.error # For raising exceptions in methods, use the '!' at its end rrd.fetch!(:unknown_function) # raises an error
# Creating a new rrd rrd = RRD::Base.new("myrrd.rrd") rrd.create :start => Time.now - 10.seconds, :step => 5.minutes do datasource "memory", :type => :gauge, :heartbeat => 10.minutes, :min => 0, :max => :unlimited archive :average, :every => 10.minutes, :during => 1.year end # Generating a graph with memory and cpu usage from myrrd.rrd file RRD.graph "graph.png", :title => "Test", :width => 800, :height => 250, :color => ["FONT#000000", "BACK#FFFFFF"] do area "myrrd.rrd", :cpu0 => :average, :color => "#00FF00", :label => "CPU 0" line "myrrd.rrd", :cpu0 => :average, :color => "#007f3f" line "myrrd.rrd", :memory => :average, :color => "#0000FF", :label => "Memory" end # Generating a graph or raising an exception if something bad happens RRD.graph! "graph.png", :title => "Test", :width => 800, :height => 250, :color => ["FONT#000000", "BACK#FFFFFF"] do area "myrrd.rrd", :cpu0 => :average, :color => "#00FF00", :label => "CPU 0" line "myrrd.rrd", :cpu0 => :average, :color => "#007f3f" line "myrrd.rrd", :memory => :average, :color => "#0000FF", :label => "Memory" end # Generating a more complex graph using advanced DSL RRD.graph IMG_FILE, :title => "Test", :width => 800, :height => 250, :start => Time.now - 1.day, :end => Time.now do for_rrd_data "cpu0", :cpu0 => :average, :from => RRD_FILE for_rrd_data "mem", :memory => :average, :from => RRD_FILE using_calculated_data "half_mem", :calc => "mem,2,/" using_value "mem_avg", :calc => "mem,AVERAGE" draw_line :data => "mem", :color => "#0000FF", :label => "Memory", :width => 1 draw_area :data => "cpu0", :color => "#00FF00", :label => "CPU 0" print_comment "Information - " print_value "mem_avg", :format => "%6.2lf %SB" end # Generating a graph using shift RRD.graph IMG_FILE, :title => "Test", :width => 800, :height => 250, :start => Time.now - 1.day, :end => Time.now do for_rrd_data "mem", :memory => :average, :from => RRD_FILE for_rrd_data "mem_yesterday", :memory => :average, :from => RRD_FILE, :start => Time.now - 2.day draw_line :data => "mem", :color => "#0000FF", :label => "Memory", :width => 1 shift :mem_yesterday => 1.day draw_line :data => "mem_yesterday", :color => "#0000FF", :label => "Yesterday memory", :width => 1 end
Normal methods return false on error, or the expected result otherwise.
# Creating a rrd file
RRD::Wrapper.create "myrrd.rrd", "--step", "300", "DS:ifOutOctets:COUNTER:1800:0:4294967295", "RRA:AVERAGE:0.5:1:2016"
# Fetching average data
RRD::Wrapper.fetch "myrrd.rrd", "AVERAGE"
# Looking for the first entered dates
RRD::Wrapper.first "myrrd.rrd"
# Creating a graph
RRD::Wrapper.graph("graph.png", "DEF:data=myrrd.rrd:ifOutOctets:AVERAGE", "LINE1:data#0000FF:Output bytes")
# Getting info on a rrd file
RRD::Wrapper.info("myrrd.rrd") # Looking for the last entered dates
RRD::Wrapper.last “myrrd.rrd”
# Getting last data inserted on a rrd RRD::Wrapper.last_update “myrrd.rrd”
# Resizing a rrd file RRA
RRD::Wrapper.resize "myrrd.rrd", "0", "GROW", "10" # Restoring a rrd file from xml RRD::Wrapper.restore "myrrd.xml", "myrrd.rrd"
# Tuning a rrd file
RRD::Wrapper.tune "myrrd.rrd", "--minimum", "memory:5" # Updating rrd with a new value RRD::Wrapper.update "myrrd.rrd", "N:500000000" # Getting the error happened puts RRD::Wrapper.error
Bang methods raise exception on error.
# Throwing the error if happens RRD::Wrapper.fetch! "myrrd.rrd", "WRONG FUNCTION"