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 +4 -4
- data/.gitignore +3 -0
- data/Rakefile +4 -0
- data/lib/presto/metrics/client.rb +174 -0
- data/lib/presto/metrics/query.rb +167 -0
- data/lib/presto/metrics/version.rb +1 -1
- data/lib/presto/metrics.rb +3 -222
- data/presto-metrics.gemspec +2 -0
- metadata +32 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f68643372b784275eac1dd75ec8c9e4bd899f177
|
4
|
+
data.tar.gz: 6e5aca1a188c6a526175c8e6b2a4af254b46132a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6dbdd29162bb6f26f4cfaa83210d95c4270c2534efc1175a21f825c8349b5dd3eedd04c481ebc88d011f6142c18a42e6f490ae75249cddc790b334bfc3891c5b
|
7
|
+
data.tar.gz: b4cc203242ac159e0e7bd1a95693197bf38e3cc57007bcb024ee3efb97a5e72f2944adf37765f8e15ad60c7a9cf8bcdf5d14a2cd2f23acc03eeb16203e69f472
|
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -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
|
data/lib/presto/metrics.rb
CHANGED
@@ -1,222 +1,3 @@
|
|
1
|
-
require
|
2
|
-
require '
|
3
|
-
require '
|
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'
|
data/presto-metrics.gemspec
CHANGED
@@ -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.
|
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:
|
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
|