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/updater.rb
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
require 'gri/builtindefs'
|
4
|
+
require 'gri/rrd'
|
5
|
+
require 'gri/utils'
|
6
|
+
require 'gri/config'
|
7
|
+
|
8
|
+
module GRI
|
9
|
+
class Updater
|
10
|
+
include Utils
|
11
|
+
attr_reader :options
|
12
|
+
|
13
|
+
def self.get_tag_ary description
|
14
|
+
unless @tag_pats
|
15
|
+
@tag_pats = (pats = GRI::Config.getvar 'tag-rule') ?
|
16
|
+
pats.map {|patline| pat, *remain =
|
17
|
+
patline.scan(/^\/([^\/]+)\/\s+(\S+)\s+(\S+)\s+(\S+)/)[0] #/
|
18
|
+
[Regexp.new(pat), *remain]} : []
|
19
|
+
end
|
20
|
+
@tag_pats.map {|re, group, subdir, descr_v|
|
21
|
+
if re === description
|
22
|
+
m = $~.to_a
|
23
|
+
if group =~ /^\$(\d+)(\.\w+)?/
|
24
|
+
group = m[$1.to_i].dup
|
25
|
+
group.downcase! if $2 == '.downcase'
|
26
|
+
end
|
27
|
+
if subdir =~ /^\$(\d+)(\.\w+)?/
|
28
|
+
subdir = m[$1.to_i].dup
|
29
|
+
subdir.downcase! if $2 == '.downcase'
|
30
|
+
end
|
31
|
+
if descr_v =~ /^\$(\d+)/
|
32
|
+
descr_v = m[$1.to_i]
|
33
|
+
end
|
34
|
+
[group, subdir, descr_v]
|
35
|
+
else
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
}.compact
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize options={}
|
42
|
+
@options = options
|
43
|
+
@interval = options[:step] || options[:interval] || 300
|
44
|
+
@config = GRI::Config
|
45
|
+
end
|
46
|
+
|
47
|
+
def update time, record
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class RRDUpdater < Updater
|
52
|
+
attr_reader :rrd, :key
|
53
|
+
attr_accessor :rrd_class
|
54
|
+
|
55
|
+
def initialize options={}
|
56
|
+
super
|
57
|
+
@tagrrds = {}
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_rrd path, time, interval, ds_specs, rra_specs
|
61
|
+
ds_args, @record_keys = mk_ds_args ds_specs, interval
|
62
|
+
rra_args = rra_specs || mk_rra_args
|
63
|
+
@rrd_args = ds_args + rra_args
|
64
|
+
rrd = (@rrd_class || RRD).new @options[:rrdcached_address],
|
65
|
+
@options[:base_dir]
|
66
|
+
rrd.set_create_args path, (time - interval), interval, *@rrd_args
|
67
|
+
rrd
|
68
|
+
end
|
69
|
+
|
70
|
+
def mk_ds_args ds_specs, interval
|
71
|
+
ds_args = []
|
72
|
+
record_keys = []
|
73
|
+
n = 0
|
74
|
+
for spec_line in ds_specs
|
75
|
+
key, dsname, dst = spec_line.split /,/
|
76
|
+
heartbeat = interval * ((dst == 'DERIVE' or dst == 'COUNTER') ? 2.5 : 2)
|
77
|
+
key = key[1..-1].intern if key[0] == ?:
|
78
|
+
record_keys.push key
|
79
|
+
ds_args.push "DS:#{dsname}:#{dst}:#{heartbeat.to_i}:U:U"
|
80
|
+
n += 1
|
81
|
+
end
|
82
|
+
return ds_args, record_keys
|
83
|
+
end
|
84
|
+
|
85
|
+
def mk_rra_args
|
86
|
+
rra_args = []
|
87
|
+
for cf in ['average', 'max', 'min']
|
88
|
+
optrraname = "rra-#{@options[:data_name]}-#{cf}"
|
89
|
+
if (optrra = @config.getvar optrraname)
|
90
|
+
for line in optrra
|
91
|
+
steps, rows = line.split
|
92
|
+
rra_args.push "RRA:#{cf.upcase}:0.5:#{steps}:#{rows}"
|
93
|
+
end
|
94
|
+
else
|
95
|
+
optrraname = 'rra-' + cf
|
96
|
+
optrra = @config.getvar optrraname
|
97
|
+
if optrra
|
98
|
+
for line in optrra
|
99
|
+
steps, rows = line.split
|
100
|
+
rra_args.push "RRA:#{cf.upcase}:0.5:#{steps}:#{rows}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
rra_args.size.zero? ? default_rra_args : rra_args
|
106
|
+
end
|
107
|
+
|
108
|
+
def default_rra_args
|
109
|
+
['RRA:AVERAGE:0.5:12:9000', 'RRA:MAX:0.5:1:20000',
|
110
|
+
'RRA:MAX:0.5:12:9000', 'RRA:MAX:0.5:144:2000']
|
111
|
+
end
|
112
|
+
|
113
|
+
def mk_key options
|
114
|
+
unless (key = options[:key])
|
115
|
+
data_name = options[:data_name]
|
116
|
+
key = (Numeric === (index = options[:index])) ?
|
117
|
+
"#{data_name}#{index}" : "#{data_name}_#{index}"
|
118
|
+
end
|
119
|
+
key
|
120
|
+
end
|
121
|
+
|
122
|
+
def mk_path options
|
123
|
+
host = options[:host]
|
124
|
+
dir = options[:dir] || options[:gra_dir] + '/' + host
|
125
|
+
dkey = mk_key options
|
126
|
+
"#{dir}/#{host}_#{dkey}.rrd"
|
127
|
+
end
|
128
|
+
|
129
|
+
def update time, record
|
130
|
+
unless @rrd
|
131
|
+
data_name = options[:data_name]
|
132
|
+
@specs = DEFS.get_specs data_name
|
133
|
+
return unless @specs # unknown data_name
|
134
|
+
return unless @specs[:ds]
|
135
|
+
#if (index_key = (@specs[:index_key] || @specs[:named_index]) and
|
136
|
+
# index = record[index_key])
|
137
|
+
# options[:index] = key_encode index
|
138
|
+
# options.delete :key
|
139
|
+
#end
|
140
|
+
@key = mk_key options
|
141
|
+
return if (ex_proc = @specs[:exclude?]) and ex_proc.call(record)
|
142
|
+
path = mk_path options
|
143
|
+
ds_specs = @specs[:ds]
|
144
|
+
return if !ds_specs or ds_specs.empty?
|
145
|
+
@rrd = create_rrd path, time, (@interval || 300),
|
146
|
+
ds_specs, @specs[:rra]
|
147
|
+
end
|
148
|
+
data = @record_keys.map {|key| record[key]}
|
149
|
+
s = "#{time.to_i}:#{mk_update_str data}"
|
150
|
+
puts " update #{@key} #{s}" if record['_d']
|
151
|
+
@rrd.buffered_update s
|
152
|
+
|
153
|
+
if (prop = @specs[:prop]) and (descr_k = prop[:description]) and
|
154
|
+
(description = record[descr_k]) and !description.empty?
|
155
|
+
for group, subdir, descr_v in Updater.get_tag_ary(description)
|
156
|
+
unless (tagrrd = @tagrrds[group + '/' + subdir])
|
157
|
+
tagrrd = create_tagrrd group, subdir, descr_v, record
|
158
|
+
@tagrrds[group + '/' + subdir] = tagrrd
|
159
|
+
end
|
160
|
+
tagrrd.buffered_update s
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def mk_update_str data
|
166
|
+
data.map {|item|
|
167
|
+
if item =~ /\A0x[\da-f]+\z/i
|
168
|
+
Integer(item)
|
169
|
+
elsif item == '' or item == nil or
|
170
|
+
(item.kind_of?(Float) and not(item.finite?)) or
|
171
|
+
(item.kind_of?(String) and item !~ /\A[-+e\.\d]+$/i)
|
172
|
+
'U'
|
173
|
+
else
|
174
|
+
item
|
175
|
+
end
|
176
|
+
}.join(':')
|
177
|
+
end
|
178
|
+
|
179
|
+
def create_tagrrd group, subdir, descr_v, record
|
180
|
+
grp_dir = "#{options[:gra_dir]}/#{group}"
|
181
|
+
Dir.mkdir grp_dir unless File.exist? grp_dir
|
182
|
+
tag_dir = "#{grp_dir}/#{subdir}"
|
183
|
+
Dir.mkdir tag_dir unless File.exist? tag_dir
|
184
|
+
open(tag_dir + '/.description', 'w') {|f| f.puts descr_v}
|
185
|
+
|
186
|
+
time = record['_time']
|
187
|
+
path = "#{tag_dir}/#{@options[:host]}_#{@key}.rrd"
|
188
|
+
tagrrd = (@rrd_class ||RRD).new @options[:rrdcached_address],
|
189
|
+
@options[:base_dir]
|
190
|
+
tagrrd.set_create_args path, (time - @interval), @interval, *@rrd_args
|
191
|
+
tagrrd
|
192
|
+
end
|
193
|
+
|
194
|
+
def close
|
195
|
+
if @rrd
|
196
|
+
@rrd.flush_buffer
|
197
|
+
end
|
198
|
+
@tagrrds.each_value {|tagrrd| tagrrd.flush_buffer}
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Process
|
2
|
+
class << self
|
3
|
+
unless method_defined?(:daemon)
|
4
|
+
def daemon(nochdir = nil, noclose = nil)
|
5
|
+
exit!(0) if Process.fork
|
6
|
+
Process.setsid
|
7
|
+
exit!(0) if Process.fork
|
8
|
+
Dir.chdir("/") unless nochdir
|
9
|
+
unless noclose
|
10
|
+
#File.umask(0)
|
11
|
+
STDIN.reopen("/dev/null", "r")
|
12
|
+
STDOUT.reopen("/dev/null", "w")
|
13
|
+
STDERR.reopen("/dev/null", "w")
|
14
|
+
end
|
15
|
+
0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
def Marshal.dump_to_file obj, path
|
2
|
+
tmppath = path + ".tmp#{$$}"
|
3
|
+
open(tmppath, 'w') {|f| Marshal.dump obj, f}
|
4
|
+
File.rename tmppath, path
|
5
|
+
end
|
6
|
+
|
7
|
+
def Marshal.load_from_file path
|
8
|
+
obj = nil
|
9
|
+
if File.size? path
|
10
|
+
open(path) {|f| obj = Marshal.load(f) rescue nil}
|
11
|
+
end
|
12
|
+
obj
|
13
|
+
end
|
data/lib/gri/utils.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'gri/ltsv'
|
2
|
+
|
3
|
+
module GRI
|
4
|
+
module Utils
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def load_records dir
|
8
|
+
values = LTSV.load_from_file dir + '/.records.txt'
|
9
|
+
values.inject({}) {|h, v| h[v['_key']] = v; h}
|
10
|
+
end
|
11
|
+
|
12
|
+
def search_records dirs, host
|
13
|
+
for dir in dirs
|
14
|
+
path = "#{dir}/#{host}/.records.txt"
|
15
|
+
if File.exist? path
|
16
|
+
values = LTSV.load_from_file path
|
17
|
+
rh = values.inject({}) {|h, v| (k = v['_key']) and h[k] = v; h}
|
18
|
+
return [dir, rh]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_prop record
|
25
|
+
h = {}
|
26
|
+
data_name, index = parse_key record['_key']
|
27
|
+
record['_index'] = index
|
28
|
+
if data_name and (specs = DEFS.get_specs data_name) and specs[:prop]
|
29
|
+
specs[:prop].each {|k1, k2| h[k1] = record[k2] if record[k2]}
|
30
|
+
h[:name] ||= specs[:prop][:name]
|
31
|
+
end
|
32
|
+
h
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_ltsv_file path, key, other
|
36
|
+
if File.exist? path
|
37
|
+
values = LTSV.load_from_file path
|
38
|
+
nvalues = values.inject({}) {|h, v| h[v[key]] = v; h}
|
39
|
+
nvalues.merge! other
|
40
|
+
else
|
41
|
+
nvalues = other
|
42
|
+
end
|
43
|
+
LTSV.dump_to_file nvalues, path
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_key s
|
47
|
+
s.to_s.scan(/\A([^_\d]*)(?:_?(.*))/).first
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_host_key s
|
51
|
+
s.to_s.scan(/\A([-\.A-Za-z0-9]+)_([^_\d]*)(?:_?(.*))/).first
|
52
|
+
end
|
53
|
+
|
54
|
+
def url_encode(s)
|
55
|
+
s.to_s.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
|
56
|
+
end
|
57
|
+
|
58
|
+
def key_encode s
|
59
|
+
s.to_s.tr(':/ =', '\-\-__').gsub(/[^-a-zA-Z0-9_.]/n) { #/
|
60
|
+
"%02X"%$&.unpack('C').first}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/gri/vendor.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module GRI
|
2
|
+
class Vendor
|
3
|
+
DEFS = {}
|
4
|
+
class <<DEFS
|
5
|
+
alias :update :merge!
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :name, :options
|
9
|
+
|
10
|
+
def self.check sysinfo, options={}
|
11
|
+
vdefs = nil
|
12
|
+
if !(sysobjectid = sysinfo['sysObjectID']) or sysobjectid.size < 5
|
13
|
+
else
|
14
|
+
sysoid = BER.dec_oid(sysobjectid[5..-1])
|
15
|
+
sysoid.size.downto(1) {|n|
|
16
|
+
sysoidkey = sysoid[0, n].map {|noid| noid.to_s}.join('.')
|
17
|
+
if (vdefs = self::DEFS[sysoidkey])
|
18
|
+
if Array === vdefs
|
19
|
+
vname, voptions, f_re, v_re = vdefs
|
20
|
+
vdefs = {:name=>vname, :options=>voptions,
|
21
|
+
:firm_re=>f_re, :version_re=>v_re}
|
22
|
+
end
|
23
|
+
break
|
24
|
+
end
|
25
|
+
}
|
26
|
+
end
|
27
|
+
vdefs ||= {:name=>'unknown'}
|
28
|
+
Vendor.new vdefs, sysinfo, options
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize vdefs, sysinfo, options
|
32
|
+
@name = vdefs[:name]
|
33
|
+
@sysinfo = sysinfo
|
34
|
+
@options = {'ver'=>'1', 'interfaces'=>true, 'ipaddr'=>true}
|
35
|
+
@options.merge! vdefs[:options] if vdefs[:options]
|
36
|
+
@options.merge! options if options
|
37
|
+
class <<@options
|
38
|
+
def set_unless_defined k, v=true
|
39
|
+
self[k] = v unless self.has_key? k
|
40
|
+
end
|
41
|
+
end
|
42
|
+
sysinfo['_firm'] = get_firm vdefs[:firm_re], sysinfo
|
43
|
+
sysinfo['_ver'] = get_ver vdefs[:version_re], sysinfo
|
44
|
+
sysinfo['_sysdescr'] = sysinfo['sysDescr']
|
45
|
+
if (cb = vdefs[:after_initialize])
|
46
|
+
cb.call @sysinfo, @options
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_firm f_re, sysinfo
|
51
|
+
sysdescr = sysinfo['sysDescr'] || '?'
|
52
|
+
if f_re
|
53
|
+
match = f_re.match sysdescr
|
54
|
+
match ? match[1] : '?'
|
55
|
+
else
|
56
|
+
(f = sysdescr.scan(/\A([-\w]+)/).first) ? f[0] : '?'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_ver v_re, sysinfo
|
61
|
+
sysdescr = sysinfo['sysDescr'] || '?'
|
62
|
+
if v_re
|
63
|
+
match = v_re.match sysdescr
|
64
|
+
match ? match[1] : '?'
|
65
|
+
else
|
66
|
+
tmp, = sysdescr.scan(/(\d+\.[\.\d]+)/).first
|
67
|
+
tmp || '?'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_punits
|
72
|
+
units = PollingUnit.all_units
|
73
|
+
options.keys.map {|k| options[k] ? units[k] : nil}.compact
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/gri/version.rb
ADDED
data/lib/gri/wmain.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
require 'gri/msnmp'
|
4
|
+
require 'gri/builtindefs'
|
5
|
+
require 'gri/vendor'
|
6
|
+
require 'gri/plugin'
|
7
|
+
|
8
|
+
module GRI
|
9
|
+
class WMain
|
10
|
+
attr_writer :app
|
11
|
+
|
12
|
+
def initialize app=nil
|
13
|
+
@app = app
|
14
|
+
config_path = ENV['GRI_CONFIG_PATH'] || Config::DEFAULT_PATH
|
15
|
+
Config.init config_path
|
16
|
+
end
|
17
|
+
|
18
|
+
def run opts=nil
|
19
|
+
opts ||= {:server=>'webrick', :Port=>5125}
|
20
|
+
optparser = optparse opts
|
21
|
+
optparser.parse!
|
22
|
+
root_dir = Config['root-dir'] ||= Config::ROOT_PATH
|
23
|
+
plugin_dirs = Config.getvar('plugin-dir') || [root_dir + '/plugin']
|
24
|
+
Plugin.load_plugins plugin_dirs, Config
|
25
|
+
|
26
|
+
app = @app
|
27
|
+
builder = Rack::Builder.new {
|
28
|
+
use Rack::Static, :urls=>['/css', '/js'], :root=>app.public_dir
|
29
|
+
run app
|
30
|
+
}
|
31
|
+
if ENV['GATEWAY_INTERFACE']
|
32
|
+
Rack::Handler::CGI.run builder
|
33
|
+
else
|
34
|
+
if Rack.const_defined? :Server
|
35
|
+
opts[:app] = builder
|
36
|
+
Rack::Server.new(opts).start
|
37
|
+
else
|
38
|
+
Rack::Handler::WEBrick.run builder, opts
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def optparse opts
|
44
|
+
op = OptionParser.new
|
45
|
+
op.on('--debug') {$debug = true; STDOUT.sync = true}
|
46
|
+
op.on('-d', '--daemonize') {opts[:daemonize] = true}
|
47
|
+
op.on('-h', '--host HOST') {|arg| opts[:Host] = arg}
|
48
|
+
op.on('-p', '--port PORT', Integer) {|arg| opts[:Port] = arg}
|
49
|
+
op.on('-s', '--server SERVER') {|arg| opts[:server] = arg}
|
50
|
+
class <<op
|
51
|
+
attr_accessor :options
|
52
|
+
end
|
53
|
+
op.options = opts
|
54
|
+
op
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
module Rack
|
60
|
+
class Static
|
61
|
+
alias :call0 :call
|
62
|
+
def call env
|
63
|
+
env['PATH_INFO'] ||= '/'
|
64
|
+
call0 env
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|