presto-metrics 0.2.6 → 0.3.0

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 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