presto-metrics 0.2.6 → 0.3.0

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: c8592a3b20c830df773dd674d2788d97a1efcb2f
4
- data.tar.gz: a52c98446f0a94b05802382aa89c41369521feb8
3
+ metadata.gz: f68643372b784275eac1dd75ec8c9e4bd899f177
4
+ data.tar.gz: 6e5aca1a188c6a526175c8e6b2a4af254b46132a
5
5
  SHA512:
6
- metadata.gz: 77428d020bf697818cee9b087315dd75c02a7e65dd5ad1aed61b647c78477488eb674a4c626d9f0971c152f7c398d53b3f3f2278761935877766c831bd7f322e
7
- data.tar.gz: b8229d7b34a91245292651408a40d62b050618cd7c0f2eb8260abcc3d564c4b5d4ec09c06f4b2c6c1cd86b495482338fd2138c9c5d359c4144d287abc65243a8
6
+ metadata.gz: 6dbdd29162bb6f26f4cfaa83210d95c4270c2534efc1175a21f825c8349b5dd3eedd04c481ebc88d011f6142c18a42e6f490ae75249cddc790b334bfc3891c5b
7
+ data.tar.gz: b4cc203242ac159e0e7bd1a95693197bf38e3cc57007bcb024ee3efb97a5e72f2944adf37765f8e15ad60c7a9cf8bcdf5d14a2cd2f23acc03eeb16203e69f472
data/.gitignore CHANGED
@@ -12,3 +12,6 @@
12
12
  *.o
13
13
  *.a
14
14
  mkmf.log
15
+ *.iml
16
+ .idea
17
+ .ruby-version
data/Rakefile CHANGED
@@ -5,3 +5,7 @@ RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
7
7
 
8
+ desc "Open an irb session preloaded with this library"
9
+ task :console do
10
+ sh "irb -I lib -r presto/metrics.rb"
11
+ end
@@ -0,0 +1,174 @@
1
+
2
+ module Presto
3
+ module Metrics
4
+
5
+ class Client
6
+ def initialize(opts={})
7
+ require 'httparty'
8
+ require 'json'
9
+ require 'set'
10
+ require 'time'
11
+
12
+ @host = opts[:host] || 'localhost'
13
+ @port = opts[:port] || '8080'
14
+ @endpoint = opts[:endpoint] || "http://#{@host}:#{@port}"
15
+ @mbean_path = opts[:mbean_path] || '/v1/jmx/mbean'
16
+ @query_path = opts[:query_path] || '/v1/query'
17
+ @caml_case = opts[:caml_case] || false
18
+ end
19
+
20
+ @@MBEAN_ALIAS = {
21
+ 'memory' => 'java.lang:type=Memory',
22
+ 'gc_cms' => 'java.lang:type=GarbageCollector,name=ConcurrentMarkSweep',
23
+ 'gc_parnew' => 'java.lang:type=GarbageCollector,name=ParNew',
24
+ 'os' => 'java.lang:type=OperatingSystem',
25
+ 'query_manager' => 'com.facebook.presto.execution:name=QueryManager',
26
+ 'query_execution' => 'com.facebook.presto.execution:name=QueryExecution',
27
+ 'node_scheduler' => 'com.facebook.presto.execution:name=NodeScheduler',
28
+ 'task_executor' => 'com.facebook.presto.execution:name=TaskExecutor',
29
+ 'task_manager' => 'com.facebook.presto.execution:name=TaskManager'
30
+ }
31
+
32
+
33
+ def path(path)
34
+ c = path.split(/:/)
35
+ target = c[0]
36
+ mbean = @@MBEAN_ALIAS[target] || target
37
+ json_obj = get_metrics(mbean)
38
+ return json_obj if c.size <= 1
39
+ query_list = (c[1] || '').split(/,/)
40
+ result = {}
41
+ query_list.each{|q|
42
+ path_elems = q.split('/')
43
+ target_elem = extract_path(json_obj, path_elems, 0)
44
+ result[q] = target_elem unless target_elem.nil?
45
+ }
46
+ result
47
+ end
48
+
49
+
50
+ def extract_path(json_obj, path, depth)
51
+ return nil if json_obj.nil?
52
+ if depth >= path.length
53
+ json_obj
54
+ else
55
+ if json_obj.kind_of?(Array)
56
+ # Handle key, value pairs of GC information
57
+ value = json_obj.find{|e|
58
+ e.is_a?(Hash) && e['key'] == path[depth]
59
+ }
60
+ extract_path(value['value'], path, depth+1)
61
+ else
62
+ extract_path(json_obj[path[depth]], path, depth+1)
63
+ end
64
+ end
65
+ end
66
+
67
+ def query
68
+ Query.new(self)
69
+ end
70
+
71
+ def get_mbean(mbean)
72
+ JSON.parse(get_mbean_json(mbean))
73
+ end
74
+
75
+ def get(path, default='{}')
76
+ resp = HTTParty.get("#{@endpoint}#{path}")
77
+ if resp.code == 200
78
+ resp.body
79
+ else
80
+ default
81
+ end
82
+ end
83
+
84
+ def get_mbean_json(mbean)
85
+ get("#{@mbean_path}/#{mbean}")
86
+ end
87
+
88
+ def get_query_json(path='', default='[]')
89
+ get("#{@query_path}/#{path}",default)
90
+ end
91
+
92
+ def get_attributes(mbean)
93
+ json = get_mbean(mbean)
94
+ json['attributes'] || []
95
+ end
96
+
97
+ def get_attribute(mbean, attr_name)
98
+ get_attributes(mbean).find {|obj| obj['name'] == attr_name } || {}
99
+ end
100
+
101
+ def map_to_canonical_name(name_arr)
102
+ name_arr.map{|name| to_canonical_name(name) }
103
+ end
104
+
105
+ def to_canonical_name(name)
106
+ name.to_s.downcase.gsub(/_/, '')
107
+ end
108
+
109
+ def underscore(str)
110
+ str.gsub(/::/, '/').
111
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
112
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
113
+ tr('-', '_').
114
+ downcase
115
+ end
116
+
117
+ def get_metrics(mbean, target_attr=[])
118
+ kv = Hash.new
119
+ arr = target_attr.kind_of?(Array) ? target_attr : [target_attr]
120
+ c_target_attr = map_to_canonical_name(arr).to_set
121
+ get_attributes(mbean)
122
+ .reject {|attr| attr['name'].nil? || attr['value'].nil? }
123
+ .each {|attr|
124
+ c_name = to_canonical_name(attr['name'])
125
+ if c_target_attr.empty? || c_target_attr.include?(c_name)
126
+ key = @caml_case ? attr['name'] : underscore(attr['name'])
127
+ kv[key] = attr['value']
128
+ end
129
+ }
130
+ kv
131
+ end
132
+
133
+
134
+ def memory_usage_metrics(target_attr=[])
135
+ get_metrics('java.lang:type=Memory', target_attr)
136
+ end
137
+
138
+ def gc_cms_metrics(target_attr=[])
139
+ get_metrics('java.lang:type=GarbageCollector,name=ConcurrentMarkSweep', target_attr)
140
+ end
141
+
142
+ def gc_parnew_metrics(target_attr=[])
143
+ get_metrics('java.lang:type=GarbageCollector,name=ParNew', target_attr)
144
+ end
145
+
146
+ def os_metrics(target_attr=[])
147
+ get_metrics('java.lang:type=OperatingSystem', target_attr)
148
+ end
149
+
150
+ def query_manager_metrics(target_attr=[])
151
+ get_metrics('com.facebook.presto.execution:name=QueryManager', target_attr)
152
+ end
153
+
154
+ def query_execution_metrics(target_attr=[])
155
+ get_metrics('com.facebook.presto.execution:name=QueryExecution', target_attr)
156
+ end
157
+
158
+ def node_scheduler_metrics(target_attr=[])
159
+ get_metrics('com.facebook.presto.execution:name=NodeScheduler', target_attr)
160
+ end
161
+
162
+ def task_executor_metrics(target_attr=[])
163
+ get_metrics('com.facebook.presto.execution:name=TaskExecutor', target_attr)
164
+ end
165
+
166
+ def task_manager_metrics(target_attr=[])
167
+ get_metrics('com.facebook.presto.execution:name=TaskManager', target_attr)
168
+ end
169
+
170
+ private :map_to_canonical_name, :to_canonical_name, :underscore
171
+ end
172
+ end
173
+ end
174
+
@@ -0,0 +1,167 @@
1
+ require 'presto/metrics/client'
2
+ require 'presto-client'
3
+ # Use httpclient for faster json retrieval
4
+ Faraday.default_adapter = :httpclient
5
+ require 'presto/client/models'
6
+ require 'pp'
7
+ include Presto::Client::Models
8
+
9
+ module Presto
10
+ module Metrics
11
+
12
+ class Query
13
+ def initialize(client)
14
+ @client = client
15
+ end
16
+
17
+ def format_table(tbl, label:[], align:[], sep:' ')
18
+ # Compute col length
19
+ col = {}
20
+ label.each_with_index{|l, i| col[i] = l.length}
21
+ tbl.each{|row|
22
+ row.each_with_index {|cell, i|
23
+ l = cell.to_s.size if cell
24
+ l ||= 0
25
+ col[i] ||= l
26
+ col[i] = [[col[i], l].max, 150].min
27
+ }
28
+ }
29
+ # print label
30
+ line = []
31
+ label.each_with_index{|l, i|
32
+ line << l.to_s[0..col[i]].ljust(col[i])
33
+ }
34
+ puts line.join(sep)
35
+ tbl.each{|row|
36
+ line = []
37
+ row.each_with_index{|cell, i|
38
+ str = cell.to_s[0..col[i]]
39
+ a = align[i] || 'l'
40
+ case a
41
+ when 'r'
42
+ line << str.rjust(col[i])
43
+ when 'l'
44
+ line << str.ljust(col[i])
45
+ else
46
+ line << str.ljust(col[i])
47
+ end
48
+ }
49
+ puts line.join(sep)
50
+ }
51
+ 0
52
+ end
53
+
54
+ def list
55
+ ql = query_list
56
+ tbl = ql.map {|q|
57
+ s = q['session'] || {}
58
+ query = q['query'].gsub(/[\t\r\n]/, ' ').gsub(/ {1,}/, ' ').strip
59
+ [q['queryId'], q['elapsedTime'], q['state'], q['runningDrivers'], q['completedDrivers'], q['totalDrivers'], s['user'], s['catalog'], s['schema'], s['source'], query]
60
+ }.sort_by{|row| row[0]}.reverse
61
+
62
+ format_table(
63
+ tbl,
64
+ :label => %w|query time state r f t user catalog schema source sql|,
65
+ :align => %w|r r r r r r l l r l l |
66
+ )
67
+ end
68
+
69
+ def find(queryId)
70
+ JSON.parse(@client.get_query_json(queryId, "{}"))
71
+ end
72
+
73
+ def task_list(queryId)
74
+ qj = find(queryId) || {}
75
+ root_stage = qj['outputStage'] || []
76
+ tasks = root_stage['tasks'] || []
77
+ tasks << find_tasks(root_stage['subStages'])
78
+ tasks.flatten
79
+ end
80
+
81
+ def tasks(queryId)
82
+ tl = task_list(queryId)
83
+ stats = tl.map {|t|
84
+ s = t['stats']
85
+ host = (t['self'] || '').sub(/http:\/\/([a-z0-9\-.]+[\/:][0-9]+)\/.*/, '\1')
86
+ [t['taskId'], host, t['state'], s['rawInputPositions'], s['rawInputDataSize'], s['queuedDrivers'], s['runningDrivers'], s['completedDrivers']]
87
+ }
88
+ format_table(stats,
89
+ :label => %w|task_id host state processed_rows size|,
90
+ :align => %w|l l l r r|
91
+ )
92
+ end
93
+
94
+ def query_list(path="")
95
+ JSON.parse(@client.get_query_json(path))
96
+ end
97
+
98
+ def running_list
99
+ ql = query_list.select{|q| q['state'] == 'RUNNING'}.sort_by{|row| row[0]}.reverse
100
+ ql.each{|q|
101
+ tasks(q['queryId'])
102
+ }
103
+ ql.size
104
+ end
105
+
106
+ private :count_total_processed_rows
107
+
108
+ def count_total_processed_rows(stage)
109
+ rows = stage.tasks.map{|t| t.stats.processed_input_positions }.inject(0, :+)
110
+ rows + stage.sub_stages.map{|ss| count_total_processed_rows(ss) }.inject(0, :+)
111
+ end
112
+
113
+ def query_progress
114
+ running_queries = query_list.map{|q| QueryInfo.decode(q) }.select{|q| q.state == :running }
115
+ query_info = running_queries.map{|q|
116
+ queryInfo = find(q.query_id)
117
+ QueryInfo.decode(queryInfo)
118
+ }
119
+
120
+ result = {}
121
+ query_info.each{|q|
122
+ os = q.output_stage
123
+ result[q.query_id] = count_total_processed_rows(os)
124
+ }
125
+ result
126
+ end
127
+
128
+ def metrics
129
+ ql = query_list
130
+ ql.map{|qi|
131
+ h = {}
132
+ h['query_id'] = qi['queryId'] || ''
133
+ h['state'] = qi['state'] || ''
134
+ session = qi['session'] || {}
135
+ h['source'] = session['source'] || ''
136
+ h['user'] = session['user'] || h['source'].gsub(/[^a-zA-Z0-9]/,'')
137
+ h['running_drivers'] = qi['runningDrivers'] || 0
138
+ h['queued_drivers'] = qi['queuedDrivers'] || 0
139
+ h['completed_drivers'] = qi['completedDrivers'] || 0
140
+ h['total_drivers'] = qi['totalDrivers'] || 0
141
+ h['elapsed_time'] = qi['elapsedTime'] || '0.0m'
142
+ h['create_time'] = qi['createTime']
143
+ h['running_time'] = qi['endTime'] || Time.now.utc.iso8601(3)
144
+ #if(h['state'] == "FAILED")
145
+ # h['errorCode'] = find(h['query_id'])['errorCode'] || {}
146
+ #end
147
+ h
148
+ }
149
+ end
150
+
151
+
152
+
153
+
154
+ def find_tasks(sub_stages)
155
+ task_list = []
156
+ return task_list unless sub_stages
157
+ sub_stages.each{|ss|
158
+ tl = ss['tasks']
159
+ task_list << tl if tl
160
+ task_list << find_tasks(ss['subStages'])
161
+ }
162
+ task_list.flatten()
163
+ end
164
+
165
+ end
166
+ end
167
+ end
@@ -1,5 +1,5 @@
1
1
  module Presto
2
2
  module Metrics
3
- VERSION = "0.2.6"
3
+ VERSION = '0.3.0'
4
4
  end
5
5
  end
@@ -1,222 +1,3 @@
1
- require "presto/metrics/version"
2
- require 'httparty'
3
- require 'json'
4
- require 'set'
5
- require 'time'
6
-
7
- module Presto
8
- module Metrics
9
-
10
- class Query
11
- def initialize(client)
12
- @client = client
13
- end
14
-
15
- def list
16
- query_list().each {|q|
17
- s = q['session'] || {}
18
- query = q['query'].gsub(/[\r\n]/, " ")[0..50]
19
- c = [q['queryId'], s['user'], s['catalog'], s['schema'], s['source'], query]
20
- puts c.join("\t")
21
- }
22
- 0
23
- end
24
-
25
- def find(id)
26
- JSON.parse(@client.get_query_json(id))
27
- end
28
-
29
- def query_list(path="")
30
- JSON.parse(@client.get_query_json(path))
31
- end
32
-
33
- def metrics
34
- ql = query_list
35
- ql.map{|qi|
36
- h = {}
37
- h['query_id'] = qi['queryId'] || ""
38
- h['state'] = qi['state'] || ""
39
- session = qi['session'] || {}
40
- h['source'] = session['source'] || ""
41
- h['user'] = session['user'] || h['source'].gsub(/[^a-zA-Z0-9]/,'')
42
- h['running_drivers'] = qi['runningDrivers'] || 0
43
- h['queued_drivers'] = qi['queuedDrivers'] || 0
44
- h['completed_drivers'] = qi['completedDrivers'] || 0
45
- h['total_drivers'] = qi['totalDrivers'] || 0
46
- h['elapsed_time'] = qi['elapsedTime'] || "0.0m"
47
- h['create_time'] = qi['createTime']
48
- h['running_time'] = qi['endTime'] || Time.now.utc.iso8601(3)
49
- #if(h['state'] == "FAILED")
50
- # h['errorCode'] = find(h['query_id'])['errorCode'] || {}
51
- #end
52
- h
53
- }
54
- end
55
-
56
- end
57
-
58
- class Client
59
- def initialize(opts={})
60
- @host = opts[:host] || "localhost"
61
- @port = opts[:port] || "8080"
62
- @endpoint = opts[:endpoint] || "http://#{@host}:#{@port}"
63
- @mbean_path = opts[:mbean_path] || "/v1/jmx/mbean"
64
- @query_path = opts[:query_path] || "/v1/query"
65
- @caml_case = opts[:caml_case] || false
66
- end
67
-
68
- @@MBEAN_ALIAS = {
69
- "memory" => "java.lang:type=Memory",
70
- "gc_cms" => "java.lang:type=GarbageCollector,name=ConcurrentMarkSweep",
71
- "gc_parnew" => "java.lang:type=GarbageCollector,name=ParNew",
72
- "os" => "java.lang:type=OperatingSystem",
73
- "query_manager" => "com.facebook.presto.execution:name=QueryManager",
74
- "query_execution" => "com.facebook.presto.execution:name=QueryExecution",
75
- "node_scheduler" => "com.facebook.presto.execution:name=NodeScheduler",
76
- "task_executor" => "com.facebook.presto.execution:name=TaskExecutor",
77
- "task_manager" => "com.facebook.presto.execution:name=TaskManager"
78
- }
79
-
80
-
81
- def path(path)
82
- c = path.split(/:/)
83
- target = c[0]
84
- mbean = @@MBEAN_ALIAS[target] || target
85
- json_obj = get_metrics(mbean)
86
- return json_obj if c.size <= 1
87
- query_list = (c[1] || "").split(/,/)
88
- result = {}
89
- query_list.each{|q|
90
- path_elems = q.split("/")
91
- target_elem = extract_path(json_obj, path_elems, 0)
92
- result[q] = target_elem unless target_elem.nil?
93
- }
94
- result
95
- end
96
-
97
-
98
- def extract_path(json_obj, path, depth)
99
- return nil if json_obj.nil?
100
- if depth >= path.length
101
- json_obj
102
- else
103
- if json_obj.kind_of?(Array)
104
- # Handle key, value pairs of GC information
105
- value = json_obj.find{|e|
106
- e.is_a?(Hash) && e['key'] == path[depth]
107
- }
108
- extract_path(value['value'], path, depth+1)
109
- else
110
- extract_path(json_obj[path[depth]], path, depth+1)
111
- end
112
- end
113
- end
114
-
115
- def query
116
- Query.new(self)
117
- end
118
-
119
- def get_mbean(mbean)
120
- JSON.parse(get_mbean_json(mbean))
121
- end
122
-
123
- def get(path, default="{}")
124
- resp = HTTParty.get("#{@endpoint}#{path}")
125
- if resp.code == 200
126
- resp.body
127
- else
128
- default
129
- end
130
- end
131
-
132
- def get_mbean_json(mbean)
133
- get("#{@mbean_path}/#{mbean}")
134
- end
135
-
136
- def get_query_json(path="")
137
- get("#{@query_path}/#{path}","[]")
138
- end
139
-
140
- def get_attributes(mbean)
141
- json = get_mbean(mbean)
142
- json['attributes'] || []
143
- end
144
-
145
- def get_attribute(mbean, attr_name)
146
- get_attributes(mbean).find {|obj| obj['name'] == attr_name } || {}
147
- end
148
-
149
- def map_to_canonical_name(name_arr)
150
- name_arr.map{|name| to_canonical_name(name) }
151
- end
152
-
153
- def to_canonical_name(name)
154
- name.to_s.downcase.gsub(/_/, "")
155
- end
156
-
157
- def underscore(str)
158
- str.gsub(/::/, '/').
159
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
160
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
161
- tr("-", "_").
162
- downcase
163
- end
164
-
165
- def get_metrics(mbean, target_attr=[])
166
- kv = Hash.new
167
- arr = target_attr.kind_of?(Array) ? target_attr : [target_attr]
168
- c_target_attr = map_to_canonical_name(arr).to_set
169
- get_attributes(mbean)
170
- .reject {|attr| attr['name'].nil? || attr['value'].nil? }
171
- .each {|attr|
172
- c_name = to_canonical_name(attr['name'])
173
- if c_target_attr.empty? || c_target_attr.include?(c_name)
174
- key = @caml_case ? attr['name'] : underscore(attr['name'])
175
- kv[key] = attr['value']
176
- end
177
- }
178
- kv
179
- end
180
-
181
-
182
- def memory_usage_metrics(target_attr=[])
183
- get_metrics("java.lang:type=Memory", target_attr)
184
- end
185
-
186
- def gc_cms_metrics(target_attr=[])
187
- get_metrics("java.lang:type=GarbageCollector,name=ConcurrentMarkSweep", target_attr)
188
- end
189
-
190
- def gc_parnew_metrics(target_attr=[])
191
- get_metrics("java.lang:type=GarbageCollector,name=ParNew", target_attr)
192
- end
193
-
194
- def os_metrics(target_attr=[])
195
- get_metrics("java.lang:type=OperatingSystem", target_attr)
196
- end
197
-
198
- def query_manager_metrics(target_attr=[])
199
- get_metrics("com.facebook.presto.execution:name=QueryManager", target_attr)
200
- end
201
-
202
- def query_execution_metrics(target_attr=[])
203
- get_metrics("com.facebook.presto.execution:name=QueryExecution", target_attr)
204
- end
205
-
206
- def node_scheduler_metrics(target_attr=[])
207
- get_metrics("com.facebook.presto.execution:name=NodeScheduler", target_attr)
208
- end
209
-
210
- def task_executor_metrics(target_attr=[])
211
- get_metrics("com.facebook.presto.execution:name=TaskExecutor", target_attr)
212
- end
213
-
214
- def task_manager_metrics(target_attr=[])
215
- get_metrics("com.facebook.presto.execution:name=TaskManager", target_attr)
216
- end
217
-
218
- private :map_to_canonical_name, :to_canonical_name, :underscore
219
- end
220
- end
221
- end
222
-
1
+ require 'presto/metrics/version'
2
+ require 'presto/metrics/client'
3
+ require 'presto/metrics/query'
@@ -21,6 +21,8 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.7"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "presto-client", '~> 0.4.4'
25
+ spec.add_development_dependency "httpclient"
24
26
 
25
27
  spec.add_runtime_dependency "httparty"
26
28
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: presto-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taro L. Saito
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-05 00:00:00.000000000 Z
11
+ date: 2015-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: presto-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.4.4
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.4.4
69
+ - !ruby/object:Gem::Dependency
70
+ name: httpclient
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: httparty
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -82,6 +110,8 @@ files:
82
110
  - README.md
83
111
  - Rakefile
84
112
  - lib/presto/metrics.rb
113
+ - lib/presto/metrics/client.rb
114
+ - lib/presto/metrics/query.rb
85
115
  - lib/presto/metrics/version.rb
86
116
  - presto-metrics.gemspec
87
117
  - spec/presto/metrics_spec.rb