Class: RRD::Wrapper

Inherits:
Object
  • Object
show all
Extended by:
FFI::Library
Defined in:
lib/rrd/wrapper.rb

Overview

Raw RRD Tool wrapper.

See oss.oetiker.ch/rrdtool/doc/rrdtool.en.html for details on the parameters

Defined Under Namespace

Classes: RRDBlob, RRDInfo, RRDInfoVal

Constant Summary collapse

INFO_TYPE =
{ 0 => :u_val, 1 => :u_cnt, 2 => :u_str, 3 => :u_int, 4 => :u_blob}
BANG_METHODS =
[:create!, :dump!, :fetch!, :first!, :graph!, :info!, :last!, :last_update!, :resize!, :restore!, :tune!, :update!]

Class Method Summary collapse

Class Method Details

.bang(method, *args, &block) ⇒ Object



369
370
371
372
373
# File 'lib/rrd/wrapper.rb', line 369

def bang(method, *args, &block)
  result = send(method, *args, &block)
  raise error unless result
  result
end

.clear_errorObject

Clear the error message.



361
362
363
# File 'lib/rrd/wrapper.rb', line 361

def clear_error
  rrd_clear_error
end

.create(*args) ⇒ Object

Set up a new Round Robin Database (RRD).



84
85
86
87
88
89
# File 'lib/rrd/wrapper.rb', line 84

def create(*args)
  argv = to_pointer(["create"] + args)
  rrd_create(args.size+1, argv) == 0
ensure
  free_pointers
end

.detect_rrd_libObject



11
12
13
14
15
16
17
18
19
# File 'lib/rrd/wrapper.rb', line 11

def self.detect_rrd_lib
  if defined?(RRD_LIB)
    RRD_LIB
  elsif ENV["RRD_LIB"]
    ENV["RRD_LIB"] 
  else
    "rrd"
  end
end

.dump(*args) ⇒ Object

Dump a binary RRD to an RRD in XML format.



92
93
94
95
96
97
# File 'lib/rrd/wrapper.rb', line 92

def dump(*args)
  argv = to_pointer(["dump"] + args)
  rrd_dump(args.size+1, argv) == 0
ensure
  free_pointers
end

.errorObject

Returns the error happened.



356
357
358
# File 'lib/rrd/wrapper.rb', line 356

def error
  rrd_get_error
end

.fetch(*args) ⇒ Object

Get data for a certain time period from a RRD.

Returns an array of arrays (which contains the date and values for all datasources):

[["time"    , "cpu", "memory"],
 [1266933600, "0.5", "511"   ],
 [1266933900, "0.9", "253"   ]]


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/rrd/wrapper.rb', line 107

def fetch(*args)
  #FIXME: Refactor this
  start_time_ptr = empty_pointer
  end_time_ptr = empty_pointer
  step_ptr = empty_pointer
  ds_count_ptr = empty_pointer
  ds_names_ptr = empty_pointer
  values_ptr = empty_pointer
  
  argv = to_pointer(["fetch"] + args)
  if respond_to?(:rrd_fetch_r)
    file = args[0]
    cf = args[1]
    options = {}
    args[2..-1].each_slice(2) {|v| options[v.first] = v.last}
    start_time = options["--start"]
    end_time = options["--end"]
    step = options["--resolution"]
    start_time_ptr.put_int(0, start_time.to_i)
    end_time_ptr.put_int(0, end_time.to_i)
    step_ptr.put_int(0, step.to_i)
    return false unless rrd_fetch_r(file, cf, start_time_ptr, end_time_ptr, step_ptr, ds_count_ptr, ds_names_ptr, values_ptr) == 0
  else
    return false unless rrd_fetch(args.size+1, argv, start_time_ptr, end_time_ptr, step_ptr, ds_count_ptr, ds_names_ptr, values_ptr) == 0
  end
  
  ds_count = ds_count_ptr.get_int(0)
  start_time = start_time_ptr.get_int(0)
  end_time = end_time_ptr.get_int(0)
  step = step_ptr.get_int(0)
  
  result_lines = (end_time-start_time)/step
  
  ds_names = ds_names_ptr.get_pointer(0).get_array_of_string(0, ds_count)
  values = values_ptr.get_pointer(0).get_array_of_double(0, result_lines * ds_count)
  
  result = [["time"] + ds_names]
  (0..result_lines-1).each do |line|
    date = start_time + line*step
    first = ds_count*line
    last = ds_count*line + ds_count - 1
    result << [date] + values[first..last]
  end
  
  free_in_rrd(*ds_names_ptr.read_pointer.read_array_of_pointer(ds_count))
  free_in_rrd(values_ptr.read_pointer, ds_names_ptr.read_pointer)
  
  result
ensure
  free_pointers
end

.first(*args) ⇒ Object

Find the first update time of an RRD.

Returns an integer unix time



221
222
223
224
225
226
227
228
# File 'lib/rrd/wrapper.rb', line 221

def first(*args)
  argv = to_pointer(["first"] + args)
  date = rrd_first(args.size+1, argv)
  return false if date == -1
  date
ensure
  free_pointers
end

.graph(*args) ⇒ Object

Create a graph from data stored in one or several RRDs.



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/rrd/wrapper.rb', line 231

def graph(*args)
  warn('Your RRDTool version contains a memory leak on rrd_graph function. Please, use carefully!') if ('1.3' <= rrd_strversion && rrd_strversion <= '1.4.2')
  argv = to_pointer(["graph"] + args)
  calcpr_ptr = empty_pointer
  xsize_ptr = empty_pointer
  ysize_ptr = empty_pointer
  ymin_ptr = empty_pointer
  ymax_ptr = empty_pointer
  result = rrd_graph(args.size+1, argv, calcpr_ptr, xsize_ptr, ysize_ptr, nil, ymin_ptr, ymax_ptr) == 0
  
  if (!calcpr_ptr.read_pointer.null?)
    iter = calcpr_ptr.read_pointer
    until ((pointer = iter.read_pointer).null?)
      iter += FFI::Type::POINTER.size
      free_in_rrd(pointer)
    end
    free_in_rrd(calcpr_ptr.read_pointer)
  end
  
  result
ensure
  free_pointers
end

.info(*args) ⇒ Object

Get information about an RRD.

Returns a hash with the information



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/rrd/wrapper.rb', line 258

def info(*args)
  argv = to_pointer(["info"] + args)
  ptr = result_ptr = rrd_info(args.size+1, argv)
    
  info = {}
  while result_ptr.address != 0
    item = RRD::Wrapper::RRDInfo.new result_ptr
    info[item[:key]] = item[:value][INFO_TYPE[item[:type]].to_sym]
    result_ptr = item[:next]
  end
  
  rrd_info_free(ptr)
  
  return false if info.empty?
  info
  
ensure
  free_pointers
end

.last(*args) ⇒ Object

Find the last update time of an RRD.

Returns an integer unix time



281
282
283
284
285
286
287
288
# File 'lib/rrd/wrapper.rb', line 281

def last(*args)
  argv = to_pointer(["last"] + args)
  date = rrd_last(args.size+1, argv)
  return false if date == -1
  date
ensure
  free_pointers
end

.last_update(file) ⇒ Object

Get the last entered data.

Returns an array of 2 arrays (one with datasource names and other with the values):

[["time"    , "cpu", "memory"],
 [1266933900, "0.9", "253"   ]]


297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/rrd/wrapper.rb', line 297

def last_update(file)
  raise "Please upgrade your rrdtool version before using last_update method" unless respond_to?(:rrd_lastupdate_r)
  update_time_ptr = empty_pointer
  ds_count_ptr = empty_pointer
  ds_names_ptr = empty_pointer
  values_ptr = empty_pointer
  
  return false if rrd_lastupdate_r(file, update_time_ptr, ds_count_ptr, ds_names_ptr, values_ptr) == -1
  update_time = update_time_ptr.get_ulong(0)
  ds_count = ds_count_ptr.get_ulong(0)
  ds_names = ds_names_ptr.read_pointer.get_array_of_string(0, ds_count)
  values = values_ptr.read_pointer.get_array_of_string(0, ds_count)
  values = values.map {|item| item.include?(".")? item.to_f : item.to_i} # Converting string to numeric

  free_in_rrd(*ds_names_ptr.read_pointer.read_array_of_pointer(ds_count))
  free_in_rrd(*values_ptr.read_pointer.read_array_of_pointer(ds_count))
  free_in_rrd(ds_names_ptr.read_pointer, values_ptr.read_pointer)

  [["time"] + ds_names, [update_time]+values]
ensure
  # free_pointers
end

.methodsObject



365
366
367
# File 'lib/rrd/wrapper.rb', line 365

def methods
  super + BANG_METHODS
end

.resize(*args) ⇒ Object

Used to modify the number of rows in an RRA

Creates a new file in the same directory, called ‘resize.rrd’



323
324
325
326
327
328
# File 'lib/rrd/wrapper.rb', line 323

def resize(*args)
  argv = to_pointer(["resize"] + args)
  rrd_resize(args.size+1, argv) == 0
ensure
  free_pointers
end

.restore(*args) ⇒ Object

Restore an RRD in XML format to a binary RRD.



331
332
333
334
335
336
# File 'lib/rrd/wrapper.rb', line 331

def restore(*args)
  argv = to_pointer(["restore"] + args)
  rrd_restore(args.size+1, argv) == 0
ensure
  free_pointers
end

.tune(*args) ⇒ Object

Allows you to alter some of the basic configuration values stored in the header area of a Round Robin Database.



340
341
342
343
344
345
# File 'lib/rrd/wrapper.rb', line 340

def tune(*args)
  argv = to_pointer(["tune"] + args)
  rrd_tune(args.size+1, argv) == 0
ensure
  free_pointers
end

.update(*args) ⇒ Object

Store new data values into an RRD.



348
349
350
351
352
353
# File 'lib/rrd/wrapper.rb', line 348

def update(*args)
  argv = to_pointer(["update"] + args)
  rrd_update(args.size+1, argv) == 0
ensure
  free_pointers
end

.xport(*args) ⇒ Object

int rrd_xport(

int argc,
char **argv,
int UNUSED(*xsize),
time_t *start,
time_t *end,        /* which time frame do you want ?
                     * will be changed to represent reality */
unsigned long *step,    /* which stepsize do you want? 
                         * will be changed to represent reality */
unsigned long *col_cnt, /* number of data columns in the result */
char ***legend_v,   /* legend entries */
rrd_value_t **data)


172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/rrd/wrapper.rb', line 172

def xport(*args)
  start_time_ptr = empty_pointer
  end_time_ptr = empty_pointer
  step_ptr = empty_pointer
  legend_count_ptr = empty_pointer
  legend_names_ptr = empty_pointer
  values_ptr = empty_pointer
  
  i_am_useless = empty_pointer
  
  
  argv = to_pointer(["xport"] + args)
  ret = rrd_xport(args.size+1, argv,
    i_am_useless, start_time_ptr, end_time_ptr, step_ptr,
    legend_count_ptr, legend_names_ptr, values_ptr)
  
  return false unless ret == 0
  
  
  legends_count = legend_count_ptr.get_int(0)
  start_time = start_time_ptr.get_int(0)
  end_time = end_time_ptr.get_int(0)
  step = step_ptr.get_int(0)
  
  result_lines = (end_time-start_time)/step
  
  legends = legend_names_ptr.get_pointer(0).get_array_of_string(0, legends_count)
  values = values_ptr.get_pointer(0).get_array_of_double(0, result_lines * legends_count)
  
  result = [["time"] + legends]
  (0..result_lines-1).each do |line|
    date = start_time + line*step
    first = legends_count*line
    last = legends_count*line + legends_count - 1
    result << [date] + values[first..last]
  end
  
  free_in_rrd(*legend_names_ptr.read_pointer.read_array_of_pointer(legends_count))
  free_in_rrd(values_ptr.read_pointer, legend_names_ptr.read_pointer)
  
  result
  
ensure
  free_pointers
end