gri 10.0.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 +7 -0
- data/.gitignore +7 -0
- data/MIT-LICENSE.txt +20 -0
- data/README.md +132 -0
- data/Rakefile +5 -0
- data/bin/grapher +17 -0
- data/bin/gri +5 -0
- data/bin/gricast +17 -0
- data/bin/grispark +5 -0
- data/bin/griwalk +9 -0
- data/bin/trad +19 -0
- data/bin/trad-http +17 -0
- data/gri.gemspec +21 -0
- data/lib/fluent/plugin/out_gri.rb +56 -0
- data/lib/gri/api.rb +28 -0
- data/lib/gri/app_collector.rb +154 -0
- data/lib/gri/app_walker.rb +23 -0
- data/lib/gri/blank.rb +49 -0
- data/lib/gri/builtindefs.rb +211 -0
- data/lib/gri/cast.rb +84 -0
- data/lib/gri/cgraph.rb +37 -0
- data/lib/gri/clist.rb +163 -0
- data/lib/gri/collector.rb +284 -0
- data/lib/gri/config.rb +134 -0
- data/lib/gri/ds_list.rb +166 -0
- data/lib/gri/format_helper.rb +112 -0
- data/lib/gri/gparams.rb +43 -0
- data/lib/gri/graph.rb +239 -0
- data/lib/gri/grapher.rb +70 -0
- data/lib/gri/ldb.rb +160 -0
- data/lib/gri/list.rb +242 -0
- data/lib/gri/log.rb +140 -0
- data/lib/gri/loop.rb +109 -0
- data/lib/gri/ltsv.rb +58 -0
- data/lib/gri/main.rb +107 -0
- data/lib/gri/mlog.rb +22 -0
- data/lib/gri/mmsgpack.rb +57 -0
- data/lib/gri/msnmp.rb +601 -0
- data/lib/gri/page.rb +235 -0
- data/lib/gri/pcollector.rb +209 -0
- data/lib/gri/plugin.rb +75 -0
- data/lib/gri/plugin/bootstrap.rb +65 -0
- data/lib/gri/plugin/cisco.rb +98 -0
- data/lib/gri/plugin/exec_collector.rb +89 -0
- data/lib/gri/plugin/juniper.rb +5 -0
- data/lib/gri/plugin/netsnmp.rb +8 -0
- data/lib/gri/plugin/ucdavis.rb +176 -0
- data/lib/gri/plugin/writer_fluentd.rb +26 -0
- data/lib/gri/polling_unit.rb +88 -0
- data/lib/gri/q.rb +5 -0
- data/lib/gri/request.rb +29 -0
- data/lib/gri/rrd.rb +438 -0
- data/lib/gri/scheduler.rb +68 -0
- data/lib/gri/sgraph.rb +147 -0
- data/lib/gri/spark.rb +94 -0
- data/lib/gri/tra_collector.rb +80 -0
- data/lib/gri/trad.rb +170 -0
- data/lib/gri/updater.rb +201 -0
- data/lib/gri/util_daemon.rb +19 -0
- data/lib/gri/util_marshal.rb +13 -0
- data/lib/gri/utils.rb +63 -0
- data/lib/gri/vendor.rb +76 -0
- data/lib/gri/version.rb +3 -0
- data/lib/gri/wmain.rb +67 -0
- data/lib/gri/writer.rb +184 -0
- data/mcollector +47 -0
- data/test/mock.rb +60 -0
- data/test/root/gra/.sysdb/sysdb.txt +3 -0
- data/test/root/gra/testhost/.records.txt +2 -0
- data/test/root/if.def +2 -0
- data/test/root/test.conf +4 -0
- data/test/root/testtab +9 -0
- data/test/root/testtab2 +2 -0
- data/test/root/tra/testhost/_/20130614 +20 -0
- data/test/test_app.rb +58 -0
- data/test/test_builtindefs.rb +24 -0
- data/test/test_collector.rb +58 -0
- data/test/test_config.rb +62 -0
- data/test/test_ds_list.rb +48 -0
- data/test/test_exec_collector.rb +33 -0
- data/test/test_format_helper.rb +68 -0
- data/test/test_graph.rb +69 -0
- data/test/test_ldb.rb +29 -0
- data/test/test_list.rb +65 -0
- data/test/test_log.rb +16 -0
- data/test/test_loop.rb +35 -0
- data/test/test_ltsv.rb +38 -0
- data/test/test_main.rb +19 -0
- data/test/test_mmsgpack.rb +27 -0
- data/test/test_msnmp.rb +147 -0
- data/test/test_page.rb +51 -0
- data/test/test_pcollector.rb +71 -0
- data/test/test_plugin.rb +62 -0
- data/test/test_plugin_cisco.rb +23 -0
- data/test/test_polling_unit.rb +58 -0
- data/test/test_request.rb +26 -0
- data/test/test_rrd.rb +53 -0
- data/test/test_rrd_updater.rb +139 -0
- data/test/test_scheduler.rb +31 -0
- data/test/test_tra_collector.rb +40 -0
- data/test/test_trad.rb +33 -0
- data/test/test_util_marshal.rb +17 -0
- data/test/test_utils.rb +15 -0
- data/test/test_vendor.rb +40 -0
- data/test/test_writer.rb +33 -0
- data/test/unittest_helper.rb +27 -0
- metadata +208 -0
data/lib/gri/page.rb
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'time'
|
2
|
+
require 'gri/builtindefs'
|
3
|
+
require 'gri/utils'
|
4
|
+
require 'gri/request'
|
5
|
+
require 'gri/format_helper'
|
6
|
+
|
7
|
+
module GRI
|
8
|
+
class Page
|
9
|
+
include Utils
|
10
|
+
include FormatHelper
|
11
|
+
|
12
|
+
def initialize options={}
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def mk_page_title dirs, rs, params
|
17
|
+
jstr = (params['p'] == 't' or params['p'] == 'v') ? ', ' : ' + '
|
18
|
+
hosthash = {}
|
19
|
+
descrs = []
|
20
|
+
headlegend = nil
|
21
|
+
|
22
|
+
for rname in rs
|
23
|
+
host, key = rname.split('_', 2)
|
24
|
+
hosthash[host] = true
|
25
|
+
dir, records = search_records dirs, host
|
26
|
+
if records and (prop = get_prop records[key])
|
27
|
+
xhost = prop[:description] ? nil : host
|
28
|
+
descr = (prop[:description] || prop[:name] || '?').to_s
|
29
|
+
url = if params['grp'].blank?
|
30
|
+
url_to("?r=#{rname}")
|
31
|
+
else
|
32
|
+
url_to("?grp=#{params['grp']}&r=#{rname}")
|
33
|
+
end
|
34
|
+
descrs.push [url, xhost, descr]
|
35
|
+
unless headlegend or params['grp']
|
36
|
+
ub = prop[:ub]
|
37
|
+
if descr or ub
|
38
|
+
name = prop[:name].to_s
|
39
|
+
url = url_to("#{host}")
|
40
|
+
headlegend = "<a href=\"#{h url}\">#{h host}</a>"
|
41
|
+
headlegend << ' ' + name if descr
|
42
|
+
#headlegend << ", MAX: #{to_scalestr ub, 1000}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
html_title = descrs.map {|url, xhost, descr|
|
49
|
+
if xhost and hosthash.size > 1
|
50
|
+
xhost + ':' + descr
|
51
|
+
else
|
52
|
+
descr
|
53
|
+
end
|
54
|
+
}.join(jstr)
|
55
|
+
body_title = descrs.collect {|url, xhost, descr|
|
56
|
+
if xhost and hosthash.size > 1
|
57
|
+
"<a href=\"#{h url}\">#{h xhost}:#{h descr}</a>"
|
58
|
+
else
|
59
|
+
"<a href=\"#{h url}\">#{h descr}</a>"
|
60
|
+
end
|
61
|
+
}.join(jstr)
|
62
|
+
|
63
|
+
return html_title, body_title, headlegend
|
64
|
+
end
|
65
|
+
|
66
|
+
def mk_param_str stime, etime, rs, ds, params
|
67
|
+
res = rs.map {|r| "r=#{u r}"}
|
68
|
+
res << "grp=#{u params['grp']}" if params['grp']
|
69
|
+
res << "stime=#{stime.to_i}"
|
70
|
+
res << "etime=#{etime.to_i}" if etime.to_i.nonzero?
|
71
|
+
res << "z=#{u params['z']}"
|
72
|
+
res << "tz=#{u params['tz']}"
|
73
|
+
res << "y=#{u params['y']}"
|
74
|
+
res << "p=#{u params['p']}" if params['p']
|
75
|
+
res << "ds=#{ds}" if ds
|
76
|
+
res.join('&')
|
77
|
+
end
|
78
|
+
|
79
|
+
def mk_graph_tag stime, etime, rs, params
|
80
|
+
if params['p'] == 't'
|
81
|
+
rs.map {|rname|
|
82
|
+
mk_graph_tag_r stime, etime, [rname], params
|
83
|
+
}.join("\n")
|
84
|
+
else
|
85
|
+
mk_graph_tag_r stime, etime, rs, params
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def mk_graph_tag_r stime, etime, rs, params
|
90
|
+
specs = DEFS.get_specs @data_name
|
91
|
+
if (gr_specs = specs[:graph]) and gr_specs.size >= 1
|
92
|
+
if params['p'] == 's' or params['p'] == 'v'
|
93
|
+
(0..gr_specs.size-1).map {|gidx|
|
94
|
+
gr_spec = gr_specs[gidx]
|
95
|
+
pickup_re = gr_spec[3]
|
96
|
+
dss = specs[:ds] || []
|
97
|
+
dss = dss.grep pickup_re if pickup_re
|
98
|
+
dss = dss.map {|ds| ds.split(',', 3)[1]}
|
99
|
+
dss.map {|ds|
|
100
|
+
param_str = mk_param_str stime, etime, rs, ds, params
|
101
|
+
mk_graph_tag_s param_str, gidx
|
102
|
+
}.join ''
|
103
|
+
}.join ''
|
104
|
+
else
|
105
|
+
param_str = mk_param_str stime, etime, rs, nil, params
|
106
|
+
(0..gr_specs.size-1).map {|gidx|
|
107
|
+
mk_graph_tag_s param_str, gidx}.join ''
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def mk_graph_tag_s param_str, gidx=nil
|
113
|
+
param_str += "&g=#{gidx}" if gidx
|
114
|
+
name = ENV['SCRIPT_NAME'] || ''
|
115
|
+
"<a href=\"#{name}/#{h param_str}\">" +
|
116
|
+
"<img ismap src=\"#{name}?#{h param_str}\"></a><br/>"
|
117
|
+
end
|
118
|
+
|
119
|
+
def parse_tstr tstr
|
120
|
+
(tstr and !tstr.empty?) ? Time.parse(tstr) : nil
|
121
|
+
end
|
122
|
+
|
123
|
+
def parse_request req
|
124
|
+
now = Time.now
|
125
|
+
if @options[:clicked]
|
126
|
+
s = req.path_info[1..-1]
|
127
|
+
req.query_string = s
|
128
|
+
params = req.gparams
|
129
|
+
z = params['z']
|
130
|
+
width, = GRI::Graph::SIZE[z]
|
131
|
+
|
132
|
+
canvas_x_offset = (Config['canvas-x-offset'] || 75).to_i
|
133
|
+
imgx = @options[:imgx].to_i - canvas_x_offset
|
134
|
+
imgy = @options[:imgy].to_i
|
135
|
+
|
136
|
+
stime = params['stime'].to_i
|
137
|
+
etime = params['etime'].to_i
|
138
|
+
etime = (now + etime).to_i if etime <= 0
|
139
|
+
stime = (etime + stime).to_i if stime <= 0
|
140
|
+
stime = Time.at stime
|
141
|
+
time = stime + ((Time.at(etime) - stime) / width) * imgx
|
142
|
+
stime = Time.local(time.year, time.mon, time.day)
|
143
|
+
etime = stime + 24*3600
|
144
|
+
params['pt'] = 's'
|
145
|
+
else
|
146
|
+
params = req.gparams
|
147
|
+
deftime = now - now.to_i % 60
|
148
|
+
stime = parse_tstr(params['cs']) || deftime - 7*24*3600
|
149
|
+
etime = parse_tstr(params['ce']) || deftime
|
150
|
+
end
|
151
|
+
return stime, etime, params
|
152
|
+
end
|
153
|
+
|
154
|
+
def call env
|
155
|
+
req = GRI::Request.new env
|
156
|
+
ENV['TZ'] = req.params['tz'].to_s unless req.params['tz'].blank?
|
157
|
+
stime, etime, params = parse_request req
|
158
|
+
|
159
|
+
cs = stime.strftime '%Y-%m-%d %H:%M:%S'
|
160
|
+
ce = etime.strftime '%Y-%m-%d %H:%M:%S'
|
161
|
+
|
162
|
+
r = params['r'] || ''
|
163
|
+
host, @data_name, index = parse_host_key r
|
164
|
+
rs = params.getvar 'r'
|
165
|
+
|
166
|
+
@title, body_title, headlegend =
|
167
|
+
mk_page_title @options[:dirs], rs, params
|
168
|
+
|
169
|
+
defs_term = DEFS[:term]
|
170
|
+
sym = params['tm'].blank? ? '' : params['tm'].intern
|
171
|
+
terms = defs_term[sym] || defs_term[:default]
|
172
|
+
body = render(Grapher.layout) {render template, binding}
|
173
|
+
[200, {'Content-type' => 'text/html'}, [body]]
|
174
|
+
end
|
175
|
+
|
176
|
+
TZS = [['', 'localtime'], ['JST-9', 'JST-9'],
|
177
|
+
['EST5EDT', 'EST5EDT'], ['PST8PDT', 'PST8PDT'],
|
178
|
+
['Europe/London', 'Europe/London'],
|
179
|
+
['Europe/Amsterdam', 'Europe/Amsterdam'],
|
180
|
+
['Singapore', 'Singapore']]
|
181
|
+
def template
|
182
|
+
<<'EOS'
|
183
|
+
<span class="large"><%= body_title %></span><br/>
|
184
|
+
<% if params['z'] != 'll' and rs.size == 1 and headlegend and headlegend.size > 0 -%>
|
185
|
+
<span class="small"><%= headlegend %></span><br/>
|
186
|
+
<% end -%>
|
187
|
+
<br/>
|
188
|
+
|
189
|
+
<form enctype="application/x-www-form-urlencoded" method="get"
|
190
|
+
action="<%= url_to '?' %>">
|
191
|
+
<% rs.each {|r| -%><%= hidden 'r', r %><% } -%>
|
192
|
+
<% if params['grp'] then %><%= hidden 'grp', params['grp'] %><% end %>
|
193
|
+
<% tzs = TZS -%>
|
194
|
+
<% (tzs.assoc(params['tz']) || tzs[0])[2] = true -%>
|
195
|
+
TIMEZONE: <%= popup_menu('tz', nil, *tzs) %>
|
196
|
+
<% nflag, uflag = (params['y'] == 'u') ? [false, true] : [true, false] -%>
|
197
|
+
Y-axis scale:
|
198
|
+
<%= radio_button 'y', 'a', nflag %>auto
|
199
|
+
<%= radio_button 'y', 'u', uflag %>upper limit<br/>
|
200
|
+
<%= check_box 'pt', 's', (params['pt'] == 's') %>
|
201
|
+
<nobr>
|
202
|
+
from <%= text_field 'cs', cs, 20, 19, nil %>
|
203
|
+
to <%= text_field 'ce', ce, 20, 19, nil %>
|
204
|
+
</nobr>
|
205
|
+
<% zs = [['ss', 'SS'], ['s', 'S'], ['m', 'M'], ['l', 'L'], ['ll', 'LL']] -%>
|
206
|
+
<% (zs.assoc(params['z']) || zs[2])[2] = true -%>
|
207
|
+
Graph size: <%= popup_menu('z', nil, *zs) %>
|
208
|
+
<% tms = defs_term.sort_by {|k, v| v[0][1]}.map {|k,| [k.to_s, k.to_s]} -%>
|
209
|
+
<% (tms.assoc(params['tm']) || tms[1])[2] = true -%>
|
210
|
+
term: <%= popup_menu('tm', nil, *tms) %>
|
211
|
+
<br/>
|
212
|
+
<% if rs.size > 1 -%>
|
213
|
+
<% c_ary = [['', 'sum'], ['s', 'stack'], ['v', 'overlay'], ['t', 'tile']] -%>
|
214
|
+
<% (c_ary.assoc(params['p']) || c_ary[0])[2] = true -%>
|
215
|
+
Composite type: <%= popup_menu('p', nil, *c_ary) %><br/>
|
216
|
+
<% end -%>
|
217
|
+
<input class="btn btn-primary btn-sm" type="submit" value="submit">
|
218
|
+
</form>
|
219
|
+
|
220
|
+
<% if params['pt'] == 's' -%>
|
221
|
+
<%= mk_graph_tag stime.to_i, etime.to_i, rs, params %>
|
222
|
+
<% else -%>
|
223
|
+
<% for label, int in terms -%>
|
224
|
+
<hr/><p>
|
225
|
+
<strong><%=h label %> Graph</strong><br/>
|
226
|
+
<%= mk_graph_tag -int, 0, rs, params %>
|
227
|
+
</p>
|
228
|
+
<% end -%>
|
229
|
+
<% end -%>
|
230
|
+
|
231
|
+
<hr/><!--%= RUBY_VERSION %-->
|
232
|
+
EOS
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'gri/util_marshal'
|
3
|
+
require 'gri/app_collector'
|
4
|
+
|
5
|
+
module GRI
|
6
|
+
class AppCollector
|
7
|
+
def run_para targets, scheduler_class, start_time, fdh
|
8
|
+
sock_path = config['sock-path'] || '/tmp/.gcollectsock'
|
9
|
+
begin
|
10
|
+
server_sock = UNIXServer.new sock_path
|
11
|
+
rescue SystemCallError
|
12
|
+
puts "#{$!}: server_sock error" if $debug
|
13
|
+
Log.fatal "#{$!}: server_sock error"
|
14
|
+
return
|
15
|
+
end
|
16
|
+
|
17
|
+
duration = (config['duration'] || 0).to_i
|
18
|
+
if duration.zero?
|
19
|
+
basetime = start_time
|
20
|
+
offset = 0
|
21
|
+
else
|
22
|
+
basetime = start_time - start_time % duration
|
23
|
+
offset = start_time - basetime
|
24
|
+
end
|
25
|
+
interval = (config['interval'] || 300).to_i
|
26
|
+
ptargets = get_ptargets targets, basetime, duration, offset, interval
|
27
|
+
log_dir = config['log-dir'] || (config['root-dir'] + '/log')
|
28
|
+
Dir.glob("#{log_dir}/res.*.dump") {|path| File.unlink path} rescue nil
|
29
|
+
max_processes = (config['max-processes'] ||
|
30
|
+
config['max-fork-process']).to_i
|
31
|
+
max_processes = 30 if max_processes < 1
|
32
|
+
nproc = [targets.size * 2 / 3 + 1, max_processes].min
|
33
|
+
waittime = [20, duration].min
|
34
|
+
begin
|
35
|
+
pids = fork_child server_sock, sock_path, nproc, targets, log_dir,
|
36
|
+
scheduler_class, fdh
|
37
|
+
server_loop targets, ptargets, server_sock, waittime
|
38
|
+
rescue TimeoutError, SystemCallError
|
39
|
+
Log.error $!.inspect
|
40
|
+
ensure
|
41
|
+
server_sock.close
|
42
|
+
Log.info "server_sock.close"
|
43
|
+
File.unlink sock_path
|
44
|
+
end
|
45
|
+
pids.each {|pid| Process.waitpid pid}
|
46
|
+
Dir.glob("#{log_dir}/res.#{$$}.*.dump") {|path|
|
47
|
+
begin
|
48
|
+
res = Marshal.load_from_file path
|
49
|
+
res.each {|k, v| @metrics[k] += v}
|
50
|
+
File.unlink path
|
51
|
+
rescue SystemCallError
|
52
|
+
Log.error "{$!}"
|
53
|
+
end
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def server_loop targets, ptargets, server_sock, waittime
|
58
|
+
sock = nil
|
59
|
+
pkeys = ptargets.keys.sort
|
60
|
+
pts = []
|
61
|
+
while true
|
62
|
+
break if pkeys.empty?
|
63
|
+
now = Time.now.to_f
|
64
|
+
t = pkeys.first
|
65
|
+
if t <= now
|
66
|
+
pkeys.shift
|
67
|
+
pts += ptargets[t]
|
68
|
+
while (n = pts.shift)
|
69
|
+
timeout(waittime) {sock = server_sock.accept}
|
70
|
+
if (res = IO.select(nil, [sock], nil, 20))
|
71
|
+
thost = targets[n].first
|
72
|
+
sock.puts "#{n} #{thost}"
|
73
|
+
sock.close
|
74
|
+
else
|
75
|
+
sock.close
|
76
|
+
raise TimeoutError, 'select timeout'
|
77
|
+
end
|
78
|
+
if pts.empty? and (t = pkeys.first)
|
79
|
+
now = Time.now.to_f
|
80
|
+
if t <= now
|
81
|
+
pkeys.shift
|
82
|
+
small, big = [pts, ptargets[t]].sort_by {|e| e.size}
|
83
|
+
pts.replace big.zip(small)
|
84
|
+
pts.flatten!
|
85
|
+
pts.compact!
|
86
|
+
#pts += ptargets[t]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
else
|
91
|
+
sleep(t - now)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def get_ptargets targets, basetime, duration, offset=0, default_interval=300
|
97
|
+
if duration.zero?
|
98
|
+
ptargets = {basetime=>(0..targets.size-1).to_a}
|
99
|
+
else
|
100
|
+
intervals = {}
|
101
|
+
n = 0
|
102
|
+
for host, options in targets
|
103
|
+
interval = (options['interval'] || default_interval).to_i
|
104
|
+
next if interval.zero?
|
105
|
+
(intervals[interval] ||= []).push n
|
106
|
+
n += 1
|
107
|
+
end
|
108
|
+
ptargets = {}
|
109
|
+
et = basetime + duration
|
110
|
+
for interval in intervals.keys
|
111
|
+
st = basetime - basetime % interval
|
112
|
+
(0..duration/interval).each {|n|
|
113
|
+
s = n * interval
|
114
|
+
if (t = st + s) >= basetime and t < et
|
115
|
+
ptargets[t+offset] ||= []
|
116
|
+
ptargets[t+offset] += intervals[interval]
|
117
|
+
end
|
118
|
+
}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
ptargets
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_max_queue_size
|
125
|
+
4
|
126
|
+
end
|
127
|
+
|
128
|
+
def fillup_queue n, sock_path, targets, scheduler
|
129
|
+
e = false
|
130
|
+
mqs = get_max_queue_size
|
131
|
+
while scheduler.queue.size < mqs
|
132
|
+
begin
|
133
|
+
unless File.socket? sock_path
|
134
|
+
e = true
|
135
|
+
break
|
136
|
+
end
|
137
|
+
sock = UNIXSocket.new sock_path
|
138
|
+
rescue Errno::ECONNREFUSED
|
139
|
+
sock.close rescue nil
|
140
|
+
sleep(0.1 + rand)
|
141
|
+
retry
|
142
|
+
rescue SystemCallError
|
143
|
+
sock.close rescue nil
|
144
|
+
e = true
|
145
|
+
break
|
146
|
+
end
|
147
|
+
begin
|
148
|
+
unless (line = sock.gets)
|
149
|
+
e = true
|
150
|
+
break
|
151
|
+
end
|
152
|
+
rescue
|
153
|
+
e = true
|
154
|
+
break
|
155
|
+
ensure
|
156
|
+
sock.close
|
157
|
+
end
|
158
|
+
num, host = line.split
|
159
|
+
scheduler.queue.push targets[num.to_i]
|
160
|
+
scheduler.process_queue
|
161
|
+
end
|
162
|
+
e
|
163
|
+
end
|
164
|
+
|
165
|
+
def fork_child server_sock, sock_path, nproc, targets, log_dir,
|
166
|
+
scheduler_class, fdh
|
167
|
+
pids = []
|
168
|
+
ppid = $$
|
169
|
+
for n in 1..nproc
|
170
|
+
pid = fork {
|
171
|
+
server_sock.close
|
172
|
+
start_time = Time.now
|
173
|
+
sleep 0.05 * n
|
174
|
+
Log.debug "child ##{n}"
|
175
|
+
loop = Loop.new
|
176
|
+
@writers.each {|writer| writer.loop = loop}
|
177
|
+
scheduler = scheduler_class.new loop, @metrics
|
178
|
+
scheduler.queue = []
|
179
|
+
scheduler.writers = @writers
|
180
|
+
scheduler.fake_descr_hash = fdh
|
181
|
+
|
182
|
+
e = fillup_queue n, sock_path, targets, scheduler
|
183
|
+
scheduler.process_queue
|
184
|
+
if !e or loop.has_active_watchers?
|
185
|
+
while true
|
186
|
+
loop.run_once
|
187
|
+
break if e and !loop.has_active_watchers?
|
188
|
+
e = fillup_queue n, sock_path, targets, scheduler
|
189
|
+
scheduler.process_queue
|
190
|
+
end
|
191
|
+
end
|
192
|
+
scheduler.finalize
|
193
|
+
rc = @metrics[:run_count]
|
194
|
+
elapsed = Time.now - start_time
|
195
|
+
Log.debug "end ##{n} #{rc} #{rc/elapsed}"
|
196
|
+
#@metrics["run_count#{n}".intern] = rc
|
197
|
+
begin
|
198
|
+
path = "#{log_dir}/res.#{ppid}.#{$$}.dump"
|
199
|
+
Marshal.dump_to_file @metrics, path
|
200
|
+
rescue SystemCallError
|
201
|
+
Log.error "#{$!}"
|
202
|
+
end
|
203
|
+
}
|
204
|
+
pids.push pid
|
205
|
+
end
|
206
|
+
pids
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
data/lib/gri/plugin.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
module GRI
|
2
|
+
module Plugin
|
3
|
+
extend Plugin
|
4
|
+
|
5
|
+
def load_plugins dirs=[], config=nil
|
6
|
+
@loaded = {}
|
7
|
+
dirs += get_gem_dirs
|
8
|
+
dirs.push File.join(File.dirname(__FILE__), 'plugin')
|
9
|
+
dirs.each {|dir| load_plugin_dir dir, config}
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_plugin_dir dir, config=nil
|
13
|
+
dir = File.expand_path dir
|
14
|
+
return unless File.exists? dir
|
15
|
+
files = get_plugin_files dir, config
|
16
|
+
files.each {|fname|
|
17
|
+
unless @loaded[fname]
|
18
|
+
path = File.join dir, fname
|
19
|
+
require path
|
20
|
+
@loaded[fname] = path
|
21
|
+
end
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_plugin_files dir, config=nil
|
26
|
+
files = Dir.entries(dir).sort.select {|fname| fname =~ /\A[^.].*\.rb$/}
|
27
|
+
if config
|
28
|
+
if config['enable-plugin']
|
29
|
+
eps = config.getvar 'enable-plugin'
|
30
|
+
files = files.select {|fname|
|
31
|
+
s = fname.sub(/\.rb$/, '')
|
32
|
+
eps.detect {|pname| pname == s}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
if config['disable-plugin']
|
36
|
+
dps = config.getvar 'disable-plugin'
|
37
|
+
files = files.select {|fname|
|
38
|
+
s = fname.sub(/\.rb$/, '')
|
39
|
+
!dps.detect {|pname| pname == s}
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
files
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_gem_dirs
|
47
|
+
dirs = []
|
48
|
+
if Object.const_defined?(:Gem)
|
49
|
+
if defined?(::Gem::Specification) and
|
50
|
+
Gem::Specification.respond_to?(:find_all)
|
51
|
+
specs = Gem::Specification.find_all {|spec|
|
52
|
+
spec.full_require_paths.map {|path|
|
53
|
+
File.directory?(path + '/gri/plugin')}.any?
|
54
|
+
}.sort_by {|spec| spec.version}.reverse
|
55
|
+
names = {}
|
56
|
+
specs.each {|spec| names[spec.name] ||= spec}
|
57
|
+
names.values.each {|spec|
|
58
|
+
dirs += spec.full_require_paths.map {|path| path + '/gri/plugin'}
|
59
|
+
}
|
60
|
+
elsif Gem.respond_to?(:searcher)
|
61
|
+
specs = Gem.searcher.find_all 'gri/plugin/*.rb'
|
62
|
+
names = {}
|
63
|
+
specs.sort_by {|spec| spec.version}.reverse.each {|spec|
|
64
|
+
names[spec.name] ||= spec
|
65
|
+
}
|
66
|
+
names.values.each {|spec|
|
67
|
+
files = Gem.searcher.matching_files spec, 'gri/plugin/*.rb'
|
68
|
+
dirs += files.map {|fname| File.dirname fname}
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
dirs
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|