class Grafana::AbstractDatasource

This abstract class defines the base functionalities for the common datasource implementations. Additionally it provides a factory method to build a real datasource from a given specification.

Attributes

model[R]

Public Class Methods

build_instance(ds_model) click to toggle source

Factory method to build a datasource from a given datasource Hash description. @param ds_model [Hash] grafana specification of a single datasource @return [AbstractDatasource] instance of a fitting datasource implementation

# File lib/grafana/abstract_datasource.rb, line 29
def self.build_instance(ds_model)
  raise InvalidDatasourceQueryProvidedError, ds_model unless ds_model.is_a?(Hash)

  raise InvalidDatasourceQueryProvidedError, ds_model unless ds_model['meta'].is_a?(Hash)

  @@subclasses.each do |datasource_class|
    return datasource_class.new(ds_model) if datasource_class.handles?(ds_model)
  end

  UnsupportedDatasource.new(ds_model)
end
handles?(model) click to toggle source

Overwrite this method, to specify if the current datasource implementation handles the given model. This method is called by {build_instance} to determine, if the current datasource implementation can handle the given grafana model. By default this method returns false. @param model [Hash] grafana specification of the datasource to check @return [Boolean] True if fits, false otherwise

# File lib/grafana/abstract_datasource.rb, line 22
def self.handles?(model)
  false
end
inherited(subclass) click to toggle source

Registers the subclass as datasource. @param subclass [Class] class inheriting from this abstract class

# File lib/grafana/abstract_datasource.rb, line 13
def self.inherited(subclass)
  @@subclasses << subclass
end
new(model) click to toggle source
# File lib/grafana/abstract_datasource.rb, line 41
def initialize(model)
  @model = model
end

Public Instance Methods

category() click to toggle source

@return [String] category of the datasource, e.g. tsdb or sql

# File lib/grafana/abstract_datasource.rb, line 46
def category
  @model['meta']['category']
end
default_variable_format() click to toggle source

@abstract

Overwrite in subclass, to specify the default variable format during replacement of variables. @return [String] default {Variable#value_formatted} format

# File lib/grafana/abstract_datasource.rb, line 107
def default_variable_format
  raise NotImplementedError
end
id() click to toggle source

@return [Integer] ID of the datasource

# File lib/grafana/abstract_datasource.rb, line 61
def id
  @model['id'].to_i
end
name() click to toggle source

@return [String] name of the datasource

# File lib/grafana/abstract_datasource.rb, line 56
def name
  @model['name']
end
raw_query_from_panel_model(panel_query_target) click to toggle source

@abstract

The different datasources supported by grafana use different ways to store the query in the panel's JSON model. This method extracts a query from that description, that can be used by the {AbstractDatasource} implementation of the datasource.

@param panel_query_target [Hash] grafana panel target, which contains the query description @return [String] query string, which can be used as raw_query in a {#request}

# File lib/grafana/abstract_datasource.rb, line 99
def raw_query_from_panel_model(panel_query_target)
  raise NotImplementedError
end
request(query_description) click to toggle source

@abstract

Executes a request for the current database with the given options.

Used format of the response will always be the following:

{
  :header => [column_title_1, column_title_2],
  :content => [
                [row_1_column_1, row_1_column_2],
                [row_2_column_1, row_2_column_2]
              ]
}

@param query_description [Hash] query description, which will requested: @option query_description [String] :from from timestamp @option query_description [String] :to to timestamp @option query_description [Integer] :timeout expected timeout for the request @option query_description [WebRequest] :prepared_request prepared web request for relevant {Grafana} instance, if this is needed by datasource @option query_description [String] :raw_query raw query, which shall be executed. May include variables, which will be replaced before execution @option query_description [Hash<Variable>] :variables hash of variables, which can potentially be replaced in the given :raw_query @return [Hash] sql result formatted as stated above

# File lib/grafana/abstract_datasource.rb, line 87
def request(query_description)
  raise NotImplementedError
end
type() click to toggle source

@return [String] type of the datasource, e.g. mysql

# File lib/grafana/abstract_datasource.rb, line 51
def type
  @model['type'] || @model['meta']['id']
end

Private Instance Methods

replace_variables(string, variables = {}) click to toggle source

Replaces the grafana variables in the given string with their replacement value.

@param string [String] string in which the variables shall be replaced @param variables [Hash<String,Variable>] Hash containing the variables, which shall be replaced in the

given string

@return [String] string in which all variables are properly replaced

# File lib/grafana/abstract_datasource.rb, line 119
def replace_variables(string, variables = {})
  res = string
  repeat = true
  repeat_count = 0

  # TODO: find a proper way to replace variables recursively instead of over and over again
  # TODO: add tests for recursive replacement of variable
  while repeat && (repeat_count < 3)
    repeat = false
    repeat_count += 1

    variables.each do |name, variable|
      # only set ticks if value is string
      var_name = name.gsub(/^var-/, '')
      next unless var_name =~ /^\w+$/

      res = res.gsub(/(?:\$\{#{var_name}(?::(?<format>\w+))?\}|\$#{var_name}(?!\w))/) do
        format = default_variable_format
        if $LAST_MATCH_INFO
          format = $LAST_MATCH_INFO[:format] if $LAST_MATCH_INFO[:format]
        end
        variable.value_formatted(format)
      end
    end
    repeat = true if res.include?('$')
  end

  res
end