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/ldb.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'gri/ltsv'
|
3
|
+
|
4
|
+
module GRI
|
5
|
+
class LocalLDB
|
6
|
+
def self.get_gritab_lines path
|
7
|
+
lines = File.readlines path
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize dir
|
11
|
+
@dir = dir
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_after data_name, time, pos=0
|
15
|
+
open_after(data_name, time) {|t, line, pos|
|
16
|
+
h = LTSV.parse_string line
|
17
|
+
yield t, h, pos
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def getl_after data_name, time, pos=0
|
22
|
+
open_after(data_name, time, pos) {|t, line, pos2|
|
23
|
+
yield t, line, pos2
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def open_after data_name, time, pos=0
|
28
|
+
ymd = time.strftime '%Y%m%d'
|
29
|
+
pat = "#{@dir}/#{data_name}_*/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
|
30
|
+
for ymd_file in Dir.glob(pat).sort
|
31
|
+
vymd = File.basename ymd_file
|
32
|
+
if vymd >= ymd
|
33
|
+
rtime = Time.local(vymd[0, 4], vymd[4, 2], vymd[6, 2])
|
34
|
+
open(ymd_file, 'rb') {|f|
|
35
|
+
f.pos = pos
|
36
|
+
while line = f.gets
|
37
|
+
pos += line.size
|
38
|
+
line.chomp!
|
39
|
+
tstr = line.scan(/\b_time:(\d+)\b/).first.first rescue nil
|
40
|
+
t = Time.at(tstr.to_i)
|
41
|
+
if t > time
|
42
|
+
yield t, line, pos
|
43
|
+
end
|
44
|
+
end
|
45
|
+
pos = 0
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_data_names
|
52
|
+
Dir.glob("#{@dir}/*_*").inject({}) {|h, path|
|
53
|
+
data_name, interval = File.basename(path).split /_/
|
54
|
+
h[data_name || ''] = (interval || 300).to_i
|
55
|
+
h
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
def close
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class RemoteLDB
|
64
|
+
def self.get_gritab_lines tra_uri
|
65
|
+
lines = nil
|
66
|
+
tra_uri.path = '/gritab'
|
67
|
+
get_lines tra_uri
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.get_lines uri
|
71
|
+
case uri.scheme
|
72
|
+
when 'http'
|
73
|
+
res = Net::HTTP.get uri
|
74
|
+
lines = res.split /\n/
|
75
|
+
when 'tra'
|
76
|
+
sock = TCPSocket.new(uri.host, uri.port || 7079)
|
77
|
+
sock.puts "#{uri.path} #{uri.query}"
|
78
|
+
lines = tra_gets sock
|
79
|
+
sock.close
|
80
|
+
end
|
81
|
+
lines
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.tra_gets sock
|
85
|
+
lines = []
|
86
|
+
while line = sock.gets
|
87
|
+
line.chomp!
|
88
|
+
break if line == '.'
|
89
|
+
line.sub!(/\A\./, '')
|
90
|
+
lines.push line
|
91
|
+
end
|
92
|
+
lines
|
93
|
+
end
|
94
|
+
|
95
|
+
def initialize tra_uri, host
|
96
|
+
@tra_uri = tra_uri
|
97
|
+
@host = host
|
98
|
+
@sock = nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def get_after data_name, time, pos=0
|
102
|
+
open_after(data_name, time, pos) {|t, line, pos|
|
103
|
+
h = LTSV.parse_string line
|
104
|
+
t ||= Time.at(h['_time'].to_i)
|
105
|
+
yield t, h, pos
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def open_after data_name, time, pos=0
|
110
|
+
case @tra_uri.scheme
|
111
|
+
when 'http'
|
112
|
+
http = Net::HTTP.new @tra_uri.host, @tra_uri.port
|
113
|
+
begin
|
114
|
+
url = @tra_uri + "get?h=#{@host}&s=#{data_name}&t=#{time.to_i}"
|
115
|
+
res = http.get url.request_uri
|
116
|
+
res.body.each_line {|line| yield nil, line.chomp, pos}
|
117
|
+
end while(time = res['x-gri-continue'])
|
118
|
+
http.finish
|
119
|
+
when 'tra'
|
120
|
+
sock = sock_connect @tra_uri.host, @tra_uri.port
|
121
|
+
begin
|
122
|
+
query = "h=#{@host}&s=#{data_name}&t=#{time.to_i}&pos=#{pos}"
|
123
|
+
sock.puts "/get #{query}"
|
124
|
+
lines = self.class.tra_gets sock
|
125
|
+
ind = lines.index ''
|
126
|
+
headers = lines.slice!(0, ind+1)
|
127
|
+
if headers.detect {|line| line =~ /x-gri-pos: (\d+)/i}
|
128
|
+
pos = $1.to_i
|
129
|
+
end
|
130
|
+
lines.each {|line| yield nil, line, pos}
|
131
|
+
if headers.detect {|line| line =~ /x-gri-continue: (\d+) (\d+)/i}
|
132
|
+
time = $1.to_i
|
133
|
+
pos = $2.to_i
|
134
|
+
else
|
135
|
+
time = nil
|
136
|
+
end
|
137
|
+
end while time
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def sock_connect host, port
|
142
|
+
@sock ||= TCPSocket.new host, port
|
143
|
+
end
|
144
|
+
|
145
|
+
def close
|
146
|
+
@sock.close rescue nil
|
147
|
+
end
|
148
|
+
|
149
|
+
def get_data_names
|
150
|
+
@tra_uri.path = '/get_data_names'
|
151
|
+
@tra_uri.query = "h=#{@host}"
|
152
|
+
lines = self.class.get_lines @tra_uri
|
153
|
+
lines.inject({}) {|h, line|
|
154
|
+
data_name, interval = line.split /_/
|
155
|
+
h[data_name || ''] = (interval || 300).to_i
|
156
|
+
h
|
157
|
+
}
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/lib/gri/list.rb
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'gri/utils'
|
2
|
+
require 'gri/format_helper'
|
3
|
+
require 'gri/blank'
|
4
|
+
|
5
|
+
module GRI
|
6
|
+
class List
|
7
|
+
include FormatHelper
|
8
|
+
include Utils
|
9
|
+
|
10
|
+
SORT_PROC = {
|
11
|
+
'a'=>proc {|aa, bb| a, = aa; b, = bb
|
12
|
+
(a =~ /\A[\.\d]+$/ and b =~ /\A[\.\d]+$/) ?
|
13
|
+
ipstr2bin(a) <=> ipstr2bin(b) : a <=> b
|
14
|
+
},
|
15
|
+
'l'=>proc {|a, b|
|
16
|
+
(a[1]['sysLocation'] || "\377") <=> (b[1]['sysLocation'] || "\377")
|
17
|
+
},
|
18
|
+
'u'=>Proc.new {|a, b|
|
19
|
+
(a[1]['sysUpTime'].to_i) <=> (b[1]['sysUpTime'].to_i)
|
20
|
+
},
|
21
|
+
'v'=>Proc.new {|a, b|
|
22
|
+
(a[1]['_ver'] || "\377") <=> (b[1]['_ver'] || "\377")
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
def self.ipstr2bin str
|
27
|
+
str.split('.').map {|s|s.to_i}.pack('C4')
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize options={}
|
31
|
+
@options = options
|
32
|
+
@urs = !!(options[:use_regexp_search])
|
33
|
+
end
|
34
|
+
|
35
|
+
def call env
|
36
|
+
req = Rack::Request.new env
|
37
|
+
params = req.params
|
38
|
+
|
39
|
+
dirs = @options[:dirs]
|
40
|
+
sysdb = load_sysdb(dirs) rescue {}
|
41
|
+
|
42
|
+
if params['op'] == 'comp'
|
43
|
+
shash = {}
|
44
|
+
grep_results = grep_graph dirs, sysdb.keys, params
|
45
|
+
for h0 in grep_results.keys.sort
|
46
|
+
for data_name, host, key in grep_results[h0]
|
47
|
+
(shash[data_name] ||= []).push "#{host}_#{key}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
if shash.keys.size == 0
|
51
|
+
url = url_to ''
|
52
|
+
else
|
53
|
+
key, = shash.keys
|
54
|
+
rstr = shash[key].map {|hkey| "r=#{hkey}"}.join('&')
|
55
|
+
query = "?p=#{params['p']}&s=#{key}&#{rstr}"
|
56
|
+
url = url_to query
|
57
|
+
end
|
58
|
+
return [302, {'Location'=>url}, []]
|
59
|
+
end
|
60
|
+
|
61
|
+
ly_ary = [['0', 'none'],
|
62
|
+
['1', 'day'], ['7', 'week'], ['31', 'month'], ['366', 'year']]
|
63
|
+
(ly_ary.assoc(params['ly']) || ly_ary[0])[2] = true
|
64
|
+
sort_ary = [['a', 'hostname'], #['n','sysName'],
|
65
|
+
['l','location'], ['u','uptime'], ['v','version']]
|
66
|
+
(sort_ary.assoc(params['sort']) || sort_ary[0])[2] = true
|
67
|
+
|
68
|
+
@title = 'list'
|
69
|
+
body = render(Grapher.layout) {render template, binding}
|
70
|
+
[200, {'Content-type' => 'text/html'}, [body]]
|
71
|
+
end
|
72
|
+
|
73
|
+
def load_sysdb dirs
|
74
|
+
sysdb = {}
|
75
|
+
for dir in dirs
|
76
|
+
values = LTSV.load_from_file(dir + '/.sysdb/sysdb.txt')
|
77
|
+
values.inject(sysdb) {|h, v| h[v['_host']] = v; h}
|
78
|
+
end
|
79
|
+
sysdb
|
80
|
+
end
|
81
|
+
|
82
|
+
def sysdb_list dirs, sysdb, params
|
83
|
+
hosts = sysdb.keys
|
84
|
+
if params['n'].present? or params['d'].present?
|
85
|
+
grep_results = grep_graph dirs, hosts, params
|
86
|
+
end
|
87
|
+
grep_results ||= {}
|
88
|
+
|
89
|
+
sort_proc = SORT_PROC[params['sort']] || SORT_PROC['a']
|
90
|
+
hlines = []
|
91
|
+
for host, sysinfo in sysdb.sort(&sort_proc)
|
92
|
+
next if params['h'].present? and host !~ mk_regexp(params['h'])
|
93
|
+
next if sysinfo['sysDescr'] and params['sysdescr'] and
|
94
|
+
sysinfo['sysDescr'] !~ mk_regexp(params['sysdescr'])
|
95
|
+
line = format_rowstr host, sysinfo
|
96
|
+
hlines.push [host, line, grep_results[host]]
|
97
|
+
end
|
98
|
+
hlines
|
99
|
+
end
|
100
|
+
|
101
|
+
def mk_regexp str
|
102
|
+
str = @urs ? str.to_s.gsub(/[#]/) {|c| "\\#{c}"} : Regexp.quote(str.to_s)
|
103
|
+
Regexp.new str, Regexp::IGNORECASE
|
104
|
+
end
|
105
|
+
|
106
|
+
def grep_graph dirs, hosts, params
|
107
|
+
re_name = mk_regexp params['n']
|
108
|
+
re_descr = mk_regexp params['d']
|
109
|
+
re_host = mk_regexp params['h']
|
110
|
+
hostres = {}
|
111
|
+
for host in hosts
|
112
|
+
next if params['h'].present? and host !~ re_host
|
113
|
+
dir, h = search_records dirs, host
|
114
|
+
if h
|
115
|
+
for key in h.keys.sort
|
116
|
+
prop = get_prop h[key]
|
117
|
+
next unless re_name === prop[:name]
|
118
|
+
next unless re_descr === (descr = prop[:description] || '')
|
119
|
+
data_name, index = parse_key key
|
120
|
+
(hostres[host] ||= []).push [data_name, host, key,
|
121
|
+
prop[:name], prop[:description]]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
hostres
|
126
|
+
end
|
127
|
+
|
128
|
+
def format_rowstr basename, sysinfo
|
129
|
+
mtime = sysinfo['_mtime'].to_i
|
130
|
+
now = Time.now.to_i
|
131
|
+
if mtime < (now - 24*3600)
|
132
|
+
hostname = "(#{basename})"
|
133
|
+
else
|
134
|
+
hostname = basename
|
135
|
+
end
|
136
|
+
list_format = @options[:list_format] || "%-28_H%-18M %-18V %L"
|
137
|
+
rowstr = list_format.gsub(/(%([-+]?([ \d]+)?(\.\d+)?))(_)?([A-Z%])/) {
|
138
|
+
form = $1 + 's'
|
139
|
+
linkflag = $5
|
140
|
+
case $6
|
141
|
+
when 'H'
|
142
|
+
s = form % hostname
|
143
|
+
when 'L'
|
144
|
+
s = form % sysinfo['sysLocation']
|
145
|
+
when 'M'
|
146
|
+
s = form % sysinfo['_firm']
|
147
|
+
when 'N'
|
148
|
+
s = form % sysinfo['sysName']
|
149
|
+
when 'S'
|
150
|
+
mtime = sysinfo['_mtime'].to_i
|
151
|
+
if mtime > (now - 3600)
|
152
|
+
s = Time.at(mtime).strftime '%H:%M'
|
153
|
+
else
|
154
|
+
s = '?'
|
155
|
+
end
|
156
|
+
s = form % s
|
157
|
+
when 'U'
|
158
|
+
if mtime > (now - 24*3600)
|
159
|
+
ustr = ''#format_uptime sysinfo['sysUpTime']
|
160
|
+
else
|
161
|
+
ustr = ''
|
162
|
+
end
|
163
|
+
s = form % ustr
|
164
|
+
when 'V'
|
165
|
+
s = form % sysinfo['_ver']
|
166
|
+
else
|
167
|
+
s = ''
|
168
|
+
end
|
169
|
+
if linkflag == '_'
|
170
|
+
ss = s.strip
|
171
|
+
s = "<a href=\"#{h url_to(basename)}\">#{h ss}</a>" +
|
172
|
+
' ' * (s.size - ss.size)
|
173
|
+
end
|
174
|
+
s
|
175
|
+
}
|
176
|
+
|
177
|
+
rowstr
|
178
|
+
end
|
179
|
+
|
180
|
+
def template
|
181
|
+
<<'EOS'
|
182
|
+
<% if sysdb -%>
|
183
|
+
|
184
|
+
<% if params['search'] == '1' -%>
|
185
|
+
<form enctype="application/x-www-form-urlencoded" method="get"
|
186
|
+
action="<%=h url_to '' %>">
|
187
|
+
<table>
|
188
|
+
<% for hname, vname in [['Hostname', 'h'], #['sysName', 'sysname'],
|
189
|
+
['sysDescr', 'sysdescr'], ['I/F or Name', 'n'], ['Description', 'd'],] -%>
|
190
|
+
<tr>
|
191
|
+
<td class=text-right><%= hname %> :</td>
|
192
|
+
<td><%= text_field vname, params[vname], 40 %></td>
|
193
|
+
</tr>
|
194
|
+
<% end -%>
|
195
|
+
<tr>
|
196
|
+
<td class=text-right>sort by:</td>
|
197
|
+
<td><%= popup_menu 'sort', 'form-control', *sort_ary %></td>
|
198
|
+
</tr>
|
199
|
+
<tr>
|
200
|
+
<td class=text-right>graph:</td>
|
201
|
+
<td><%= popup_menu 'ly', 'form-control', *ly_ary %></td>
|
202
|
+
</tr>
|
203
|
+
</table>
|
204
|
+
<input type="hidden" name="start" value="<%=h params['start'] %>">
|
205
|
+
<input type="hidden" name="search" value="1">
|
206
|
+
<input class="btn btn-primary btn-sm" type="submit" value="submit">
|
207
|
+
</form>
|
208
|
+
|
209
|
+
<% if params['n'].present? or params['d'].present? -%>
|
210
|
+
<% ary = [['', 'sum'], ['s', 'stack'], ['v', 'overlay']] -%>
|
211
|
+
<% while item = ary.shift -%>
|
212
|
+
<% q = mk_query :op=>'comp', :p=>item[0], :h=>params['h'], :n=>params['n'],
|
213
|
+
:d=>params['d'], :sysdescr=>params['sysdescr'] -%>
|
214
|
+
<a href="<%=h url_to q %>"><%= item[1] %></a>
|
215
|
+
<% if ary.size > 0 then %> | <% end -%>
|
216
|
+
<% end -%>
|
217
|
+
<% end -%>
|
218
|
+
|
219
|
+
<% else -%>
|
220
|
+
<a href="<%= url_to '?search=1'%>">Search</a>
|
221
|
+
<% end -%>
|
222
|
+
|
223
|
+
<pre>
|
224
|
+
<% for host, line, gres in sysdb_list dirs, sysdb, params -%>
|
225
|
+
<span class="line"><%= line %></span>
|
226
|
+
<% if gres -%>
|
227
|
+
<% for data_name, h2, key, name, description in gres -%>
|
228
|
+
<% url = "?r=#{h2}_#{key}" + (params['grp'] ? "&grp=#{params['grp']}" : "") -%>
|
229
|
+
- <a href="<%=h url_to(url) %>"><%=h name %></a> <%= description %>
|
230
|
+
<% unless (ly = params['ly'].to_i).zero? -%>
|
231
|
+
<img src="<%=h url%>&z=s&stime=-<%= ly * 24 * 3600 %>"/><br/>
|
232
|
+
<% end -%>
|
233
|
+
<% end -%>
|
234
|
+
<% end -%>
|
235
|
+
<% end -%>
|
236
|
+
</pre>
|
237
|
+
|
238
|
+
<% end -%>
|
239
|
+
EOS
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
data/lib/gri/log.rb
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Log
|
4
|
+
IOBUF = {}
|
5
|
+
|
6
|
+
class Formatter
|
7
|
+
Format = "%s %s\n"
|
8
|
+
attr_accessor :datetime_format
|
9
|
+
|
10
|
+
def call severity, time, progname, msg
|
11
|
+
tstr = time.strftime("%Y-%m-%d %H:%M:%S")
|
12
|
+
Format % [tstr, msg2str(msg)]
|
13
|
+
end
|
14
|
+
|
15
|
+
def msg2str(msg)
|
16
|
+
case msg
|
17
|
+
when ::String
|
18
|
+
msg
|
19
|
+
when ::Exception
|
20
|
+
"#{ msg.message } (#{ msg.class })\n" <<
|
21
|
+
(msg.backtrace || []).join("\n")
|
22
|
+
else
|
23
|
+
msg.inspect
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class << self
|
29
|
+
attr_accessor :logger
|
30
|
+
end
|
31
|
+
|
32
|
+
module_function
|
33
|
+
|
34
|
+
def init logdev, options={}
|
35
|
+
shift_age = options[:log_shift_age] || 8
|
36
|
+
shift_size = options[:log_shift_size] || 100_000_000
|
37
|
+
logger = Logger.new logdev, shift_age, shift_size
|
38
|
+
logger.formatter = Log::Formatter.new
|
39
|
+
logger.add Logger::INFO, '-'
|
40
|
+
logger = Logger.new logdev
|
41
|
+
logger.formatter = Log::Formatter.new
|
42
|
+
logger.level = {'fatal'=>Logger::FATAL, 'error'=>Logger::ERROR,
|
43
|
+
'warn'=>Logger::WARN, 'info'=>Logger::INFO, 'debug'=>Logger::DEBUG,
|
44
|
+
}[(options[:log_level] || '').downcase] || Logger::INFO
|
45
|
+
Log.logger = logger
|
46
|
+
end
|
47
|
+
|
48
|
+
def open logdev
|
49
|
+
if logdev == '-'
|
50
|
+
logdev = STDOUT
|
51
|
+
end
|
52
|
+
init logdev
|
53
|
+
end
|
54
|
+
|
55
|
+
def close grp=nil
|
56
|
+
if @logger
|
57
|
+
@logger.close
|
58
|
+
else
|
59
|
+
if grp
|
60
|
+
if (io = IOBUF[grp])
|
61
|
+
io.close
|
62
|
+
end
|
63
|
+
else
|
64
|
+
for io in IOBUF.values
|
65
|
+
io.close
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def write grp, str, severity=nil
|
72
|
+
if @logger
|
73
|
+
if severity.kind_of? Symbol
|
74
|
+
severity = @logger.class.const_get severity
|
75
|
+
else
|
76
|
+
severity ||= @logger.class::INFO
|
77
|
+
end
|
78
|
+
begin
|
79
|
+
logger.add severity, str.chomp
|
80
|
+
rescue Logger::Error
|
81
|
+
disable
|
82
|
+
end
|
83
|
+
else
|
84
|
+
io = IOBUF[grp]
|
85
|
+
if io
|
86
|
+
if io.kind_of? File
|
87
|
+
#mtime = io.mtime
|
88
|
+
tstr = Time.now.strftime("%Y-%m-%d %H:%M:%S ")
|
89
|
+
gstr = (grp == :default) ? '' : "#{grp}: "
|
90
|
+
io.print tstr + gstr + str
|
91
|
+
else
|
92
|
+
io.print str
|
93
|
+
io.print "\n" if severity #XXX
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def puts(*args)
|
100
|
+
if args.size >= 2 and args[0].kind_of?(Symbol)
|
101
|
+
grp = args.shift
|
102
|
+
else
|
103
|
+
grp = :default
|
104
|
+
end
|
105
|
+
str = args.join('').chomp + "\n"
|
106
|
+
self.write grp, str
|
107
|
+
end
|
108
|
+
|
109
|
+
def pp(*args)
|
110
|
+
if args.size >= 2 and args[0].kind_of?(Symbol)
|
111
|
+
self.puts args[0], args[1..-1].map {|e| e.inspect}.join(', ')
|
112
|
+
else
|
113
|
+
self.puts args.map {|e| e.inspect}.join(', ')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def debug(*args, &block)
|
118
|
+
write :default, args.first, :DEBUG
|
119
|
+
end
|
120
|
+
def info(*args, &block)
|
121
|
+
write :default, args.first, :INFO
|
122
|
+
end
|
123
|
+
def warn(*args, &block)
|
124
|
+
write :default, args.first, :WARN
|
125
|
+
end
|
126
|
+
def error(*args, &block)
|
127
|
+
write :default, args.first, :ERROR
|
128
|
+
end
|
129
|
+
def fatal(*args, &block)
|
130
|
+
write :default, args.first, :FATAL
|
131
|
+
end
|
132
|
+
|
133
|
+
def null(*args, &block)
|
134
|
+
end
|
135
|
+
|
136
|
+
def disable
|
137
|
+
@logger = nil
|
138
|
+
IOBUF.clear
|
139
|
+
end
|
140
|
+
end
|