rrd-ffi 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +11 -1
- data/README.rdoc +30 -0
- data/Rakefile +25 -14
- data/lib/rrd.rb +7 -0
- data/lib/rrd/base.rb +39 -2
- data/lib/rrd/builder.rb +45 -0
- data/lib/rrd/ext/fixnum.rb +39 -0
- data/lib/rrd/graph.rb +77 -16
- data/lib/rrd/version.rb +1 -1
- data/lib/rrd/wrapper.rb +2 -0
- data/rrd-ffi.gemspec +7 -3
- data/spec/rrd/base_spec.rb +34 -0
- data/spec/rrd/builder_spec.rb +30 -0
- data/spec/rrd/graph_spec.rb +52 -2
- data/spec/rrd_spec.rb +17 -1
- metadata +7 -3
data/CHANGELOG.rdoc
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
= Changelog
|
2
2
|
|
3
|
+
== 2010-02-25
|
4
|
+
|
5
|
+
* Fixed error message to be cleared before every call to wrapper. It was causing problems when doing a valid call after an invalid one
|
6
|
+
* Added advanced DSL for graphic building
|
7
|
+
* Added DSL for creating RRD file
|
8
|
+
* Added to RRD::Base methods create, update, fetch, info
|
9
|
+
|
3
10
|
== 2010-02-24
|
4
11
|
|
5
|
-
* Released version 0.1.0
|
12
|
+
* Released version 0.1.0
|
13
|
+
* Basic DSL for graphic building
|
14
|
+
* Added to RRD::Base methods first, last, restore
|
15
|
+
* Added bindings to librrd through RRD::Wrapper - create, update, fetch, info, first, last, restore, graph
|
data/README.rdoc
CHANGED
@@ -31,10 +31,28 @@ If you are not using MAC OS and still have problems, export the RRD_PATH variabl
|
|
31
31
|
rrd = RRD::Base.new("myrrd.rrd")
|
32
32
|
# Restoring a rrd file from xml
|
33
33
|
rrd.restore("myrrd.xml")
|
34
|
+
|
35
|
+
# Fetching data from rrd
|
36
|
+
rrd.fetch(:average).each {|line| puts line.inspect}
|
37
|
+
|
38
|
+
# Collecting information from rrd
|
39
|
+
puts rrd.info.to_yaml
|
40
|
+
|
41
|
+
# Updating rrd (this rrd example has 3 datasources)
|
42
|
+
rrd.update Time.now, 500, nil, 30
|
34
43
|
|
35
44
|
# Looking for the first and last entered dates
|
36
45
|
puts rrd.starts_at
|
37
46
|
puts rrd.ends_at
|
47
|
+
|
48
|
+
=== DSLs
|
49
|
+
|
50
|
+
# Creating a new rrd
|
51
|
+
rrd = RRD::Base.new("myrrd.rrd")
|
52
|
+
rrd.create :start => Time.now - 10.seconds, :step => 5.minutes do
|
53
|
+
datasource "memory", :type => :gauge, :heartbeat => 10.minutes, :min => 0, :max => :unlimited
|
54
|
+
archive :average, :every => 10.minutes, :during => 1.year
|
55
|
+
end
|
38
56
|
|
39
57
|
# Generating a graph with memory and cpu usage from myrrd.rrd file
|
40
58
|
RRD.graph "graph.png", :title => "Test", :width => 800, :height => 250 do
|
@@ -42,6 +60,18 @@ If you are not using MAC OS and still have problems, export the RRD_PATH variabl
|
|
42
60
|
line "myrrd.rrd", :memory => :average, :color => "#0000FF", :label => "Memory"
|
43
61
|
end
|
44
62
|
|
63
|
+
# Generating a more complex graph using advanced DSL
|
64
|
+
RRD.graph IMG_FILE, :title => "Test", :width => 800, :height => 250, :start => Time.now - 1.day, :end => Time.now do
|
65
|
+
for_rrd_data "cpu0", :cpu0 => :average, :from => RRD_FILE
|
66
|
+
for_rrd_data "mem", :memory => :average, :from => RRD_FILE
|
67
|
+
using_calculated_data "half_mem", :calc => "mem,2,/"
|
68
|
+
using_value "mem_avg", :calc => "mem,AVERAGE"
|
69
|
+
draw_line :data => "mem", :color => "#0000FF", :label => "Memory", :width => 1
|
70
|
+
draw_area :data => "cpu0", :color => "#00FF00", :label => "CPU 0"
|
71
|
+
print_comment "Information - "
|
72
|
+
print_value "mem_avg", :format => "%6.2lf %SB"
|
73
|
+
end
|
74
|
+
|
45
75
|
== Raw API Usage
|
46
76
|
|
47
77
|
# Creating a rrd file
|
data/Rakefile
CHANGED
@@ -1,21 +1,30 @@
|
|
1
1
|
require "rake"
|
2
|
-
require "hanna/rdoctask"
|
3
2
|
require "spec/rake/spectask"
|
4
3
|
require "lib/rrd/version"
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
gem.description = %Q{Provides bindings for many RRD functions (using ffi gem and librrd), as well as some DSL for graphic building}
|
11
|
-
gem.email = "morellon@gmail.com"
|
12
|
-
gem.homepage = "http://github.com/morellon/rrd-ffi"
|
13
|
-
gem.authors = ["morellon", "fnando", "rafaelrosafu", "dalcico"]
|
14
|
-
gem.add_development_dependency "rspec"
|
15
|
-
gem.add_dependency "ffi"
|
4
|
+
|
5
|
+
begin
|
6
|
+
require "hanna/rdoctask"
|
7
|
+
rescue LoadError => e
|
8
|
+
require "rake/rdoctask"
|
16
9
|
end
|
17
10
|
|
18
|
-
|
11
|
+
begin
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
gem.name = "rrd-ffi"
|
15
|
+
gem.version = RRD::Version::STRING
|
16
|
+
gem.summary = %Q{RRDTool gem using librrd and ffi}
|
17
|
+
gem.description = %Q{Provides bindings for many RRD functions (using ffi gem and librrd), as well as DSLs for graphic and rrd building. You must have librrd in your system!}
|
18
|
+
gem.email = "morellon@gmail.com"
|
19
|
+
gem.homepage = "http://github.com/morellon/rrd-ffi"
|
20
|
+
gem.authors = ["morellon", "fnando", "rafaelrosafu", "dalcico"]
|
21
|
+
gem.add_development_dependency "rspec"
|
22
|
+
gem.add_dependency "ffi"
|
23
|
+
end
|
24
|
+
Jeweler::GemcutterTasks.new
|
25
|
+
rescue LoadError
|
26
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
27
|
+
end
|
19
28
|
|
20
29
|
desc 'Run the specs'
|
21
30
|
Spec::Rake::SpecTask.new(:spec) do |t|
|
@@ -30,4 +39,6 @@ Rake::RDocTask.new do |rdoc|
|
|
30
39
|
rdoc.options += %w[ --line-numbers --inline-source --charset utf-8 ]
|
31
40
|
rdoc.rdoc_files.include("README.rdoc", "CHANGELOG.rdoc")
|
32
41
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
33
|
-
end
|
42
|
+
end
|
43
|
+
|
44
|
+
task :default => :spec
|
data/lib/rrd.rb
CHANGED
@@ -3,6 +3,8 @@ require "rrd/version"
|
|
3
3
|
require "rrd/wrapper"
|
4
4
|
require "rrd/base"
|
5
5
|
require "rrd/graph"
|
6
|
+
require "rrd/builder"
|
7
|
+
require "rrd/ext/fixnum"
|
6
8
|
|
7
9
|
module RRD
|
8
10
|
extend self
|
@@ -12,5 +14,10 @@ module RRD
|
|
12
14
|
graph.instance_eval(&block)
|
13
15
|
graph.save
|
14
16
|
end
|
17
|
+
|
18
|
+
def to_line_parameters(hash)
|
19
|
+
line_params = Hash[*hash.reduce([]) { |result, (key,value)| result += ["--#{key}", value.to_s] }]
|
20
|
+
line_params.keys.sort.reduce([]) { |result, key| result += [key, line_params[key]] }
|
21
|
+
end
|
15
22
|
end
|
16
23
|
|
data/lib/rrd/base.rb
CHANGED
@@ -1,23 +1,60 @@
|
|
1
1
|
module RRD
|
2
2
|
class Base
|
3
3
|
attr_accessor :rrd_file
|
4
|
-
|
4
|
+
|
5
5
|
def initialize(rrd_file)
|
6
6
|
@rrd_file = rrd_file
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
|
+
def create(options = {}, &block)
|
10
|
+
builder = RRD::Builder.new(rrd_file, options)
|
11
|
+
builder.instance_eval(&block)
|
12
|
+
builder.save
|
13
|
+
end
|
14
|
+
|
15
|
+
# Basic usage: rrd.update Time.now, 20.0, 20, nil, 2
|
16
|
+
#
|
17
|
+
# Note: All datasources must receive a value, based on datasources order in rrd file
|
18
|
+
def update(time, *data)
|
19
|
+
new_data = data.map {|item| item.nil? ? "U" : item}
|
20
|
+
new_data = [time.to_i] + new_data
|
21
|
+
|
22
|
+
Wrapper.update(rrd_file, new_data.join(":"))
|
23
|
+
end
|
24
|
+
|
25
|
+
# Basic usage: rrd.fetch :average
|
26
|
+
#
|
27
|
+
def fetch(consolidation_function, options = {})
|
28
|
+
options = {:start => Time.now - 1.day, :end => Time.now}.merge options
|
29
|
+
|
30
|
+
options[:start] = options[:start].to_i
|
31
|
+
options[:end] = options[:end].to_i
|
32
|
+
line_params = RRD.to_line_parameters(options)
|
33
|
+
|
34
|
+
Wrapper.fetch(rrd_file, consolidation_function.to_s.upcase, *line_params)
|
35
|
+
end
|
36
|
+
|
37
|
+
# See RRD::Wrapper.info
|
38
|
+
def info
|
39
|
+
Wrapper.info(rrd_file)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a time object with the first entered value date
|
9
43
|
def starts_at
|
10
44
|
Time.at Wrapper.first(rrd_file)
|
11
45
|
end
|
12
46
|
alias :first :starts_at
|
13
47
|
|
48
|
+
# Returns a time object with the last entered value date
|
14
49
|
def ends_at
|
15
50
|
Time.at Wrapper.last(rrd_file)
|
16
51
|
end
|
17
52
|
alias :last :ends_at
|
18
53
|
|
54
|
+
# See RRD::Wrapper.restore
|
19
55
|
def restore(xml_file)
|
20
56
|
Wrapper.restore(xml_file, rrd_file)
|
21
57
|
end
|
58
|
+
|
22
59
|
end
|
23
60
|
end
|
data/lib/rrd/builder.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module RRD
|
2
|
+
class Builder
|
3
|
+
attr_accessor :output, :parameters, :datasources, :archives
|
4
|
+
|
5
|
+
DATASOURCE_TYPES = [:gauge, :counter, :derive, :absolute]
|
6
|
+
ARCHIVE_TYPES = [:average, :min, :max, :last]
|
7
|
+
|
8
|
+
def initialize(output, parameters = {})
|
9
|
+
@output = output
|
10
|
+
|
11
|
+
@parameters = {:step => 5.minutes, :start => Time.now - 10.seconds }.merge parameters
|
12
|
+
@parameters[:start] = @parameters[:start].to_i
|
13
|
+
|
14
|
+
@datasources = []
|
15
|
+
@archives = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def datasource(name, options = {})
|
19
|
+
options = {:type => :gauge, :heartbeat => 10.minutes, :min => 0, :max => :unlimited}.merge options
|
20
|
+
options[:max] = "U" if options[:max] == :unlimited
|
21
|
+
datasource = "DS:#{name}:#{options[:type].to_s.upcase}:#{options[:heartbeat]}:#{options[:min]}:#{options[:max]}"
|
22
|
+
datasources << datasource
|
23
|
+
datasource
|
24
|
+
end
|
25
|
+
|
26
|
+
def archive(consolidation_function, options = {})
|
27
|
+
options = {:every => 5.minutes, :during => 1.day}.merge options
|
28
|
+
archive_steps = options[:every]/parameters[:step]
|
29
|
+
archive_rows = options[:during]/options[:every]
|
30
|
+
archive = "RRA:#{consolidation_function.to_s.upcase}:0.5:#{archive_steps}:#{archive_rows}"
|
31
|
+
archives << archive
|
32
|
+
archive
|
33
|
+
end
|
34
|
+
|
35
|
+
def save
|
36
|
+
args = [output]
|
37
|
+
line_parameters = RRD.to_line_parameters(parameters)
|
38
|
+
args += line_parameters
|
39
|
+
args += datasources
|
40
|
+
args += archives
|
41
|
+
|
42
|
+
Wrapper.create(*args)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#TODO: Change to ActiveSupport from Rails 3
|
2
|
+
class Fixnum
|
3
|
+
def second
|
4
|
+
self
|
5
|
+
end
|
6
|
+
alias :seconds :second
|
7
|
+
|
8
|
+
def minute
|
9
|
+
second * 60
|
10
|
+
end
|
11
|
+
alias :minutes :minute
|
12
|
+
|
13
|
+
def hour
|
14
|
+
minute * 60
|
15
|
+
end
|
16
|
+
alias :hours :hour
|
17
|
+
|
18
|
+
def day
|
19
|
+
hour * 24
|
20
|
+
end
|
21
|
+
alias :days :day
|
22
|
+
|
23
|
+
def week
|
24
|
+
day * 7
|
25
|
+
end
|
26
|
+
alias :weeks :week
|
27
|
+
|
28
|
+
def month
|
29
|
+
day * 30
|
30
|
+
end
|
31
|
+
alias :months :month
|
32
|
+
|
33
|
+
def year
|
34
|
+
day * 365
|
35
|
+
end
|
36
|
+
alias :years :year
|
37
|
+
end
|
38
|
+
|
39
|
+
|
data/lib/rrd/graph.rb
CHANGED
@@ -1,35 +1,96 @@
|
|
1
1
|
module RRD
|
2
2
|
class Graph
|
3
3
|
GRAPH_OPTIONS = [:color, :label]
|
4
|
-
|
4
|
+
DEF_OPTIONS= [:from]
|
5
5
|
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :output, :parameters, :definitions, :printables
|
7
7
|
|
8
|
-
def initialize(output,
|
8
|
+
def initialize(output, parameters = {})
|
9
9
|
@output = output
|
10
|
-
|
11
|
-
@
|
10
|
+
|
11
|
+
@parameters = {:start => Time.now - 1.day, :end => Time.now, :title => ""}
|
12
|
+
@parameters[:start] = @parameters[:start].to_i
|
13
|
+
@parameters[:end] = @parameters[:end].to_i
|
14
|
+
|
15
|
+
@definitions = []
|
16
|
+
@printables = []
|
17
|
+
end
|
18
|
+
|
19
|
+
def for_rrd_data(data_name, options)
|
20
|
+
dataset = options.reject {|name, value| DEF_OPTIONS.include?(name.to_sym)}
|
21
|
+
definition = "DEF:#{data_name}=#{options[:from]}:#{dataset.keys.first}:#{dataset.values.first.to_s.upcase}"
|
22
|
+
definitions << definition
|
23
|
+
definition
|
24
|
+
end
|
25
|
+
|
26
|
+
def using_calculated_data(data_name, options)
|
27
|
+
definition = "CDEF:#{data_name}=#{options[:calc]}"
|
28
|
+
definitions << definition
|
29
|
+
definition
|
30
|
+
end
|
31
|
+
|
32
|
+
def using_value(value_name, options)
|
33
|
+
definition = "VDEF:#{value_name}=#{options[:calc]}"
|
34
|
+
definitions << definition
|
35
|
+
definition
|
36
|
+
end
|
37
|
+
|
38
|
+
def print_comment(comment)
|
39
|
+
printable = "COMMENT:#{comment}"
|
40
|
+
printables << printable
|
41
|
+
printable
|
12
42
|
end
|
13
43
|
|
14
|
-
def
|
15
|
-
|
44
|
+
def print_value(value_name, options)
|
45
|
+
printable = "GPRINT:#{value_name}:#{options[:format]}"
|
46
|
+
printables << printable
|
47
|
+
printable
|
16
48
|
end
|
17
49
|
|
18
|
-
def
|
19
|
-
|
50
|
+
def draw_line(options)
|
51
|
+
options = {:width => 1}.merge options
|
52
|
+
type = "LINE#{options[:width]}"
|
53
|
+
draw(type, options)
|
54
|
+
end
|
55
|
+
|
56
|
+
def draw_area(options)
|
57
|
+
draw("AREA", options)
|
58
|
+
end
|
59
|
+
|
60
|
+
def line(rrd_file, options)
|
61
|
+
dataset = options.reject {|name, value| GRAPH_OPTIONS.include?(name.to_sym)}
|
62
|
+
name = "#{dataset.keys.first}_#{dataset.values.first.to_s}"
|
63
|
+
definition = "DEF:#{name}=#{rrd_file}:#{dataset.keys.first}:#{dataset.values.first.to_s.upcase}"
|
64
|
+
definitions << definition
|
65
|
+
printable = "LINE1:#{name}#{options[:color]}:#{options[:label]}"
|
66
|
+
printables << printable
|
67
|
+
[definition, printable]
|
68
|
+
end
|
69
|
+
|
70
|
+
def area(rrd_file, options)
|
71
|
+
dataset = options.reject {|name, value| GRAPH_OPTIONS.include?(name.to_sym)}
|
72
|
+
name = "#{dataset.keys.first}_#{dataset.values.first.to_s}"
|
73
|
+
definition = "DEF:#{name}=#{rrd_file}:#{dataset.keys.first}:#{dataset.values.first.to_s.upcase}"
|
74
|
+
definitions << definition
|
75
|
+
printable = "AREA:#{name}#{options[:color]}:#{options[:label]}"
|
76
|
+
printables << printable
|
77
|
+
[definition, printable]
|
20
78
|
end
|
21
79
|
|
22
80
|
def save
|
23
81
|
args = [output]
|
24
|
-
args +=
|
25
|
-
|
26
|
-
|
27
|
-
dataset = opts.reject {|name, value| GRAPH_OPTIONS.include?(name.to_sym)}
|
28
|
-
args << "DEF:d#{i}=#{file}:#{dataset.keys.first}:#{dataset.values.first.to_s.upcase}"
|
29
|
-
args << "#{GRAPH_TYPE[type.to_sym]}:d#{i}#{opts[:color]}:#{opts[:label]}"
|
30
|
-
end
|
82
|
+
args += RRD.to_line_parameters(parameters)
|
83
|
+
args += definitions
|
84
|
+
args += printables
|
31
85
|
|
32
86
|
Wrapper.graph(*args)
|
33
87
|
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def draw(type, options)
|
91
|
+
printable = "#{type}:#{options[:data]}#{options[:color]}:#{options[:label]}"
|
92
|
+
printables << printable
|
93
|
+
printable
|
94
|
+
end
|
34
95
|
end
|
35
96
|
end
|
data/lib/rrd/version.rb
CHANGED
data/lib/rrd/wrapper.rb
CHANGED
@@ -49,6 +49,7 @@ module RRD
|
|
49
49
|
attach_function :rrd_restore, [:int, :pointer], :int
|
50
50
|
attach_function :rrd_graph, [:int, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int
|
51
51
|
attach_function :rrd_get_error, [], :string
|
52
|
+
attach_function :rrd_clear_error, [], :void
|
52
53
|
|
53
54
|
# Set up a new Round Robin Database (RRD).
|
54
55
|
def create(*args)
|
@@ -155,6 +156,7 @@ module RRD
|
|
155
156
|
end
|
156
157
|
|
157
158
|
def to_pointer(array_of_strings)
|
159
|
+
rrd_clear_error
|
158
160
|
strptrs = []
|
159
161
|
array_of_strings.each {|item| strptrs << FFI::MemoryPointer.from_string(item)}
|
160
162
|
|
data/rrd-ffi.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rrd-ffi}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["morellon", "fnando", "rafaelrosafu", "dalcico"]
|
12
|
-
s.date = %q{2010-02-
|
13
|
-
s.description = %q{Provides bindings for many RRD functions (using ffi gem and librrd), as well as
|
12
|
+
s.date = %q{2010-02-25}
|
13
|
+
s.description = %q{Provides bindings for many RRD functions (using ffi gem and librrd), as well as DSLs for graphic and rrd building. You must have librrd in your system!}
|
14
14
|
s.email = %q{morellon@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.rdoc"
|
@@ -22,11 +22,14 @@ Gem::Specification.new do |s|
|
|
22
22
|
"Rakefile",
|
23
23
|
"lib/rrd.rb",
|
24
24
|
"lib/rrd/base.rb",
|
25
|
+
"lib/rrd/builder.rb",
|
26
|
+
"lib/rrd/ext/fixnum.rb",
|
25
27
|
"lib/rrd/graph.rb",
|
26
28
|
"lib/rrd/version.rb",
|
27
29
|
"lib/rrd/wrapper.rb",
|
28
30
|
"rrd-ffi.gemspec",
|
29
31
|
"spec/rrd/base_spec.rb",
|
32
|
+
"spec/rrd/builder_spec.rb",
|
30
33
|
"spec/rrd/graph_spec.rb",
|
31
34
|
"spec/rrd/wrapper_spec.rb",
|
32
35
|
"spec/rrd_spec.rb",
|
@@ -40,6 +43,7 @@ Gem::Specification.new do |s|
|
|
40
43
|
s.summary = %q{RRDTool gem using librrd and ffi}
|
41
44
|
s.test_files = [
|
42
45
|
"spec/rrd/base_spec.rb",
|
46
|
+
"spec/rrd/builder_spec.rb",
|
43
47
|
"spec/rrd/graph_spec.rb",
|
44
48
|
"spec/rrd/wrapper_spec.rb",
|
45
49
|
"spec/rrd_spec.rb",
|
data/spec/rrd/base_spec.rb
CHANGED
@@ -6,6 +6,40 @@ describe RRD::Base do
|
|
6
6
|
@rrd = RRD::Base.new(RRD_FILE)
|
7
7
|
end
|
8
8
|
|
9
|
+
it "should create a rrd file using dsl" do
|
10
|
+
File.should_not be_file(RRD_FILE)
|
11
|
+
|
12
|
+
@rrd.create :start => Time.now - 10.seconds, :step => 5.minutes do
|
13
|
+
datasource "memory", :type => :gauge, :heartbeat => 10.minutes, :min => 0, :max => :unlimited
|
14
|
+
archive :average, :every => 10.minutes, :during => 1.year
|
15
|
+
end
|
16
|
+
|
17
|
+
File.should be_file(RRD_FILE)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should update the rrd file with data" do
|
21
|
+
time = Time.now
|
22
|
+
# one datum for every datasource, ordered
|
23
|
+
data = [20, 20.0, nil]
|
24
|
+
update_data = "#{time.to_i}:20:20.0:U"
|
25
|
+
RRD::Wrapper.should_receive(:update).with(RRD_FILE, update_data).and_return(true)
|
26
|
+
@rrd.update(time, *data).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should fetch data from rrd file" do
|
30
|
+
start_time = Time.now - 3600
|
31
|
+
end_time = Time.now
|
32
|
+
raw_params = ["AVERAGE", "--end", "#{end_time.to_i}", "--resolution", "1", "--start", "#{start_time.to_i}"]
|
33
|
+
RRD::Wrapper.should_receive(:fetch).with(RRD_FILE, *raw_params).and_return([])
|
34
|
+
@rrd.fetch(:average, :start => start_time, :end => end_time, :resolution => 1.second)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should return the rrd file information" do
|
38
|
+
info = {"filename" => RRD_FILE}
|
39
|
+
RRD::Wrapper.should_receive(:info).with(RRD_FILE).and_return(info)
|
40
|
+
@rrd.info.should == info
|
41
|
+
end
|
42
|
+
|
9
43
|
it "should restore a rrd from xml" do
|
10
44
|
RRD::Wrapper.should_receive(:restore).with(XML_FILE, RRD_FILE).and_return(true)
|
11
45
|
@rrd.restore(XML_FILE).should be_true
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
2
|
+
|
3
|
+
describe RRD::Builder do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@start_time = Time.now - 10.seconds
|
7
|
+
@builder = RRD::Builder.new "file.rrd", :start => @start_time
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should store a datasource" do
|
11
|
+
datasource = @builder.datasource "memory", :type => :gauge, :heartbeat => 10.minutes, :min => 0, :max => :unlimited
|
12
|
+
datasource.should == "DS:memory:GAUGE:600:0:U"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should store an archive" do
|
16
|
+
archive = @builder.archive :average, :every => 10.minutes, :during => 1.day
|
17
|
+
archive.should == "RRA:AVERAGE:0.5:2:144"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should create rrd file" do
|
21
|
+
@builder.datasource "memory", :type => :gauge, :heartbeat => 10.minutes, :min => 0, :max => :unlimited
|
22
|
+
@builder.archive :average, :every => 10.minutes, :during => 1.day
|
23
|
+
RRD::Wrapper.should_receive(:create).with("file.rrd",
|
24
|
+
"--start", @start_time.to_i.to_s,
|
25
|
+
"--step", "300",
|
26
|
+
"DS:memory:GAUGE:600:0:U",
|
27
|
+
"RRA:AVERAGE:0.5:2:144")
|
28
|
+
@builder.save
|
29
|
+
end
|
30
|
+
end
|
data/spec/rrd/graph_spec.rb
CHANGED
@@ -7,11 +7,61 @@ describe RRD::Graph do
|
|
7
7
|
@graph = RRD::Graph.new IMG_FILE
|
8
8
|
end
|
9
9
|
|
10
|
+
it "should store definition for rrd data" do
|
11
|
+
result = @graph.for_rrd_data "cpu0", :cpu0 => :average, :from => RRD_FILE
|
12
|
+
result.should == "DEF:cpu0=#{RRD_FILE}:cpu0:AVERAGE"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should store definition for calculated data" do
|
16
|
+
result = @graph.using_calculated_data "half_mem", :calc => "mem,2,/"
|
17
|
+
result.should == "CDEF:half_mem=mem,2,/"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should store definition for static value" do
|
21
|
+
result = @graph.using_value "mem_avg", :calc => "mem,AVERAGE"
|
22
|
+
result.should == "VDEF:mem_avg=mem,AVERAGE"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should store printable for line drawing" do
|
26
|
+
result = @graph.draw_line :data => "mem", :color => "#0000FF", :label => "Memory", :width => 1
|
27
|
+
result.should == "LINE1:mem#0000FF:Memory"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should store printable for area drawing" do
|
31
|
+
result = @graph.draw_area :data => "cpu", :color => "#00FF00", :label => "CPU 0"
|
32
|
+
result.should == "AREA:cpu#00FF00:CPU 0"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should store printable for comment" do
|
36
|
+
result = @graph.print_comment "Lero lero"
|
37
|
+
result.should == "COMMENT:Lero lero"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should store printable for static value" do
|
41
|
+
result = @graph.print_value "mem_avg", :format => "%6.2lf %SB"
|
42
|
+
result.should == "GPRINT:mem_avg:%6.2lf %SB"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should store definition and printable for line" do
|
46
|
+
result = @graph.line RRD_FILE, :memory => :average, :color => "#0000FF", :label => "Memory Avg"
|
47
|
+
result[0].should == "DEF:memory_average=#{RRD_FILE}:memory:AVERAGE"
|
48
|
+
result[1].should == "LINE1:memory_average#0000FF:Memory Avg"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should store definition and printable for area" do
|
52
|
+
result = @graph.area RRD_FILE, :memory => :average, :color => "#0000FF", :label => "Memory Avg"
|
53
|
+
result[0].should == "DEF:memory_average=#{RRD_FILE}:memory:AVERAGE"
|
54
|
+
result[1].should == "AREA:memory_average#0000FF:Memory Avg"
|
55
|
+
end
|
56
|
+
|
10
57
|
it "should create a graph correctly" do
|
11
58
|
@graph.line RRD_FILE, :memory => :average, :color => "#0000FF", :label => "Memory Avg"
|
12
59
|
RRD::Wrapper.should_receive(:graph).with(IMG_FILE,
|
13
|
-
"
|
14
|
-
"
|
60
|
+
"--end", anything(),
|
61
|
+
"--start", anything(),
|
62
|
+
"--title", "",
|
63
|
+
"DEF:memory_average=#{RRD_FILE}:memory:AVERAGE",
|
64
|
+
"LINE1:memory_average#0000FF:Memory Avg").and_return true
|
15
65
|
@graph.save
|
16
66
|
end
|
17
67
|
|
data/spec/rrd_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe RRD do
|
|
6
6
|
RRD::Base.new(RRD_FILE).restore(XML_FILE)
|
7
7
|
end
|
8
8
|
|
9
|
-
it "should create a graph" do
|
9
|
+
it "should create a graph using simple DSL" do
|
10
10
|
result = RRD.graph IMG_FILE, :title => "Test", :width => 800, :height => 250 do
|
11
11
|
area RRD_FILE, :cpu0 => :average, :color => "#00FF00", :label => "CPU 0"
|
12
12
|
line RRD_FILE, :memory => :average, :color => "#0000FF", :label => "Memory"
|
@@ -15,4 +15,20 @@ describe RRD do
|
|
15
15
|
result.should be_true
|
16
16
|
File.should be_file(IMG_FILE)
|
17
17
|
end
|
18
|
+
|
19
|
+
it "should create a graph using advanced DSL" do
|
20
|
+
result = RRD.graph IMG_FILE, :title => "Test", :width => 800, :height => 250, :start => Time.now - 1.day, :end => Time.now do
|
21
|
+
for_rrd_data "cpu0", :cpu0 => :average, :from => RRD_FILE
|
22
|
+
for_rrd_data "mem", :memory => :average, :from => RRD_FILE #TODO: :start => Time.now - 1.day, :end => Time.now, :shift => 1.hour
|
23
|
+
using_calculated_data "half_mem", :calc => "mem,2,/"
|
24
|
+
using_value "mem_avg", :calc => "mem,AVERAGE"
|
25
|
+
draw_line :data => "mem", :color => "#0000FF", :label => "Memory", :width => 1
|
26
|
+
draw_area :data => "cpu0", :color => "#00FF00", :label => "CPU 0"
|
27
|
+
print_comment "Information - "
|
28
|
+
print_value "mem_avg", :format => "%6.2lf %SB"
|
29
|
+
end
|
30
|
+
|
31
|
+
result.should be_true
|
32
|
+
File.should be_file(IMG_FILE)
|
33
|
+
end
|
18
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rrd-ffi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- morellon
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2010-02-
|
15
|
+
date: 2010-02-25 00:00:00 -03:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
- !ruby/object:Gem::Version
|
36
36
|
version: "0"
|
37
37
|
version:
|
38
|
-
description: Provides bindings for many RRD functions (using ffi gem and librrd), as well as
|
38
|
+
description: Provides bindings for many RRD functions (using ffi gem and librrd), as well as DSLs for graphic and rrd building. You must have librrd in your system!
|
39
39
|
email: morellon@gmail.com
|
40
40
|
executables: []
|
41
41
|
|
@@ -50,11 +50,14 @@ files:
|
|
50
50
|
- Rakefile
|
51
51
|
- lib/rrd.rb
|
52
52
|
- lib/rrd/base.rb
|
53
|
+
- lib/rrd/builder.rb
|
54
|
+
- lib/rrd/ext/fixnum.rb
|
53
55
|
- lib/rrd/graph.rb
|
54
56
|
- lib/rrd/version.rb
|
55
57
|
- lib/rrd/wrapper.rb
|
56
58
|
- rrd-ffi.gemspec
|
57
59
|
- spec/rrd/base_spec.rb
|
60
|
+
- spec/rrd/builder_spec.rb
|
58
61
|
- spec/rrd/graph_spec.rb
|
59
62
|
- spec/rrd/wrapper_spec.rb
|
60
63
|
- spec/rrd_spec.rb
|
@@ -90,6 +93,7 @@ specification_version: 3
|
|
90
93
|
summary: RRDTool gem using librrd and ffi
|
91
94
|
test_files:
|
92
95
|
- spec/rrd/base_spec.rb
|
96
|
+
- spec/rrd/builder_spec.rb
|
93
97
|
- spec/rrd/graph_spec.rb
|
94
98
|
- spec/rrd/wrapper_spec.rb
|
95
99
|
- spec/rrd_spec.rb
|