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
@@ -0,0 +1,23 @@
|
|
1
|
+
module GRI
|
2
|
+
class AppWalker
|
3
|
+
attr_reader :config, :writers, :metrics
|
4
|
+
|
5
|
+
def initialize config
|
6
|
+
@config = config
|
7
|
+
@writers = []
|
8
|
+
@metrics = Hash.new 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
if ARGV.size == 2
|
13
|
+
host, sym_oid = ARGV
|
14
|
+
snmp = SNMP.new host
|
15
|
+
snmp.version = @config['version'] || '1'
|
16
|
+
snmp.community = @config['community'] || 'public'
|
17
|
+
snmp.walk(sym_oid) {|oid, tag, val|
|
18
|
+
p [oid, tag, val]
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/gri/blank.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Object
|
4
|
+
def blank?
|
5
|
+
respond_to?(:empty?) ? empty? : !self
|
6
|
+
end
|
7
|
+
|
8
|
+
def present?
|
9
|
+
!blank?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class NilClass
|
14
|
+
def blank?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class FalseClass
|
20
|
+
def blank?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class TrueClass
|
26
|
+
def blank?
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Array
|
32
|
+
alias_method :blank?, :empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
class Hash
|
36
|
+
alias_method :blank?, :empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
class String
|
40
|
+
def blank?
|
41
|
+
self !~ /[^[:space:]]/
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Numeric #:nodoc:
|
46
|
+
def blank?
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
module GRI
|
2
|
+
DEFS = {
|
3
|
+
'num'=>{
|
4
|
+
:ds=>['num,num,GAUGE,,,,:index'],
|
5
|
+
:rra=>['RRA:AVERAGE:0.5:15:10000',
|
6
|
+
'RRA:MAX:0.5:1:50000', 'RRA:MAX:0.5:15:10000', 'RRA:MAX:0.5:180:10000'],
|
7
|
+
:prop=>{:name=>'_index', :description=>'description', :lastvalue=>'num'},
|
8
|
+
:list=>['Num', '%N,%L\r'],
|
9
|
+
:graph=>[['', 0]],
|
10
|
+
:composite=>['', 's', 'v', 't'],
|
11
|
+
},
|
12
|
+
'grimetrics'=>{:ds=>['number,number,GAUGE'],
|
13
|
+
:prop=>{:name=>'_index'},
|
14
|
+
:list_text=>['grimetrics', '%N,%L\r'],
|
15
|
+
:composite=>['s'],
|
16
|
+
:graph=>[['n', 0]],
|
17
|
+
},
|
18
|
+
|
19
|
+
'interfaces'=>{:cat=>'',
|
20
|
+
:oid=>['ifDescr', 'ifSpeed', 'ifAdminStatus', 'ifOperStatus', 'ifType',
|
21
|
+
'ifInOctets', 'ifOutOctets',
|
22
|
+
'ifInDiscards', 'ifOutDiscards',
|
23
|
+
'ifInErrors', 'ifOutErrors',
|
24
|
+
'ifInUcastPkts', 'ifOutUcastPkts',
|
25
|
+
'ifInNUcastPkts', 'ifOutNUcastPkts',],
|
26
|
+
:index_key => 'ifDescr',
|
27
|
+
:exclude? => proc {|record|
|
28
|
+
record['ifOperStatus'].to_i != 1 or
|
29
|
+
record['ifSpeed'].to_i == 0 or
|
30
|
+
(Integer(record['ifInOctets']) == 0 and
|
31
|
+
Integer(record['ifOutOctets']) == 0) or
|
32
|
+
/(^(Loopback|Null|Async|lo)\d+)|cef layer|atm subif/ === record['ifDescr']
|
33
|
+
},
|
34
|
+
:hidden? => proc {|record|
|
35
|
+
/cef layer|atm subif|unrouted.VLAN/ === record['ifDescr']
|
36
|
+
},
|
37
|
+
:tdb=>['', 'ifDescr', 'ifAlias', 'ifSpeed',
|
38
|
+
'ifInOctets', 'ifOutOctets', 'ifInDiscards', 'ifOutDiscards',
|
39
|
+
'ifInErrors', 'ifOutErrors', 'ifHCInOctets', 'ifHCOutOctets',],
|
40
|
+
:ds=>['ifInOctets,inoctet,DERIVE,MAX,AREA,#90f090,in,8',
|
41
|
+
'ifOutOctets,outoctet,DERIVE,MAX,LINE1,#0000ff,out,8',
|
42
|
+
'ifInDiscards,indiscard,DERIVE,MAX,LINE1,#00ff0f',
|
43
|
+
'ifOutDiscards,outdiscard,DERIVE,MAX,LINE1,#00afff',
|
44
|
+
'ifInErrors,inerror,DERIVE,MAX,LINE1,#ff0f0f',
|
45
|
+
'ifOutErrors,outerror,DERIVE,MAX,LINE1,#ffaf00',
|
46
|
+
'ifInUcastPkts,inucast,DERIVE,MAX,LINE1,#90f090',
|
47
|
+
'ifOutUcastPkts,outucast,DERIVE,MAX,LINE1,#0000ef',
|
48
|
+
'ifInNUcastPkts,innucast,DERIVE,MAX,LINE1,#ff0f0f',
|
49
|
+
'ifOutNUcastPkts,outnucast,DERIVE,MAX,LINE1,#ffaf00'],
|
50
|
+
:prop=>{:name=>'ifDescr', :description=>'ifAlias',
|
51
|
+
:ostatus=>'ifOperStatus', :astatus=>'ifAdminStatus',
|
52
|
+
:ipaddr=>'ipaddr', :ub=>'ifSpeed',},
|
53
|
+
:list=>['Status,Interface,Description,IP Address', '%S,%N,%D,%I'],
|
54
|
+
:graph=>[['bps', 1000, [0, nil], /Octets/],
|
55
|
+
['pps', 1000, [0, nil], /N?UcastPkts/],
|
56
|
+
['packets/5min', 1000, [0, nil], /Error|Discard/]], #/
|
57
|
+
:composite=>['s', 'v', 't'],
|
58
|
+
},
|
59
|
+
'ifMIB'=>{:cat=>'',
|
60
|
+
:oid=>['ifHCInOctets', 'ifHCOutOctets', 'ifHighSpeed', 'ifAlias'],
|
61
|
+
:fix_workhash=>proc {|wh|
|
62
|
+
for k, r in wh['']
|
63
|
+
r['ifInOctets'] = r['ifHCInOctets'] if r['ifHCInOctets']
|
64
|
+
r['ifOutOctets'] = r['ifHCOutOctets'] if r['ifHCOutOctets']
|
65
|
+
if r['ifHighSpeed'] and r['ifHighSpeed'].to_i > 4000
|
66
|
+
r['ifSpeed'] = r['ifHighSpeed'].to_i * 1_000_000
|
67
|
+
end
|
68
|
+
end
|
69
|
+
},
|
70
|
+
},
|
71
|
+
'ipaddr'=>{
|
72
|
+
:oid=>['ipAdEntIfIndex', 'ipAdEntNetMask'],
|
73
|
+
:feed => lambda {|h, enoid, tag, val|
|
74
|
+
ind = BER.dec_oid(enoid[9..-1]).join('.')
|
75
|
+
h[ind] ||= {}
|
76
|
+
if tag == 2
|
77
|
+
h[ind]['ifIndex'] = val
|
78
|
+
elsif tag == 0x40 # IPv4 Addr
|
79
|
+
h[ind]['mask'] = val
|
80
|
+
end
|
81
|
+
},
|
82
|
+
:fix_workhash => lambda {|wh|
|
83
|
+
ifrecord = wh[''] || {}
|
84
|
+
for k, record in wh[:ipaddr]
|
85
|
+
a = k + '/' + record['mask']
|
86
|
+
ind = record['ifIndex']
|
87
|
+
if (r = ifrecord[ind])
|
88
|
+
if r['ipaddr']
|
89
|
+
r['ipaddr'] += ',' + a
|
90
|
+
else
|
91
|
+
r['ipaddr'] = a
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
wh.delete :ipaddr
|
96
|
+
},
|
97
|
+
},
|
98
|
+
'tcp'=>{
|
99
|
+
:oid=>['tcpCurrEstab', 'tcpActiveOpens',
|
100
|
+
'tcpPassiveOpens', 'tcpAttemptFails', 'tcpEstabResets',
|
101
|
+
'tcpInSegs', 'tcpOutSegs', 'tcpRetransSegs',
|
102
|
+
'tcpInErrs', 'tcpOutRsts',],
|
103
|
+
:tdb=>['tcp', 'tcpCurrEstab', 'tcpActiveOpens',
|
104
|
+
'tcpPassiveOpens', 'tcpAttemptFails', 'tcpEstabResets',
|
105
|
+
'tcpInSegs', 'tcpOutSegs', 'tcpRetransSegs',
|
106
|
+
'tcpInErrs', 'tcpOutRsts',],
|
107
|
+
:ds=>[
|
108
|
+
'tcpCurrEstab,tcpCurrEstab,GAUGE,MAX,AREA,#90f090',
|
109
|
+
'tcpActiveOpens,tcpActiveOpens,DERIVE,MAX,LINE1,#0000ff',
|
110
|
+
'tcpPassiveOpens,tcpPassiveOpens,DERIVE,MAX,LINE1,#c000ff',
|
111
|
+
'tcpAttemptFails,tcpAttemptFails,DERIVE,MAX,LINE1,#ff0000',
|
112
|
+
'tcpEstabResets,tcpEstabResets,DERIVE,MAX,LINE1,#ff9030',
|
113
|
+
|
114
|
+
'tcpInSegs,tcpInSegs,DERIVE,MAX,AREA,#99ff99',
|
115
|
+
'tcpOutSegs,tcpOutSegs,DERIVE,MAX,LINE1,#0000ff',
|
116
|
+
'tcpRetransSegs,tcpRetransSegs,DERIVE,MAX,LINE1,#00ffff',
|
117
|
+
'tcpInErrs,tcpInErrs,DERIVE,MAX,LINE1,#ff0000',
|
118
|
+
'tcpOutRsts,tcpOutRsts,DERIVE,MAX,LINE1,#ff9030',
|
119
|
+
],
|
120
|
+
:prop=>{:name=>'tcp'},
|
121
|
+
:list=>['TCP'],
|
122
|
+
:graph=>[
|
123
|
+
['connection', 0, [0, nil],
|
124
|
+
/tcp(CurrEstab|ActiveOpens|PassiveOpens|AttemptFails|EstabResets)/],
|
125
|
+
['packet/sec', 0, [0, nil],
|
126
|
+
/tcp(InSegs|OutSegs|RetransSegs|InErrs|OutRsts)/]
|
127
|
+
],
|
128
|
+
},
|
129
|
+
'udp'=>{
|
130
|
+
:oid=>['udpInDatagrams', 'udpOutDatagrams',
|
131
|
+
'udpNoPorts', 'udpInErrors'],
|
132
|
+
:tdb=>['udp', 'udpInDatagrams', 'udpOutDatagrams',
|
133
|
+
'udpNoPorts', 'udpInErrors'],
|
134
|
+
:ds=>[
|
135
|
+
'udpInDatagrams,udpInDatagrams,DERIVE,MAX,AREA,#90f090',
|
136
|
+
'udpOutDatagrams,udpOutDatagrams,DERIVE,MAX,LINE1,#0000ef',
|
137
|
+
'udpNoPorts,udpNoPorts,DERIVE,MAX,LINE1,#00afff',
|
138
|
+
'udpInErrors,udpInErrors,DERIVE,MAX,LINE1,#ff0f0f',
|
139
|
+
],
|
140
|
+
:prop=>{:name=>'udp'},
|
141
|
+
:list=>['UDP'], :graph=>[['"datagram/sec"', 0, [0, nil]]],
|
142
|
+
},
|
143
|
+
|
144
|
+
'entityu'=>{:oid=>['entPhysicalDescr', 'entPhysicalName'],},
|
145
|
+
|
146
|
+
'hrSystemNumUsers'=>{
|
147
|
+
:oid=>['hrSystemNumUsers'],
|
148
|
+
:tdb=>['hrsystemnumusers', 'hrSystemNumUsers'],
|
149
|
+
:ds=>['hrSystemNumUsers,users,GAUGE,MAX,LINE1,#ff4020,users'],
|
150
|
+
:prop=>{:name=>'users', :lastvalue=>'hrSystemNumUsers'},
|
151
|
+
:graph=>[['"users"', 0]],
|
152
|
+
:list=>['Users', '%N, %L\r'],
|
153
|
+
},
|
154
|
+
|
155
|
+
'hrStorage'=>{
|
156
|
+
:oid=>['hrStorageEntry'],
|
157
|
+
:tdb=>['hrStorage', 'hrStorageDescr', 'hrStorageSize', 'hrStorageUsed'],
|
158
|
+
:fix_workhash=>lambda {|wh|
|
159
|
+
if (h = wh[:hrStorage])
|
160
|
+
h.reject! {|k, v|
|
161
|
+
v['hrStorageType'] != "+\x06\x01\x02\x01\x19\x02\x01\x04"}
|
162
|
+
h.each {|k, v|
|
163
|
+
u = v['hrStorageAllocationUnits'].to_i
|
164
|
+
v.delete 'hrStorageType'
|
165
|
+
v['hrStorageSize'] = v['hrStorageSize'].to_i * u
|
166
|
+
v['hrStorageUsed'] = v['hrStorageUsed'].to_i * u
|
167
|
+
}
|
168
|
+
end
|
169
|
+
},
|
170
|
+
:ds=>['hrStorageUsed,used,GAUGE,MAX,AREA,#40ff40'],
|
171
|
+
:prop=>{:name=>'hrStorageDescr',
|
172
|
+
:lastvalue=>'hrStorageUsed', :ub=>'hrStorageSize'},
|
173
|
+
:list=>['Storage Used', '%N, %1024L / %1024U\r'],
|
174
|
+
:graph=>[['storage used', 1024]],
|
175
|
+
:composite=>['s', 'v', 't'],
|
176
|
+
},
|
177
|
+
|
178
|
+
:term => {
|
179
|
+
:default=>[['Daily', 30*3600], ['Weekly', 8*24*3600],
|
180
|
+
['Monthly', 31*24*3600], ['Yearly', 365*24*3600]],
|
181
|
+
:short=>[['Last 3 hours', 3*3600], ['Daily', 30*3600],
|
182
|
+
['Weekly', 8*24*3600], ['Monthly', 31*24*3600]],
|
183
|
+
:long=>[['Weekly', 8*24*3600], ['Monthly', 31*24*3600],
|
184
|
+
['Yearly', 365*24*3600], ['Last 6 years', 6*365*24*3600]],
|
185
|
+
:verylong=>[['Monthly', 31*24*3600], ['Yearly', 365*24*3600],
|
186
|
+
['Last 8 years', 8*365*24*3600]],
|
187
|
+
}
|
188
|
+
}
|
189
|
+
|
190
|
+
class <<DEFS
|
191
|
+
alias :update :merge!
|
192
|
+
def get_specs key
|
193
|
+
unless @specs
|
194
|
+
@specs = {}
|
195
|
+
for k, dhash in self
|
196
|
+
next unless String === k
|
197
|
+
data_name = dhash[:data_name] || dhash[:cat] ||
|
198
|
+
(dhash[:tdb] and dhash[:tdb].first) ||
|
199
|
+
k.gsub(/-/, '')
|
200
|
+
spec = (@specs[data_name.to_s] ||= {})
|
201
|
+
[:list, :index_key, :named_index, :tdb, :ds, :rra, :prop,
|
202
|
+
:graph, :composite, :exclude?, :hidden?].each {|symkey|
|
203
|
+
spec[symkey] = dhash[symkey] if dhash[symkey]
|
204
|
+
}
|
205
|
+
spec[:list] ||= dhash[:list_text] #XXX
|
206
|
+
end
|
207
|
+
end
|
208
|
+
@specs[key.to_s]
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
data/lib/gri/cast.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'gri/config'
|
2
|
+
require 'gri/log'
|
3
|
+
require 'gri/wmain'
|
4
|
+
require 'gri/api'
|
5
|
+
require 'gri/list'
|
6
|
+
require 'gri/page'
|
7
|
+
require 'gri/cgraph'
|
8
|
+
require 'gri/clist'
|
9
|
+
|
10
|
+
module GRI
|
11
|
+
class Cast
|
12
|
+
def self.parse_path_info env
|
13
|
+
if (path_info = env['PATH_INFO']) =~ %r{^/(?:list|graph)\b}
|
14
|
+
path_info = Regexp.last_match.post_match
|
15
|
+
end
|
16
|
+
if path_info
|
17
|
+
dummy, service_name, section_name, graph_name = path_info.split /\// #/
|
18
|
+
end
|
19
|
+
return service_name, section_name, graph_name
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
root_dir = Config['root-dir'] ||= Config::ROOT_PATH
|
24
|
+
log_dir = Config['log-dir'] || Config['root-dir'] + '/log'
|
25
|
+
Log.init "#{log_dir}/#{File.basename $0}.log"
|
26
|
+
rescue SystemCallError
|
27
|
+
Log.init '/tmp/gricast.log'
|
28
|
+
end
|
29
|
+
|
30
|
+
def call env
|
31
|
+
req = GRI::Request.new env
|
32
|
+
params = req.params
|
33
|
+
cast_dir = Config['cast-dir'] || (Config::ROOT_PATH + '/cast')
|
34
|
+
if params['grp']
|
35
|
+
cast_dir = cast_dir + '/' + params['grp']
|
36
|
+
end
|
37
|
+
|
38
|
+
if (req.query_string =~ /\A(\d+),(\d+)\z/)
|
39
|
+
app = Page.new :dirs=>[cast_dir], :clicked=>true, :imgx=>$1, :imgy=>$2
|
40
|
+
elsif params['r'] or params['tag']
|
41
|
+
if params['stime']
|
42
|
+
app = Graph.new :dirs=>[cast_dir]
|
43
|
+
else
|
44
|
+
app = Page.new :dirs=>[cast_dir]
|
45
|
+
end
|
46
|
+
elsif params['search'].to_i == 1
|
47
|
+
app = List.new :dirs=>[cast_dir]
|
48
|
+
elsif
|
49
|
+
case env['PATH_INFO']
|
50
|
+
when %r{^/api/}
|
51
|
+
app = API.new
|
52
|
+
when %r{^/graph/}
|
53
|
+
app = Cgraph.new :dir=>cast_dir
|
54
|
+
when %r{^/page}
|
55
|
+
app = Page.new :dirs=>[cast_dir]
|
56
|
+
else
|
57
|
+
app = Clist.new :dir=>cast_dir
|
58
|
+
end
|
59
|
+
end
|
60
|
+
app.call env
|
61
|
+
end
|
62
|
+
|
63
|
+
def public_dir
|
64
|
+
File.dirname(__FILE__) + '/../../public'
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.layout
|
68
|
+
<<EOS
|
69
|
+
<html>
|
70
|
+
<head>
|
71
|
+
<title><%= @title %></title>
|
72
|
+
<style>
|
73
|
+
td.text-right {text-align:right;}
|
74
|
+
hr {border:none;border-top:1px #cccccc solid;}
|
75
|
+
</style>
|
76
|
+
</head>
|
77
|
+
<body>
|
78
|
+
<%= yield %>
|
79
|
+
</body>
|
80
|
+
</html>
|
81
|
+
EOS
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/gri/cgraph.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'gri/rrd'
|
2
|
+
require 'gri/graph'
|
3
|
+
|
4
|
+
module GRI
|
5
|
+
class Cgraph
|
6
|
+
TERMS = {'sh'=>['Hour', 3600], 's8h'=>['8Hours', 8*3600],
|
7
|
+
'd'=>['Day', 24*3600], 'w'=>['Week', 7*24*3600],
|
8
|
+
'm'=>['Month', 31*24*3600], 'y'=>['Year', 366*24*3600]}
|
9
|
+
|
10
|
+
def initialize options={}
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def call env
|
15
|
+
req = Rack::Request.new env
|
16
|
+
service_name, section_name, graph_name = Cast.parse_path_info env
|
17
|
+
|
18
|
+
begin
|
19
|
+
cast_dir = @options[:dir]
|
20
|
+
gra_dir = "#{cast_dir}/#{service_name}"
|
21
|
+
|
22
|
+
params = GParams.new
|
23
|
+
params['r'] = "#{section_name}_num_#{graph_name}"
|
24
|
+
params['z'] = 'gf'
|
25
|
+
t = req.params['t'] || 'd'
|
26
|
+
params['title'] = TERMS[t].first
|
27
|
+
gr = Graph.new :dirs=>[gra_dir]
|
28
|
+
etime = Time.now.to_i
|
29
|
+
stime = etime - TERMS[t][1]
|
30
|
+
img = gr.graph stime, etime, params
|
31
|
+
[200, {'Content-type' => 'image/png'}, [img]]
|
32
|
+
rescue
|
33
|
+
[500, {}, []]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/gri/clist.rb
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'gri/format_helper'
|
2
|
+
require 'gri/util_marshal'
|
3
|
+
|
4
|
+
module GRI
|
5
|
+
class Clist
|
6
|
+
TERMS = {'sh'=>[['sh', 's8h'], 'hour/8hours', 0],
|
7
|
+
'd'=>[['d', 'w'], 'day/week', 3],
|
8
|
+
'm'=>[['m', 'y'], 'month/year', 4]}
|
9
|
+
|
10
|
+
include FormatHelper
|
11
|
+
|
12
|
+
def initialize options={}
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def call env
|
17
|
+
req = Rack::Request.new env
|
18
|
+
if (path_info = env['PATH_INFO']) =~ %r{^/list}
|
19
|
+
path_info = Regexp.last_match.post_match
|
20
|
+
end
|
21
|
+
if path_info
|
22
|
+
dummy, service_name, section_name, graph_name = path_info.split /\// #/
|
23
|
+
end
|
24
|
+
|
25
|
+
list_item = path_info
|
26
|
+
dir = @options[:dir] || Config['cast-dir'] ||
|
27
|
+
(Config::ROOT_PATH + '/cast')
|
28
|
+
|
29
|
+
pt = req.params['t'] || 'd'
|
30
|
+
t = TERMS[pt] || TERMS['d']
|
31
|
+
dirs = scan_dir dir, service_name, section_name, graph_name
|
32
|
+
@title = 'list'
|
33
|
+
body = render(Cast.layout) {render template, binding}
|
34
|
+
[200, {'Content-type' => 'text/html'}, body]
|
35
|
+
end
|
36
|
+
|
37
|
+
def scan_dir dir, service_name, section_name, graph_name
|
38
|
+
h = {}
|
39
|
+
for f0 in Dir.glob(dir + '/' + (service_name || '*'))
|
40
|
+
b0 = File.basename f0
|
41
|
+
if File.directory? f0
|
42
|
+
h[b0] = {}
|
43
|
+
for f1 in Dir.glob(f0 + '/' + (section_name || '*'))
|
44
|
+
b1 = File.basename f1
|
45
|
+
if File.directory? f1
|
46
|
+
h[b0][b1] = {}
|
47
|
+
pat = graph_name ? "#{section_name}_num_#{graph_name}.rrd" : '*'
|
48
|
+
for f2 in Dir.glob(f1 + '/' + pat)
|
49
|
+
b2 = File.basename f2
|
50
|
+
if b2 =~ /^(?:[^_]+)_(?:[^_]+)_(.+).rrd/
|
51
|
+
h[b0][b1][$1] = true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
else
|
57
|
+
h[b0] = true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
h
|
61
|
+
end
|
62
|
+
|
63
|
+
def sysdb_path dir
|
64
|
+
sysdb_path = dir + '/.sysdb/sysdb.dump'
|
65
|
+
end
|
66
|
+
|
67
|
+
def load_sysdb dir
|
68
|
+
sysdb = Marshal.load_from_file sysdb_path(dir) || {}
|
69
|
+
end
|
70
|
+
|
71
|
+
def mk_graph_tag service_name, section_name, graph_name, t, ind
|
72
|
+
cs = (Time.now - Cgraph::TERMS[t[0][ind]][1]).strftime('%Y-%m-%d %H:%M:%S')
|
73
|
+
u = "?grp=#{service_name}&r=#{section_name}_num_#{graph_name}&pt=s"
|
74
|
+
gu = "graph/#{service_name}/#{section_name}/#{graph_name}"
|
75
|
+
img = "<img src=\"#{url_to gu + '?t=' + t[0][ind]}\"/>"
|
76
|
+
"<a href=\"#{u}&cs=#{Rack::Utils.escape cs}\">#{img}</a>"
|
77
|
+
end
|
78
|
+
|
79
|
+
CMNAME = {'s'=>'stack', 'v'=>'overlay', ''=>'sum', 't'=>'tile'}
|
80
|
+
def mk_comp_links comps, host, ckeys, aparam
|
81
|
+
links = []
|
82
|
+
for cm in comps
|
83
|
+
href_fp = url_to "?p=#{cm}&#{aparam}"
|
84
|
+
href = href_fp + ckeys.map {|k| "r=#{host}_#{k}"}.join('&')
|
85
|
+
links.push mk_tag('a', {:href=>href}, CMNAME[cm])
|
86
|
+
end
|
87
|
+
links
|
88
|
+
end
|
89
|
+
|
90
|
+
def template
|
91
|
+
<<'EOS'
|
92
|
+
<% if section_name -%>
|
93
|
+
|
94
|
+
<% d0 = dirs.keys.first -%>
|
95
|
+
|
96
|
+
<% if (ckeys = dirs[d0][section_name].keys.map {|k| "num_#{k}"}).size > 1 -%>
|
97
|
+
<div style="float: right!important;" class="pull-right"><ul class="pagination">
|
98
|
+
<% for u in mk_comp_links(DEFS['num'][:composite], section_name, ckeys, "grp=#{d0}&") -%>
|
99
|
+
<li><%= u %></li>
|
100
|
+
<% end -%>
|
101
|
+
</ul></div>
|
102
|
+
<% end -%>
|
103
|
+
|
104
|
+
<div style="float: right!important;" class="pull-right"><ul class="pagination">
|
105
|
+
<% for k, v in TERMS.sort_by {|kk, vv| vv[2]} -%>
|
106
|
+
<li style="display: inline"<%= (pt == k) ? " class=active" : '' %>>
|
107
|
+
<a href="<%= url_to "list/#{d0}/#{section_name}?t=#{k}" %>"><%= v[1] %></a>
|
108
|
+
</li>
|
109
|
+
<% end -%>
|
110
|
+
</ul></div>
|
111
|
+
|
112
|
+
|
113
|
+
<section>
|
114
|
+
<h1>
|
115
|
+
<a href="<%= url_to ''%>">Home</a> »
|
116
|
+
<a href="<%= url_to "list/#{d0}"%>"><%= d0 %></a> »
|
117
|
+
<% if graph_name -%>
|
118
|
+
<a href="<%= url_to "list/#{d0}/#{section_name}"%>"><%= section_name%></a> »
|
119
|
+
<%= graph_name %>
|
120
|
+
<% else -%>
|
121
|
+
<%= section_name%>
|
122
|
+
<% end -%>
|
123
|
+
</h1>
|
124
|
+
|
125
|
+
<% for graph_name in dirs[d0][section_name].keys.sort -%>
|
126
|
+
<h2>
|
127
|
+
<a href="<%= url_to "list/#{d0}/#{section_name}/#{graph_name}"%>"><%= graph_name %></a>
|
128
|
+
</h2>
|
129
|
+
<%= mk_graph_tag service_name, section_name, graph_name, t, 0 %>
|
130
|
+
<%= mk_graph_tag service_name, section_name, graph_name, t, 1 %>
|
131
|
+
<% end %>
|
132
|
+
</section>
|
133
|
+
|
134
|
+
<% else -%><!-- if section_name -->
|
135
|
+
|
136
|
+
<section>
|
137
|
+
<h1>
|
138
|
+
<a href="<%= url_to ''%>">Home</a>
|
139
|
+
<% if service_name -%>
|
140
|
+
» <%= service_name %>
|
141
|
+
<% end -%>
|
142
|
+
</h1>
|
143
|
+
|
144
|
+
<% for d0 in dirs.keys.sort %>
|
145
|
+
<h2><a href="<%= url_to('list') + '/' + d0 %>"><%=h d0 %>
|
146
|
+
</a></h2>
|
147
|
+
<!--a href="<%= url_to "?search=1&grp=#{d0}" %>">search</a-->
|
148
|
+
<table class="table table-striped">
|
149
|
+
<% for d1 in dirs[d0].keys.sort -%>
|
150
|
+
<tr>
|
151
|
+
<td><a href="<%= url_to('list')+'/'+d0+'/'+d1 %>"><%= d1 %></a></td>
|
152
|
+
</tr>
|
153
|
+
<% end -%>
|
154
|
+
</table>
|
155
|
+
</section>
|
156
|
+
<% end %>
|
157
|
+
|
158
|
+
<% end -%><!-- if section_name -->
|
159
|
+
<hr/>
|
160
|
+
EOS
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|