lib/visage-app/collectd/json.rb in visage-app-0.3.3 vs lib/visage-app/collectd/json.rb in visage-app-0.9.0.pre1
- old
+ new
@@ -7,27 +7,23 @@
require 'yajl'
# Exposes RRDs as JSON.
#
# A loose shim onto RRDtool, with some extra logic to normalise the data.
-# Also provides a recommended color for rendering the data in a line graph.
#
class CollectdJSON
def initialize(opts={})
@rrddir = opts[:rrddir] || CollectdJSON.rrddir
- @fallback_colors = opts[:fallback_colors] || {}
- @used_fallbacks = []
end
# Entry point.
def json(opts={})
host = opts[:host]
plugin = opts[:plugin]
plugin_instances = opts[:plugin_instances][/\w.*/]
instances = plugin_instances.blank? ? '*' : '{' + plugin_instances.split('/').join(',') + '}'
- @colors = opts[:plugin_colors]
@plugin_names = []
rrdglob = "#{@rrddir}/#{host}/#{plugin}/#{instances}.rrd"
plugin_offset = @rrddir.size + 1 + host.size + 1
@@ -64,63 +60,36 @@
# A single rrd can have multiple data sets (multiple metrics within
# the same file). Separate the metrics.
rrd_data.each_pair do |source, metric|
- # filter out NaNs, so yajl doesn't choke
+ # Filter out NaNs and weirdly massive values so yajl doesn't choke
metric.map! do |datapoint|
- (!datapoint || datapoint.nan?) ? 0.0 : datapoint
+ case
+ when datapoint && datapoint.nan?
+ @tripped = true
+ @last_valid
+ when @tripped
+ @last_valid
+ else
+ @last_valid = datapoint
+ end
end
- # Sometimes the last value from the RRD is ridiculously large.
- metric.slice!(-1)
+ metric[-1] = 0.0
- color = color_for(:host => data[:host],
- :plugin => data[:plugin],
- :instance => data[:instance],
- :metric => source)
-
structure[data[:host]] ||= {}
structure[data[:host]][data[:plugin]] ||= {}
structure[data[:host]][data[:plugin]][data[:instance]] ||= {}
structure[data[:host]][data[:plugin]][data[:instance]][source] ||= {}
structure[data[:host]][data[:plugin]][data[:instance]][source][:start] ||= data[:start]
structure[data[:host]][data[:plugin]][data[:instance]][source][:finish] ||= data[:finish]
structure[data[:host]][data[:plugin]][data[:instance]][source][:data] ||= metric
- structure[data[:host]][data[:plugin]][data[:instance]][source][:color] ||= color
end
end
encoder = Yajl::Encoder.new
encoder.encode(structure)
- end
-
- # We append the recommended line color onto data set, so the javascript
- # doesn't try and have to work it out. This lets us use all sorts of funky
- # fallback logic when determining what colours should be used.
- def color_for(opts={})
-
- plugin = opts[:plugin]
- instance = opts[:instance]
- metric = opts[:metric]
-
- return fallback_color unless plugin
- return color_for(opts.merge(:plugin => plugin[/(.+)-.+$/, 1])) unless @colors[plugin]
- return fallback_color unless instance
- return color_for(opts.merge(:instance => instance[/(.+)-.+$/, 1])) unless @colors[plugin][instance]
- return @colors[plugin][instance][metric] if @colors[plugin][instance]
- return fallback_color
- end
-
- def fallback_color
- fallbacks = @fallback_colors.to_a.sort_by {|pair| pair[1]['fallback_order'] }
- fallback = fallbacks.find { |color| !@used_fallbacks.include?(color) }
- unless fallback
- @used_fallbacks = []
- fallback = fallbacks.find { |color| !@used_fallbacks.include?(color) }
- end
- @used_fallbacks << fallback
- fallback[1]['color'] || "#000"
end
class << self
attr_writer :rrddir