"""
Friendly wrapper around the rrdtool python interface
"""
import rrdtool
import logging
log = logging.getLogger('rrdweb.rrd')
def normalize_option_key (key) :
"""
Normalize the given option key.
A -- is prepended, and _'s are converted to -
"""
return '--' + str(key).replace('_', '-')
def normalize_option_multi (key, values) :
"""
Normalize a list of option values, returning a series of --opt, val1, --opt, val2, ...
"""
for value in values :
yield key
yield str(value)
def normalize_option (key, value) :
"""
Normalize the given option to a series of cmd-args.
If value is None or False, no cmd-args are emitted. If value is True, only --opt is emitted. If value is a list,
--opt and value are emitted for each item.
Otherwise, both --opt and str(value) are emitted.
"""
key = normalize_option_key(key)
if value is None or value is False :
# omit
return ()
elif value is True :
# flag
return (key, )
elif isinstance(value, list) :
# list of option values
return tuple(normalize_option_multi(key, value))
else :
# option value
return (key, str(value))
def merge_opts (*all_opts) :
"""
Merge the given series of opt dicts
"""
out = dict()
for opts in all_opts :
# XXX: not strictly true, merge lists
out.update(opts)
return out
def run_cmd (func, pre_args, opts, post_args) :
"""
Run the given rrdtool.* function, formatting the given positional arguments and options.
"""
# series of (cmd-arg, cmd-arg, ...) tuples, giving all '--opt' and 'value' arguments for each keyword argument
opt_items = (normalize_option(key, value) for key, value in opts.iteritems())
# decomposed series of cmd-args for options
opt_args = [item for items in opt_items for item in items]
# positional arguments
pre_args = [str(arg) for arg in pre_args]
post_args = [str(arg) for arg in post_args]
# full arguments
args = pre_args + opt_args + ['--'] + post_args
log.debug('rrdtool %s %s', func.__name__, args)
return func(*args)
def graph (out_path, *args, **opts) :
"""
Create a graph from data stored in one or several RRDs.
Graph image output is written to the given path.
Returns... something to do with the image's dimensions, or even the data itself?
"""
return run_cmd(rrdtool.graph, (out_path, ), opts, args)
def create (rrd_path, *args, **opts) :
"""
Set up a new Round Robin Database (RRD).
"""
return run_cmd(rrdtool.create, (rrd_path, ), opts, args)
def update (rrd_path, *args, **opts) :
"""
Store new data values into an RRD.
"""
return run_cmd(rrdtool.update, (rrd_path, ), opts, args)