class Grafana::GraphiteDatasource

Implements the interface to graphite datasources.

Public Class Methods

handles?(model) click to toggle source

@see AbstractDatasource#handles?

# File lib/grafana/graphite_datasource.rb, line 7
def self.handles?(model)
  tmp = new(model)
  tmp.type == 'graphite'
end

Public Instance Methods

default_variable_format() click to toggle source

@see AbstractDatasource#default_variable_format

# File lib/grafana/graphite_datasource.rb, line 40
def default_variable_format
    'glob'
end
raw_query_from_panel_model(panel_query_target) click to toggle source

@see AbstractDatasource#raw_query_from_panel_model

# File lib/grafana/graphite_datasource.rb, line 35
def raw_query_from_panel_model(panel_query_target)
  panel_query_target['target']
end
request(query_description) click to toggle source

:raw_query needs to contain a Graphite query as String @see AbstractDatasource#request

# File lib/grafana/graphite_datasource.rb, line 14
def request(query_description)
  raise MissingSqlQueryError if query_description[:raw_query].nil?

  request = {
    body: URI.encode_www_form('from': DateTime.strptime(query_description[:from], '%Q').strftime('%H:%M_%Y%m%d'),
                              'until': DateTime.strptime(query_description[:to], '%Q').strftime('%H:%M_%Y%m%d'),
                              'format': 'json',
                              'target': replace_variables(query_description[:raw_query], query_description[:variables])),
    content_type: 'application/x-www-form-urlencoded',
    request: Net::HTTP::Post
  }

  webrequest = query_description[:prepared_request]
  webrequest.relative_url = "/api/datasources/proxy/#{id}/render"
  webrequest.options.merge!(request)

  result = webrequest.execute(query_description[:timeout])
  preformat_response(result.body)
end

Private Instance Methods

preformat_response(response_body) click to toggle source

@see AbstractDatasource#preformat_response

# File lib/grafana/graphite_datasource.rb, line 47
def preformat_response(response_body)
  json = JSON.parse(response_body)

  header = ['time']
  content = {}

  # keep sorting, if json has only one target item, otherwise merge results and return
  # as a time sorted array
  return { header: header << json.first['target'], content: json.first['datapoints'].map! { |item| [item[1], item[0]] } } if json.length == 1

  # TODO: show warning if results may be sorted different
  json.each_index do |i|
    header << json[i]['target']
    tmp = json[i]['datapoints'].map! { |item| [item[1], item[0]] }.to_h
    tmp.each_key { |key| content[key] = Array.new(json.length) unless content[key] }

    content.merge!(tmp) do |_key, old, new|
      old[i] = new
      old
    end
  end

  { header: header, content: content.to_a.map(&:flatten).sort { |a, b| a[0] <=> b[0] } }
end