Class: Opower::TimeSeries::TSClient

Inherits:
Object
  • Object
show all
Defined in:
lib/time_series/ts_client.rb

Overview

Ruby client object to interface with an OpenTSDB instance.

Defined Under Namespace

Classes: PipelineWrapper

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host = '127.0.0.1', port = 4242, protocol = 'http') ⇒ TSClient

Creates a connection to a specified OpenTSDB instance

Parameters:

  • host (String) (defaults to: '127.0.0.1')

    The hostname/IP to connect to. Defaults to ‘localhost’.

  • port (Integer) (defaults to: 4242)

    The port to connect to. Defaults to 4242.

  • protocol (String) (defaults to: 'http')

    The protocol to use. Defaults to ‘http’.



21
22
23
24
25
26
27
28
29
# File 'lib/time_series/ts_client.rb', line 21

def initialize(host = '127.0.0.1', port = 4242, protocol = 'http')
  @host = host
  @port = port

  @client = "#{protocol}://#{host}:#{port}/"
  @connection = Excon.new(@client, persistent: true, idempotent: true, tcp_nodelay: true)
  @connection_settings = @connection.data
  configure
end

Instance Attribute Details

#clientObject

Returns the value of attribute client.



12
13
14
# File 'lib/time_series/ts_client.rb', line 12

def client
  @client
end

#configObject

Returns the value of attribute config.



12
13
14
# File 'lib/time_series/ts_client.rb', line 12

def config
  @config
end

#connectionObject

Returns the value of attribute connection.



12
13
14
# File 'lib/time_series/ts_client.rb', line 12

def connection
  @connection
end

#connection_settingsObject

Returns the value of attribute connection_settings.



12
13
14
# File 'lib/time_series/ts_client.rb', line 12

def connection_settings
  @connection_settings
end

#hostObject

Returns the value of attribute host.



12
13
14
# File 'lib/time_series/ts_client.rb', line 12

def host
  @host
end

#portObject

Returns the value of attribute port.



12
13
14
# File 'lib/time_series/ts_client.rb', line 12

def port
  @port
end

Instance Method Details

#configure(cfg = {}) ⇒ Object

Configures client-specific options

Parameters:

  • cfg (Hash) (defaults to: {})

    The configuration options to set.

Options Hash (cfg):

  • :dry_run (Boolean)

    When set to true, the client does not actually read/write to OpenTSDB.

  • :version (String)

    The version of OpenTSDB to run against. Defaults to 2.0.



36
37
38
39
40
41
42
43
44
# File 'lib/time_series/ts_client.rb', line 36

def configure(cfg = {})
  @config = { dry_run: false, version: '2.0' }
  @valid_config_keys = @config.keys

  cfg.each do |key, value|
    key = key.to_sym
    @config[key] = value if @valid_config_keys.include?(key)
  end
end

#query_uri(query) ⇒ String

Returns the full URI for the query in the context of this client.

Parameters:

  • query (Query)

    The query object

Returns:

  • (String)

    the URI



107
108
109
# File 'lib/time_series/ts_client.rb', line 107

def query_uri(query)
  @client + 'api/query?' + query.as_graph
end

#run_queries(queries) ⇒ Array

Runs the specified queries against OpenTSDB in a HTTP pipelined connection.

Parameters:

  • queries (Array)

    An array of queries to run against OpenTSDB.

Returns:

  • (Array)

    a matching array of results for each query



131
132
133
134
135
136
137
138
139
# File 'lib/time_series/ts_client.rb', line 131

def run_queries(queries)
  # requests cannot be idempotent when pipelined, so we temporarily disable it
  @connection_settings[:idempotent] = false

  results = run_pipelined_request(queries)

  @connection_settings[:idempotent] = true
  results
end

#run_query(query) ⇒ Result || String

Runs the specified query against OpenTSDB. If config is set to true or PNG format requested, it will only return the URL for the query. Otherwise it will return a Result object.

Parameters:

  • query (Query)

    The query object to execute with.

Returns:

  • (Result || String)

    the results of the query



98
99
100
101
# File 'lib/time_series/ts_client.rb', line 98

def run_query(query)
  return query_uri(query) if @config[:dry_run] || query.format == :png
  Result.new(@connection.get(path: 'api/query', query: query.request))
end

#run_synthetic_query(name, formula, query_hash) ⇒ SyntheticResult

Runs a synthetic query using queries against OpenTSDB. It expects a formula and a matching Hash which maps parameters in the formula to time_series’ query objects.

Parameters:

  • name (String)

    the alias for this synthetic series

  • formula (String)

    the Dentaku calculator formula to use

  • query_hash (Hash)

    a Hash containing Query objects that map to corresponding parameters in the formula

Returns:



118
119
120
121
122
123
124
125
# File 'lib/time_series/ts_client.rb', line 118

def run_synthetic_query(name, formula, query_hash)
  results_hash = query_hash.map { |key, query| { key => run_query(query).results[0].fetch('dps') } }
  results_hash = results_hash.reduce do |results, result|
    results.merge(result)
  end

  SyntheticResult.new(name, formula, results_hash)
end

#suggest(query, type = 'metrics', max = 25) ⇒ Array

Returns suggestions for metric or tag names

Parameters:

  • query (String)

    The string to search for

  • type (String) (defaults to: 'metrics')

    The type to search for: ‘metrics’, ‘tagk’, ‘tagv’

Returns:

  • (Array)

    an array of possible values based on the query/type



62
63
64
65
# File 'lib/time_series/ts_client.rb', line 62

def suggest(query, type = 'metrics', max = 25)
  return suggest_uri(query, type, max) if @config[:dry_run]
  JSON.parse(@connection.get(path: 'api/suggest', query: { type: type, q: query, max: max }).body)
end

#suggest_uri(query, type = 'metrics', max = 25) ⇒ String

Returns the full URI for the suggest query in the context of this client.

Parameters:

  • query (String)

    The string to search for

  • type (String) (defaults to: 'metrics')

    The type to search for: ‘metrics’, ‘tagk’, ‘tagv’

Returns:

  • (String)

    the URI



72
73
74
# File 'lib/time_series/ts_client.rb', line 72

def suggest_uri(query, type = 'metrics', max = 25)
  @client + "api/suggest?type=#{type}&q=#{query}&max=#{max}"
end

#valid?Boolean

Basic check to see if the OpenTSDB is reachable

Returns:

  • (Boolean)

    true if call against api/version resolves



49
50
51
52
53
54
# File 'lib/time_series/ts_client.rb', line 49

def valid?
  @connection.get(path: 'api/version')
  true
rescue Excon::Errors::SocketError, Excon::Errors::Timeout
  false
end

#write(metric) ⇒ Object

Writes the specified Metric object to OpenTSDB.

Parameters:

  • metric (Metric)

    The metric to write to OpenTSDB



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/time_series/ts_client.rb', line 79

def write(metric)
  cmd = "echo \"put #{metric}\" | nc -w 30 #{@host} #{@port}"

  if @config[:dry_run]
    cmd
  else
    # Write into the db
    ret = system(cmd)

    # Command failed to run
    fail(IOError, "Failed to insert metric #{metric.name} with value of #{metric.value} into OpenTSDB.") unless ret
  end
end