RailsRRDTool 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/rrd.rb +162 -0
  2. metadata +45 -0
data/lib/rrd.rb ADDED
@@ -0,0 +1,162 @@
1
+ class RRD
2
+ def self.test
3
+ puts "test"
4
+ end
5
+
6
+ # types are alphanum, num, graph, ds_type, rra_type, path
7
+ def self.sanitize(string,type)
8
+
9
+ str = ""
10
+ if type == 'num' # 0-9 and . (accepted: 1.5, 10, 234)
11
+ str = string.to_s.match( /[0-9.]+/ )[0]
12
+ elsif type == 'alphanum' # alpha numeric only (accepted: abc123, abc, 123)
13
+ str = string.to_s.match( /[a-zA-Z0-9_\s]+/ )[0]
14
+ elsif type == 'ds_type' # only DS types (accepted values are GAUGE, COUNTER, DERIVE, ABSOLUTE, and COMPUTE
15
+ str = string.to_s.match( /(GAUGE|COUNTER|DERIVE|ABSOLUTE|COMPUTE)/ )[0] rescue RuntimeError
16
+ elsif type == 'rra_type' # only RRA types (accepted values are AVERAGE, MIN, MAX, LAST
17
+ str = string.to_s.match( /(AVERAGE|MIN|MAX|LAST)/ )[0] rescue RuntimeError
18
+ elsif type == 'path' # sanitizes the PATH of the RRD db will match test.rrd and /path/test.rrd
19
+ str = string.to_s.gsub(';', '').gsub('`', '')
20
+ elsif type == 'imagetype'
21
+ str = string.to_s.match(/(PNG|SVG|EPS|PDF)/)[0] rescue RuntimeError #[-a|--imgformat PNG|SVG|EPS|PDF]
22
+ elsif type == 'rpn'
23
+ str = string.to_s.match(/(PRINT|GPRINT|COMMENT|VRULE|HRULE|LINE|AREA|TICK|SHIFT|TEXTALIGN|STACK)/)[0] rescue RuntimeError
24
+ elsif type == 'color'
25
+ # ACK ground, CANVAS, SHADEA left/top border,
26
+ #SHADEB right/bottom border, GRID, MGRID major grid,
27
+ # FONT, FRAME and axis of the graph or ARROW.
28
+ str = string.to_s.match(/(BACK|CANVAS|SHADEA|SHADEB|GRID|MGRIF|FONT|FRAME|ARROW)/)[0] rescue RuntimeError
29
+ end
30
+
31
+ if str.nil? || str=='RuntimeError'
32
+ raise "No match was returned when matching #{type}"
33
+ else
34
+ return str
35
+ end
36
+ end
37
+
38
+ # example usage:
39
+ # RRD.create('/test.rrd', {:step => 300, :heartbeat => 600,
40
+ # :ds => [ {:name => "test", :type => "GAUGE"}, {:name => "josh", :type => "GAUGE"} ] ,
41
+ # :xff => ".5", :rra => [ {:type => "max", :steps => 20, :rows => 1} ] })
42
+ # first value is a path to the rrd db, the 2nd param is a hash of keys and values
43
+ # :ds is an array containing hashes for each DataSource (DS) type in the db
44
+ # :xff is the x files factor (see RRD website for more info on this), range is acceptable between 0 and 1
45
+ # :rra is a array containing hashes with RRA types and corresponding values
46
+ # :rra_hwpd is a hwpredict values
47
+ def self.create(path,params,rrdpath="rrdtool")
48
+
49
+ puts "Creating RRD graph"
50
+ puts "Step: " + self.sanitize(params[:step], 'num')
51
+ begin
52
+ cmd = "#{rrdpath} create #{self.sanitize(path, 'path')} --step #{self.sanitize(params[:step], 'num')} "
53
+
54
+ for p in params[:ds]
55
+ cmd << "DS:#{p[:name]}:#{self.sanitize(p[:type], 'ds_type')}:#{self.sanitize(params[:heartbeat], 'num')}:0:U "
56
+ end
57
+
58
+ xff = self.sanitize(params[:xff], 'num')
59
+ for r in params[:rra]
60
+ cmd << "RRA:#{r[:type].upcase}:#{xff}:#{self.sanitize(r[:steps], 'num')}:#{self.sanitize(r[:rows], 'num')} "
61
+ end
62
+
63
+ # hwpredict RRA:HWPREDICT:1440:0.1:0.0035:288
64
+ # # RRA:HWPREDICT:rows:alpha:beta:seasonal period[:rra-num]
65
+
66
+ for r in params[:rra_hwpd]
67
+ cmd << "RRA:#{r[:type].upcase}:#{r[:rows]}:#{r[:alpha]}:#{r[:beta]}:#{r[:period]} "
68
+ end
69
+
70
+ rescue RuntimeError => e
71
+ puts "RRD failed to create: #{e}"
72
+ else
73
+ cmd << " & "
74
+ puts "Running RRD command: #{cmd}"
75
+
76
+ system(cmd)
77
+ return cmd
78
+ end
79
+ end
80
+
81
+ # example usage:
82
+ # RRD.update('/test/path.rrd', ["123", "456a", 1234])
83
+ # first param is path to rrd db
84
+ # 2nd param will return data string of 123:456:1234 (each value is sanitized, only numeric values accepted)
85
+ # to be passed as the data values to be passed to the db
86
+ # N specifies the current time (NOW)
87
+ def self.update(path, params,rrdpath="rrdtool")
88
+
89
+
90
+ # sanitize the params
91
+ begin
92
+ sanitized = []
93
+ params.collect { |p| sanitized << self.sanitize(p, 'num') }
94
+ vals = sanitized.join(":")
95
+ cmd = "#{rrdpath} update #{self.sanitize(path, 'path')} N:#{vals}"
96
+ rescue RuntimeError => e
97
+ puts "RRD failed to update: #{e}"
98
+ else
99
+ puts "Running RRD command"
100
+ system(cmd)
101
+ return cmd
102
+ end
103
+ end
104
+
105
+ # variables for DEF's are taken care of programatically
106
+ # required params
107
+ # :ago is when to start from, a Time object ( Time.now )
108
+ # :width, :height
109
+ # :image_type
110
+ # :title
111
+ # :defs => array of hashes
112
+ # # [:defs][:key] => The DB data key
113
+ # # [:defs][:type] => RRA Type
114
+ # # [:defs][:rpn] => RPN Type
115
+ # # [:defs][:color] => Hex Color: (accepts: 001122 but not #001122)
116
+ # # [:defs][:title] => Title for this DEF
117
+ # optional params
118
+ # :base
119
+ # :vlabel
120
+ # :lowerlimit
121
+ # :upperlimit
122
+ # :background --background
123
+ def self.graph(path,image_path,params,rrdpath="rrdtool")
124
+
125
+
126
+ begin
127
+ cmd = "#{rrdpath} graph #{self.sanitize(image_path, 'path')} "
128
+ cmd << "-s #{self.sanitize(params[:ago].tv_sec, 'num')} "
129
+ cmd << "-w #{self.sanitize(params[:width], 'num')} -h #{self.sanitize(params[:height], 'num')} "
130
+ cmd << "-a #{self.sanitize(params[:image_type], 'imagetype')} "
131
+ cmd << "-t '#{self.sanitize(params[:title], 'alphanum')}' "
132
+
133
+ abet = "abcdefghijklmnaopqrstuvwxyzABCDEFGHIJKLMNAOPQRSTUVWXYZ".split('')
134
+ # do optionals
135
+ params[:base] ? cmd << " --base=#{self.sanitize(params[:base], 'num')} " : ""
136
+ params[:vlabel] ? cmd << " -v='#{self.sanitize(params[:vlabel], 'alphanum')}' " : ""
137
+ params[:lowerlimit] ? cmd << " --lower-limit=#{self.sanitize(params[:lowerlimit], 'num')} " : ""
138
+ params[:upperlimit] ? cmd << " --upper-limit=#{self.sanitize(params[:upperlimit], 'num')} " : ""
139
+ if params[:color]
140
+ for c in params[:color]
141
+ cmd << " --color #{self.sanitize(c[:type], 'color')}##{self.sanitize(c[:color], 'alphanum')} "
142
+ end
143
+ end
144
+ # load defs
145
+ i = 0
146
+ for d in params[:defs]
147
+ d_key = abet[i]
148
+ cmd << "DEF:#{d_key}='#{self.sanitize(path, 'path')}':#{self.sanitize(d[:key], 'alphanum')}:"
149
+ cmd << "#{self.sanitize(d[:type], 'rra_type')} #{self.sanitize(d[:rpn], 'rpn')}:#{d_key}"
150
+ cmd << "##{self.sanitize(d[:color], 'alphanum')}:'#{self.sanitize(d[:title], 'alphanum')}' "
151
+ i+=1
152
+ end
153
+ rescue RuntimeError => e
154
+ puts "RRD failed to graph: #{e}"
155
+ else
156
+ #cmd << " & "
157
+ puts "Running RRD command: #{cmd}"
158
+ system(cmd)
159
+ return cmd
160
+ end
161
+ end
162
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: RailsRRDTool
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Josh Rendek
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-23 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A wrapper around rrdtool to generate rrd graphs in ruby
15
+ email: josh@bluescripts.net
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/rrd.rb
21
+ homepage: https://github.com/bluescripts/rails_rrdtool
22
+ licenses: []
23
+ post_install_message:
24
+ rdoc_options: []
25
+ require_paths:
26
+ - lib
27
+ required_ruby_version: !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 1.8.15
42
+ signing_key:
43
+ specification_version: 3
44
+ summary: A wrapper around rrdtool to generate rrd graphs in ruby
45
+ test_files: []