opentsdb-ruby 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ebb5075958cfa76233980e4dae55bd0ad30e28e
4
- data.tar.gz: 003174b10051ea7d851344a17ca254a31136d9d3
3
+ metadata.gz: 137e3fc251ccc866b3211c17710181c233d3e5d3
4
+ data.tar.gz: 30fd3ba112c0cbee000a2c921f1558695ca4ecff
5
5
  SHA512:
6
- metadata.gz: 827664beb3f3aaea2c5a2e010940738214bec02afdba5532629eaf9747bd418668a7f6e8655192fa607914320906d1d330315501c8cfa889b907b879befd5a46
7
- data.tar.gz: 51b7fd589fa67d8490133476336a3e11070d0798062da5588d3a41fee5a38dabbffb0fca6b93734de1cdcee0f9878fd449ebacb6a6c53ba02a918563b2597ab5
6
+ metadata.gz: 260ed6de97dab70facdcf5442446fb2006d178170954323bc2c6b48844e7981a3a45630c0fe1252fa86f7b20ee1f8b773368b052670f40682917ba055a4442e7
7
+ data.tar.gz: 9cd16e28f2e7d80722901652cfcf3425430aaa886cb79163811f4c03090be6d9545696f4fc89cc8adb5ad6c5819ef763c95f15265aad64b5222ab00da014aa7c
data/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  Ruby client for OpenTSDB HTTP Query API.
4
4
 
5
- [![Build Status](https://travis-ci.org/cloudinsight/opentsdb-ruby.png)](https://travis-ci.org/cloudinsight/opentsdb-ruby) [![Code Climate](https://codeclimate.com/github/cloudinsight/opentsdb-ruby/badges/gpa.svg)](https://codeclimate.com/github/cloudinsight/opentsdb-ruby)
5
+ [![Gem Version](http://img.shields.io/gem/v/opentsdb-ruby.svg)](https://rubygems.org/gems/opentsdb-ruby) [![Build Status](https://travis-ci.org/cloudinsight/opentsdb-ruby.png)](https://travis-ci.org/cloudinsight/opentsdb-ruby) [![Code Climate](https://codeclimate.com/github/cloudinsight/opentsdb-ruby/badges/gpa.svg)](https://codeclimate.com/github/cloudinsight/opentsdb-ruby)
6
6
  ## Installation
7
7
 
8
8
  Add this line to your application's Gemfile:
9
9
 
10
10
  ```ruby
11
- gem 'openstd-ruby', github: 'cloudinsight/opentsdb-ruby'
11
+ gem 'opentsdb-ruby'
12
12
  ```
13
13
 
14
14
  And then execute:
@@ -17,45 +17,42 @@ And then execute:
17
17
 
18
18
  Or install it yourself as:
19
19
 
20
- $ gem install openstd-ruby
20
+ $ gem install opentsdb-ruby
21
21
 
22
22
 
23
23
  ## Quick Start Guide
24
24
 
25
- ### Configure openstdb
25
+ ### Configure opentsdb
26
26
 
27
27
  ```ruby
28
- #config/initializers/cloudinsight_openstdb.rb
28
+ #config/initializers/opentsdb.rb
29
29
 
30
- if defined?(CloudInsight)
31
- CloudInsight::Opentsdb.configure do |config|
30
+ Opentsdb.configure do |config|
32
31
  config.host = 'localhost' # opentsdb server host default: localhost
33
32
  config.port = 4242 # opentsdb server port default: 4242
34
33
  end
35
- end
36
-
37
34
  ```
38
35
 
39
36
  ### Usage
40
37
 
41
38
  ```ruby
42
39
 
43
- # define simple query params
40
+ # define simple query params
44
41
  params = { begin: Time.now.ago(1.hour), q: 'avg:system.load.1{host=*}' }
45
42
  # opensted
46
- client = CloudInsight::Opentsdb::Client.new(params)
43
+ client = Opentsdb::Client.new(params)
47
44
  result = client.query # opentsdb json result
48
45
 
49
46
 
50
- # complicate query params
47
+ # complicate query params
51
48
  params = { begin: Time.now.ago(1.hour), end: Time.now, q: 'avg:system.load.1{host=server1, host=server2, tagk=tagv}by{host}', interval: 360 }
52
- client = CloudInsight::Opentsdb::Client.new(params)
49
+ client = Opentsdb::Client.new(params)
53
50
  result = client.query # opentsdb json result
54
51
 
55
52
 
56
- # reconfig opentsdb host port
53
+ # reconfig opentsdb host port
57
54
  params = { host: '192.168.0.100', port: 8000, q: 'avg:system.load.1{host=*}' }
58
- client = CloudInsight::Opentsdb::Client.new(params)
55
+ client = Opentsdb::Client.new(params)
59
56
  result = client.query # opentsdb json result
60
57
  ```
61
58
 
data/lib/opentsdb.rb ADDED
@@ -0,0 +1,38 @@
1
+ # :nodoc:
2
+ module Opentsdb
3
+ #:nodoc:
4
+ class << self
5
+ attr_accessor :host, :port
6
+
7
+ def configure
8
+ yield self
9
+ end
10
+
11
+ def host
12
+ @host || 'localhost'
13
+ end
14
+
15
+ def port
16
+ @port || 4242
17
+ end
18
+
19
+ def reset
20
+ @host = nil
21
+ @port = nil
22
+ end
23
+
24
+ def logger
25
+ @logger ||= begin
26
+ Logger.new(STDOUT).tap { |logger| logger.datetime_format = '%Y-%m-%d %H:%M:%S' }
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ require 'logger'
33
+ require 'net/http'
34
+ require 'opentsdb/version'
35
+ require 'opentsdb/client'
36
+ require 'opentsdb/query_parser'
37
+ require 'opentsdb/query_param'
38
+ require 'forwardable'
@@ -0,0 +1,44 @@
1
+ require_relative 'http_client'
2
+ module Opentsdb
3
+ # ruby client for OpenTsdb HTTP API
4
+ class Client
5
+ extend Forwardable
6
+
7
+ def_instance_delegators :@http, :post
8
+
9
+ attr_reader :host, :port, :query_options
10
+
11
+ def initialize(options = {})
12
+ @host = options.delete(:host) || Opentsdb.host
13
+ @port = options.delete(:port) || Opentsdb.port
14
+ @http = HttpClient.new
15
+ @query_options = options
16
+ end
17
+
18
+ def query
19
+ [].tap do |data|
20
+ parse_queries.each do |query_commad|
21
+ data << post(query_uri, query_commad.to_json)
22
+ end
23
+ end
24
+ end
25
+
26
+ def parse_queries
27
+ [].tap do |qs|
28
+ query_options[:q].split(';').each do |q|
29
+ query = QueryParser.parse(q)
30
+ query.interval = query_options[:interval]
31
+ query.start_time = query_options[:begin].to_i
32
+ query.end_time = query_options[:end].to_i
33
+ qs << query
34
+ end
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def query_uri
41
+ URI("http://#{host}:#{port}/api/query")
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,36 @@
1
+ require 'net/http'
2
+ require 'benchmark'
3
+ module Opentsdb
4
+ # :nodoc:
5
+ class HttpClient
6
+ def post(uri, body)
7
+ send_http(uri) do |http|
8
+ Opentsdb.logger.debug "Http post body: #{body}"
9
+ req = Net::HTTP::Post.new(uri, headers)
10
+ req.body = body
11
+ http.request(req)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def headers
18
+ { 'Content-Type' => 'application/json; charset=UTF-8' }
19
+ end
20
+
21
+ def send_http(uri)
22
+ Opentsdb.logger.info "Http request uri: #{uri}"
23
+ http = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https')
24
+ res = nil
25
+ time = Benchmark.realtime do
26
+ res = yield(http)
27
+ end
28
+ Opentsdb.logger.info "Response: #{res.code} consume: #{time} s"
29
+ res
30
+ rescue Timeout::Error, Errno::ECONNRESET, Net::HTTPBadResponse,
31
+ Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
32
+ Opentsdb.logger.error "Http request error: #{e}"
33
+ false
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,63 @@
1
+ # :nodoc:
2
+ class QueryParam
3
+ attr_accessor :aggregator, :rate, :metric, :tags, :downsample, :interval
4
+ attr_accessor :start_time, :end_time, :queries
5
+
6
+ def initialize(options = {})
7
+ @aggregator = options[:aggregator]
8
+ @rate = options[:rate] || false
9
+ @metric = options[:metric]
10
+ @tags = options[:tags] || {}
11
+ end
12
+
13
+ def start_time
14
+ @start_time > 0 ? to_ms(@start_time) : (end_time - 3_600_000) # 1 hour ago
15
+ end
16
+
17
+ def end_time
18
+ @end_time > 0 ? to_ms(@end_time) : to_ms(Time.now)
19
+ end
20
+
21
+ def to_json
22
+ {}.tap do |h|
23
+ h[:start] = start_time
24
+ h[:end] = end_time
25
+ h[:queries] = queries
26
+ end.to_json
27
+ end
28
+
29
+ def tags
30
+ @tags.each do |tagk, tagv|
31
+ @tags[tagk] = tagv.to_a.compact.join('|') if tagv.is_a?(Array) || tagv.is_a?(Set)
32
+ end
33
+ end
34
+
35
+ def downsample
36
+ "#{interval}s-#{aggregator_for}" if interval
37
+ end
38
+
39
+ private
40
+
41
+ def to_ms(time = Time.now)
42
+ (time.to_f * 1000).to_i
43
+ end
44
+
45
+ def queries
46
+ [{}.tap do |qh|
47
+ qh[:aggregator] = aggregator
48
+ qh[:rate] = rate
49
+ qh[:metric] = metric
50
+ qh[:tags] = tags
51
+ qh[:downsample] = downsample if downsample
52
+ end]
53
+ end
54
+
55
+ def aggregator_for
56
+ case aggregator
57
+ when 'sum', 'avg' then 'avg'
58
+ when 'min' then 'mimmin'
59
+ when 'max' then 'mimmax'
60
+ else 'avg'
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,78 @@
1
+ module Opentsdb
2
+ # :nodoc:
3
+ class QueryParser
4
+ class << self
5
+ def parse(q_string)
6
+ parts = split_for(q_string, ':')
7
+ return nil if parts.size < 2 || parts.size > 3
8
+ metric_query = {}
9
+ metric_query[:aggregator] = parts[0]
10
+ metric_query[:rate] = false
11
+ temp = parts[1]
12
+ if parts.size == 3
13
+ metric_query[:rate] = true if temp.start_with?('rate')
14
+ temp = parts[2]
15
+ end
16
+ query_metric = parse_query_metric(temp)
17
+ QueryParam.new metric_query.merge(query_metric)
18
+ end
19
+
20
+ private
21
+
22
+ def parse_query_metric(metric)
23
+ start_index = metric.index('{')
24
+ return { metric: metric } unless start_index
25
+ {}.tap do |h|
26
+ h[:metric] = metric[0...start_index]
27
+ end_index = metric.index('}')
28
+ h[:tags] = parse_tags metric[(start_index + 1)...end_index].strip
29
+ groups_str = metric[(end_index + 1)..-1]
30
+ if groups_str.size > 5 # length of by{} is 4
31
+ h[:group] = parse_groups groups_str
32
+ h[:group].each { |group| h[:tags][group] ||= ['*'] }
33
+ end
34
+ end
35
+ end
36
+
37
+ def parse_tags(tags)
38
+ return if tags.nil?
39
+ rtags = {}
40
+ split_for(tags, ',').each do |tag|
41
+ tagk, tagv = split_for(tag, '=')
42
+ next if tagk.nil? || tagv.nil?
43
+ rtags[tagk] ||= []
44
+ rtags[tagk].concat tagv.split('|').uniq
45
+ end
46
+ rtags
47
+ end
48
+
49
+ def parse_groups(groups_str)
50
+ start_index = groups_str.index('{')
51
+ end_index = groups_str.index('}')
52
+ groups = groups_str[(start_index + 1)...end_index].strip
53
+ return [] if groups.empty?
54
+ split_for(groups, ',').map(&:strip)
55
+ end
56
+
57
+ def split_for(string, token = ':')
58
+ result = []
59
+ index = start = pos = 0
60
+ is_in_bracket = false
61
+ string.each_char do |char|
62
+ if char == '{'
63
+ is_in_bracket = true
64
+ elsif char == '}'
65
+ is_in_bracket = false
66
+ elsif char == token && !is_in_bracket
67
+ result[index] = string[start...pos]
68
+ index += 1
69
+ start = pos + 1
70
+ end
71
+ pos += 1
72
+ end
73
+ result[index] = string[start...pos]
74
+ result
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ module Opentsdb
2
+ VERSION = '0.0.2'.freeze
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentsdb-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - lizhe
@@ -88,6 +88,9 @@ dependencies:
88
88
  - - ~>
89
89
  - !ruby/object:Gem::Version
90
90
  version: '3.0'
91
+ - - '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 3.0.8
91
94
  type: :development
92
95
  prerelease: false
93
96
  version_requirements: !ruby/object:Gem::Requirement
@@ -95,6 +98,9 @@ dependencies:
95
98
  - - ~>
96
99
  - !ruby/object:Gem::Version
97
100
  version: '3.0'
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: 3.0.8
98
104
  - !ruby/object:Gem::Dependency
99
105
  name: guard-minitest
100
106
  requirement: !ruby/object:Gem::Requirement
@@ -146,12 +152,12 @@ extensions: []
146
152
  extra_rdoc_files: []
147
153
  files:
148
154
  - README.md
149
- - lib/cloudinsight/opentsdb.rb
150
- - lib/cloudinsight/opentsdb/client.rb
151
- - lib/cloudinsight/opentsdb/http_client.rb
152
- - lib/cloudinsight/opentsdb/query_param.rb
153
- - lib/cloudinsight/opentsdb/query_parser.rb
154
- - lib/cloudinsight/opentsdb/version.rb
155
+ - lib/opentsdb.rb
156
+ - lib/opentsdb/client.rb
157
+ - lib/opentsdb/http_client.rb
158
+ - lib/opentsdb/query_param.rb
159
+ - lib/opentsdb/query_parser.rb
160
+ - lib/opentsdb/version.rb
155
161
  homepage: https://github.com/cloudinsight/opentsdb-ruby
156
162
  licenses:
157
163
  - MIT
@@ -1,39 +0,0 @@
1
- module CloudInsight
2
- # :nodoc:
3
- module Opentsdb
4
- #:nodoc:
5
- class << self
6
- attr_accessor :host, :port
7
-
8
- def configure
9
- yield self
10
- end
11
-
12
- def host
13
- @host || 'localhost'
14
- end
15
-
16
- def port
17
- @port || 4242
18
- end
19
-
20
- def reset
21
- @host = nil
22
- @port = nil
23
- end
24
-
25
- def logger
26
- @logger ||= begin
27
- Logger.new(STDOUT).tap { |logger| logger.datetime_format = '%Y-%m-%d %H:%M:%S' }
28
- end
29
- end
30
- end
31
- end
32
- end
33
- require 'logger'
34
- require 'net/http'
35
- require 'cloudinsight/opentsdb/version'
36
- require 'cloudinsight/opentsdb/client'
37
- require 'cloudinsight/opentsdb/query_parser'
38
- require 'cloudinsight/opentsdb/query_param'
39
- require 'forwardable'
@@ -1,46 +0,0 @@
1
- require_relative 'http_client'
2
- module CloudInsight
3
- module Opentsdb
4
- # ruby client for OpenTsdb HTTP API
5
- class Client
6
- extend Forwardable
7
-
8
- def_instance_delegators :@http, :post
9
-
10
- attr_reader :host, :port, :query_options
11
-
12
- def initialize(options = {})
13
- @host = options.delete(:host) || Opentsdb.host
14
- @port = options.delete(:port) || Opentsdb.port
15
- @http = HttpClient.new
16
- @query_options = options
17
- end
18
-
19
- def query
20
- [].tap do |data|
21
- parse_queries.each do |query_commad|
22
- data << post(query_uri, query_commad.to_json)
23
- end
24
- end
25
- end
26
-
27
- def parse_queries
28
- [].tap do |qs|
29
- query_options[:q].split(';').each do |q|
30
- query = QueryParser.parse(q)
31
- query.interval = query_options[:interval]
32
- query.start_time = query_options[:begin].to_i
33
- query.end_time = query_options[:end].to_i
34
- qs << query
35
- end
36
- end
37
- end
38
-
39
- private
40
-
41
- def query_uri
42
- URI("http://#{host}:#{port}/api/query")
43
- end
44
- end
45
- end
46
- end
@@ -1,38 +0,0 @@
1
- require 'net/http'
2
- require 'benchmark'
3
- module CloudInsight
4
- module Opentsdb
5
- # :nodoc:
6
- class HttpClient
7
- def post(uri, body)
8
- send_http(uri) do |http|
9
- Opentsdb.logger.debug "Http post body: #{body}"
10
- req = Net::HTTP::Post.new(uri, headers)
11
- req.body = body
12
- http.request(req)
13
- end
14
- end
15
-
16
- private
17
-
18
- def headers
19
- { 'Content-Type' => 'application/json; charset=UTF-8' }
20
- end
21
-
22
- def send_http(uri)
23
- Opentsdb.logger.info "Http request uri: #{uri}"
24
- http = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https')
25
- res = nil
26
- time = Benchmark.realtime do
27
- res = yield(http)
28
- end
29
- Opentsdb.logger.info "Response: #{res.code} consume: #{time} s"
30
- res
31
- rescue Timeout::Error, Errno::ECONNRESET, Net::HTTPBadResponse,
32
- Net::HTTPHeaderSyntaxError, Net::ProtocolError => e
33
- Opentsdb.logger.error "Http request error: #{e}"
34
- false
35
- end
36
- end
37
- end
38
- end
@@ -1,65 +0,0 @@
1
- module CloudInsight
2
- # :nodoc:
3
- class QueryParam
4
- attr_accessor :aggregator, :rate, :metric, :tags, :downsample, :interval
5
- attr_accessor :start_time, :end_time, :queries
6
-
7
- def initialize(options = {})
8
- @aggregator = options[:aggregator]
9
- @rate = options[:rate] || false
10
- @metric = options[:metric]
11
- @tags = options[:tags] || {}
12
- end
13
-
14
- def start_time
15
- @start_time > 0 ? to_ms(@start_time) : (end_time - 3_600_000) # 1 hour ago
16
- end
17
-
18
- def end_time
19
- @end_time > 0 ? to_ms(@end_time) : to_ms(Time.now)
20
- end
21
-
22
- def to_json
23
- {}.tap do |h|
24
- h[:start] = start_time
25
- h[:end] = end_time
26
- h[:queries] = queries
27
- end.to_json
28
- end
29
-
30
- def tags
31
- @tags.each do |tagk, tagv|
32
- @tags[tagk] = tagv.to_a.compact.join('|') if tagv.is_a?(Array) || tagv.is_a?(Set)
33
- end
34
- end
35
-
36
- def downsample
37
- "#{interval}s-#{aggregator_for}" if interval
38
- end
39
-
40
- private
41
-
42
- def to_ms(time = Time.now)
43
- (time.to_f * 1000).to_i
44
- end
45
-
46
- def queries
47
- [{}.tap do |qh|
48
- qh[:aggregator] = aggregator
49
- qh[:rate] = rate
50
- qh[:metric] = metric
51
- qh[:tags] = tags
52
- qh[:downsample] = downsample if downsample
53
- end]
54
- end
55
-
56
- def aggregator_for
57
- case aggregator
58
- when 'sum', 'avg' then 'avg'
59
- when 'min' then 'mimmin'
60
- when 'max' then 'mimmax'
61
- else 'avg'
62
- end
63
- end
64
- end
65
- end
@@ -1,80 +0,0 @@
1
- module CloudInsight
2
- module Opentsdb
3
- # :nodoc:
4
- class QueryParser
5
- class << self
6
- def parse(q_string)
7
- parts = split_for(q_string, ':')
8
- return nil if parts.size < 2 || parts.size > 3
9
- metric_query = {}
10
- metric_query[:aggregator] = parts[0]
11
- metric_query[:rate] = false
12
- temp = parts[1]
13
- if parts.size == 3
14
- metric_query[:rate] = true if temp.start_with?('rate')
15
- temp = parts[2]
16
- end
17
- query_metric = parse_query_metric(temp)
18
- QueryParam.new metric_query.merge(query_metric)
19
- end
20
-
21
- private
22
-
23
- def parse_query_metric(metric)
24
- start_index = metric.index('{')
25
- return { metric: metric } unless start_index
26
- {}.tap do |h|
27
- h[:metric] = metric[0...start_index]
28
- end_index = metric.index('}')
29
- h[:tags] = parse_tags metric[(start_index + 1)...end_index].strip
30
- groups_str = metric[(end_index + 1)..-1]
31
- if groups_str.size > 5 # length of by{} is 4
32
- h[:group] = parse_groups groups_str
33
- h[:group].each { |group| h[:tags][group] ||= ['*'] }
34
- end
35
- end
36
- end
37
-
38
- def parse_tags(tags)
39
- return if tags.nil?
40
- rtags = {}
41
- split_for(tags, ',').each do |tag|
42
- tagk, tagv = split_for(tag, '=')
43
- next if tagk.nil? || tagv.nil?
44
- rtags[tagk] ||= []
45
- rtags[tagk].concat tagv.split('|').uniq
46
- end
47
- rtags
48
- end
49
-
50
- def parse_groups(groups_str)
51
- start_index = groups_str.index('{')
52
- end_index = groups_str.index('}')
53
- groups = groups_str[(start_index + 1)...end_index].strip
54
- return [] if groups.empty?
55
- split_for(groups, ',').map(&:strip)
56
- end
57
-
58
- def split_for(string, token = ':')
59
- result = []
60
- index = start = pos = 0
61
- is_in_bracket = false
62
- string.each_char do |char|
63
- if char == '{'
64
- is_in_bracket = true
65
- elsif char == '}'
66
- is_in_bracket = false
67
- elsif char == token && !is_in_bracket
68
- result[index] = string[start...pos]
69
- index += 1
70
- start = pos + 1
71
- end
72
- pos += 1
73
- end
74
- result[index] = string[start...pos]
75
- result
76
- end
77
- end
78
- end
79
- end
80
- end
@@ -1,5 +0,0 @@
1
- module CloudInsight
2
- module Opentsdb
3
- VERSION = '0.0.1'.freeze
4
- end
5
- end