opentsdb-ruby 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +62 -0
- data/lib/cloudinsight/opentsdb/client.rb +46 -0
- data/lib/cloudinsight/opentsdb/http_client.rb +38 -0
- data/lib/cloudinsight/opentsdb/query_param.rb +65 -0
- data/lib/cloudinsight/opentsdb/query_parser.rb +80 -0
- data/lib/cloudinsight/opentsdb/version.rb +5 -0
- data/lib/cloudinsight/opentsdb.rb +39 -0
- metadata +180 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2ebb5075958cfa76233980e4dae55bd0ad30e28e
|
4
|
+
data.tar.gz: 003174b10051ea7d851344a17ca254a31136d9d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 827664beb3f3aaea2c5a2e010940738214bec02afdba5532629eaf9747bd418668a7f6e8655192fa607914320906d1d330315501c8cfa889b907b879befd5a46
|
7
|
+
data.tar.gz: 51b7fd589fa67d8490133476336a3e11070d0798062da5588d3a41fee5a38dabbffb0fca6b93734de1cdcee0f9878fd449ebacb6a6c53ba02a918563b2597ab5
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# opentsdb-ruby
|
2
|
+
|
3
|
+
Ruby client for OpenTSDB HTTP Query API.
|
4
|
+
|
5
|
+
[](https://travis-ci.org/cloudinsight/opentsdb-ruby) [](https://codeclimate.com/github/cloudinsight/opentsdb-ruby)
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'openstd-ruby', github: 'cloudinsight/opentsdb-ruby'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install openstd-ruby
|
21
|
+
|
22
|
+
|
23
|
+
## Quick Start Guide
|
24
|
+
|
25
|
+
### Configure openstdb
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
#config/initializers/cloudinsight_openstdb.rb
|
29
|
+
|
30
|
+
if defined?(CloudInsight)
|
31
|
+
CloudInsight::Opentsdb.configure do |config|
|
32
|
+
config.host = 'localhost' # opentsdb server host default: localhost
|
33
|
+
config.port = 4242 # opentsdb server port default: 4242
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
```
|
38
|
+
|
39
|
+
### Usage
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
|
43
|
+
# define simple query params
|
44
|
+
params = { begin: Time.now.ago(1.hour), q: 'avg:system.load.1{host=*}' }
|
45
|
+
# opensted
|
46
|
+
client = CloudInsight::Opentsdb::Client.new(params)
|
47
|
+
result = client.query # opentsdb json result
|
48
|
+
|
49
|
+
|
50
|
+
# complicate query params
|
51
|
+
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)
|
53
|
+
result = client.query # opentsdb json result
|
54
|
+
|
55
|
+
|
56
|
+
# reconfig opentsdb host port
|
57
|
+
params = { host: '192.168.0.100', port: 8000, q: 'avg:system.load.1{host=*}' }
|
58
|
+
client = CloudInsight::Opentsdb::Client.new(params)
|
59
|
+
result = client.query # opentsdb json result
|
60
|
+
```
|
61
|
+
|
62
|
+
|
@@ -0,0 +1,46 @@
|
|
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
|
@@ -0,0 +1,38 @@
|
|
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
|
@@ -0,0 +1,65 @@
|
|
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
|
@@ -0,0 +1,80 @@
|
|
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
|
@@ -0,0 +1,39 @@
|
|
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'
|
metadata
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: opentsdb-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- lizhe
|
8
|
+
- luyingrui
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-05-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '10.0'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '10.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: minitest
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '5.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '5.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: minitest-reporters
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.1'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.1'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rubocop
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.40'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.40'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: guard
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '2.13'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '2.13'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: listen
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '3.0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ~>
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '3.0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: guard-minitest
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ~>
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '2.4'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ~>
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '2.4'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: mocha
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ~>
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '1.1'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '1.1'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: pry
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ~>
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0.10'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ~>
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0.10'
|
140
|
+
description: A ruby client library for querying data by OpenTSDB HTTP API.
|
141
|
+
email:
|
142
|
+
- lnz013@qq.com
|
143
|
+
- luyingrui@oneapm.com
|
144
|
+
executables: []
|
145
|
+
extensions: []
|
146
|
+
extra_rdoc_files: []
|
147
|
+
files:
|
148
|
+
- 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
|
+
homepage: https://github.com/cloudinsight/opentsdb-ruby
|
156
|
+
licenses:
|
157
|
+
- MIT
|
158
|
+
metadata:
|
159
|
+
allowed_push_host: https://rubygems.org
|
160
|
+
post_install_message:
|
161
|
+
rdoc_options: []
|
162
|
+
require_paths:
|
163
|
+
- lib
|
164
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: 2.0.0
|
169
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
requirements: []
|
175
|
+
rubyforge_project:
|
176
|
+
rubygems_version: 2.4.5
|
177
|
+
signing_key:
|
178
|
+
specification_version: 4
|
179
|
+
summary: Ruby client for OpenTSDB HTTP Query API.
|
180
|
+
test_files: []
|