riel 1.1.2 → 1.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,251 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+ #
4
+ # = log.rb
5
+ #
6
+ # Logging Module
7
+ #
8
+ # Author:: Jeff Pace <jpace@incava.org>
9
+ # Documentation:: Author
10
+ #
11
+
12
+ require 'riel/ansicolor'
13
+ require 'riel/log/logger'
14
+ require 'riel/log/severity'
15
+
16
+ #
17
+ # == Log
18
+ #
19
+ # Very minimal logging output. If verbose is set, this displays the method and
20
+ # line number whence called. It can be a mixin to a class, which displays the
21
+ # class and method from where it called. If not in a class, it displays only the
22
+ # method.
23
+ #
24
+ # Remember: all kids love log.
25
+ #
26
+ # == Examples
27
+ #
28
+ # See the unit tests in log_test.rb
29
+ #
30
+ # == Usage
31
+ #
32
+ # The most general usage is simply to call:
33
+ #
34
+ # Log.log "some message"
35
+ #
36
+ # That will simply log the given message.
37
+ #
38
+ # class YourClass
39
+ # include Loggable
40
+ #
41
+ # def some_method(...)
42
+ # log "my message"
43
+ #
44
+ # That will log from the given class and method, showing the line number from
45
+ # which the logger was called.
46
+ #
47
+ # def another_method(...)
48
+ # stack "my message"
49
+ #
50
+ # That will produce a stack trace from the given location.
51
+ #
52
+
53
+ module RIEL
54
+ class Log
55
+ $LOGGING_LEVEL = nil
56
+
57
+ include Log::Severity
58
+
59
+ # by default, class methods delegate to a single app-wide log.
60
+
61
+ @@log = Logger.new
62
+
63
+ # Returns the logger of the log. A class method delegating to an instance
64
+ # method ... not so good. But temporary.
65
+ def self.logger
66
+ @@log
67
+ end
68
+
69
+ def self.method_missing meth, *args, &blk
70
+ if code = ANSIColor::ATTRIBUTES[meth.to_s]
71
+ add_color_method meth.to_s, code
72
+ send meth, *args, &blk
73
+ else
74
+ super
75
+ end
76
+ end
77
+
78
+ def self.add_color_method color, code
79
+ instmeth = Array.new
80
+ instmeth << "def #{color} msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk"
81
+ instmeth << " log(\"\\e[#{code}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
82
+ instmeth << "end"
83
+ instance_eval instmeth.join("\n")
84
+
85
+ clsmeth = Array.new
86
+ clsmeth << "def #{color} msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk"
87
+ clsmeth << " logger.#{color}(\"\\e[#{code}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
88
+ clsmeth << "end"
89
+
90
+ class_eval clsmeth.join("\n")
91
+ end
92
+
93
+ if false
94
+ ANSIColor::ATTRIBUTES.sort.each do |attr|
95
+ methname = attr[0]
96
+
97
+ instmeth = Array.new
98
+ instmeth << "def #{methname}(msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk)"
99
+ instmeth << " log(\"\\e[#{attr[1]}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
100
+ instmeth << "end"
101
+ instance_eval instmeth.join("\n")
102
+
103
+ clsmeth = Array.new
104
+ clsmeth << "def #{methname}(msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk)"
105
+ clsmeth << " logger.#{methname}(\"\\e[#{attr[1]}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
106
+ clsmeth << "end"
107
+
108
+ class_eval clsmeth.join("\n")
109
+ end
110
+ end
111
+
112
+ def self.set_default_widths
113
+ logger.set_default_widths
114
+ end
115
+
116
+ def self.verbose
117
+ logger.verbose
118
+ end
119
+
120
+ def self.verbose= v
121
+ logger.verbose = v && v != 0 ? DEBUG : FATAL
122
+ end
123
+
124
+ def self.level= lvl
125
+ logger.level = lvl
126
+ end
127
+
128
+ def self.quiet
129
+ logger.quiet
130
+ end
131
+
132
+ def self.quiet= q
133
+ logger.quiet = q
134
+ end
135
+
136
+ def self.format
137
+ logger.format
138
+ end
139
+
140
+ def self.format= fmt
141
+ logger.format = fmt
142
+ end
143
+
144
+ # Assigns output to the given stream.
145
+ def self.output= io
146
+ logger.output = io
147
+ end
148
+
149
+ def self.output
150
+ logger.output
151
+ end
152
+
153
+ # sets whether to colorize the entire line, or just the message.
154
+ def self.colorize_line= col
155
+ logger.colorize_line = col
156
+ end
157
+
158
+ def self.colorize_line
159
+ logger.colorize_line
160
+ end
161
+
162
+ # Assigns output to a file with the given name. Returns the file; client
163
+ # is responsible for closing it.
164
+ def self.outfile= fname
165
+ logger.outfile = fname
166
+ end
167
+
168
+ def self.outfile
169
+ logger.outfile
170
+ end
171
+
172
+ # Creates a printf format for the given widths, for aligning output.
173
+ def self.set_widths file_width, line_width, func_width
174
+ logger.set_widths file_width, line_width, func_width
175
+ end
176
+
177
+ def self.ignore_file fname
178
+ logger.ignore_file fname
179
+ end
180
+
181
+ def self.ignore_method methname
182
+ logger.ignored_method methname
183
+ end
184
+
185
+ def self.ignore_class classname
186
+ logger.ignored_class classname
187
+ end
188
+
189
+ def self.log_file fname
190
+ logger.log_file fname
191
+ end
192
+
193
+ def self.log_method methname
194
+ logger.log_method methname
195
+ end
196
+
197
+ def self.log_class classname
198
+ logger.log_class classname
199
+ end
200
+
201
+ def self.debug msg = "", depth = 1, &blk
202
+ logger.log msg, DEBUG, depth + 1, &blk
203
+ end
204
+
205
+ def self.info msg = "", depth = 1, &blk
206
+ logger.log msg, INFO, depth + 1, &blk
207
+ end
208
+
209
+ def self.fatal msg = "", depth = 1, &blk
210
+ logger.log msg, FATAL, depth + 1, &blk
211
+ end
212
+
213
+ def self.log msg = "", lvl = DEBUG, depth = 1, cname = nil, &blk
214
+ logger.log msg, lvl, depth + 1, cname, &blk
215
+ end
216
+
217
+ def self.stack msg = "", lvl = DEBUG, depth = 1, cname = nil, &blk
218
+ logger.stack msg, lvl, depth + 1, cname, &blk
219
+ end
220
+
221
+ def self.warn msg = "", depth = 1, &blk
222
+ if verbose
223
+ logger.log msg, WARN, depth + 1, &blk
224
+ else
225
+ $stderr.puts "WARNING: " + msg
226
+ end
227
+ end
228
+
229
+ def self.error msg = "", depth = 1, &blk
230
+ if verbose
231
+ logger.log msg, ERROR, depth + 1, &blk
232
+ else
233
+ $stderr.puts "ERROR: " + msg
234
+ end
235
+ end
236
+
237
+ def self.write msg, depth = 1, cname = nil, &blk
238
+ if verbose
239
+ stack msg, Log::WARN, depth + 1, cname, &blk
240
+ elsif quiet
241
+ # nothing
242
+ else
243
+ $stderr.puts msg
244
+ end
245
+ end
246
+
247
+ def self.set_color lvl, color
248
+ logger.set_color lvl, color
249
+ end
250
+ end
251
+ end
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+ #
4
+ # = log.rb
5
+ #
6
+ # Logging Module
7
+ #
8
+ # Author:: Jeff Pace <jpace@incava.org>
9
+ # Documentation:: Author
10
+ #
11
+
12
+ require 'riel/log/log'
13
+
14
+ #
15
+ # == Loggable
16
+ #
17
+ # Including this module in a class gives access to the logger methods.
18
+ #
19
+ # == Examples
20
+ #
21
+ # See the unit tests in log_test.rb
22
+ #
23
+ # == Usage
24
+ #
25
+ # class YourClass
26
+ # include Loggable
27
+ #
28
+ # def some_method(...)
29
+ # log "my message"
30
+ #
31
+ # That will log from the given class and method, showing the line number from
32
+ # which the logger was called.
33
+ #
34
+ # def another_method(...)
35
+ # stack "my message"
36
+ #
37
+ # That will produce a stack trace from the given location.
38
+ #
39
+
40
+ module RIEL
41
+ module Loggable
42
+ # Logs the given message, including the class whence invoked.
43
+ def log msg = "", lvl = Log::DEBUG, depth = 1, &blk
44
+ Log.log msg, lvl, depth + 1, self.class.to_s, &blk
45
+ end
46
+
47
+ def debug msg = "", depth = 1, &blk
48
+ Log.log msg, Log::DEBUG, depth + 1, self.class.to_s, &blk
49
+ end
50
+
51
+ def info msg = "", depth = 1, &blk
52
+ Log.log msg, Log::INFO, depth + 1, self.class.to_s, &blk
53
+ end
54
+
55
+ def warn msg = "", depth = 1, &blk
56
+ Log.log msg, Log::WARN, depth + 1, self.class.to_s, &blk
57
+ end
58
+
59
+ def error msg = "", depth = 1, &blk
60
+ Log.log msg, Log::ERROR, depth + 1, self.class.to_s, &blk
61
+ end
62
+
63
+ def fatal msg = "", depth = 1, &blk
64
+ Log.log msg, Log::FATAL, depth + 1, self.class.to_s, &blk
65
+ end
66
+
67
+ def stack msg = "", lvl = Log::DEBUG, depth = 1, &blk
68
+ Log.stack msg, lvl, depth + 1, self.class.to_s, &blk
69
+ end
70
+
71
+ def write msg = "", depth = 1, &blk
72
+ Log.write msg, depth + 1, self.class.to_s, &blk
73
+ end
74
+
75
+ def method_missing meth, *args, &blk
76
+ if ANSIColor::ATTRIBUTES[meth.to_s]
77
+ add_color_method meth.to_s
78
+ send meth, *args, &blk
79
+ else
80
+ super
81
+ end
82
+ end
83
+
84
+ def add_color_method color
85
+ meth = Array.new
86
+ meth << "def #{color} msg = \"\", lvl = Log::DEBUG, depth = 1, &blk"
87
+ meth << " Log.#{color} msg, lvl, depth + 1, self.class.to_s, &blk"
88
+ meth << "end"
89
+ self.class.module_eval meth.join("\n")
90
+ end
91
+
92
+ if false
93
+ ANSIColor::ATTRIBUTES.sort.each do |attr|
94
+ methname = attr[0]
95
+ meth = Array.new
96
+ meth << "def #{methname} msg = \"\", lvl = Log::DEBUG, depth = 1, &blk"
97
+ meth << " Log.#{methname} msg, lvl, depth + 1, self.class.to_s, &blk"
98
+ meth << "end"
99
+ module_eval meth.join("\n")
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,297 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+ #
4
+ # = logger.rb
5
+ #
6
+ # Logging Module
7
+ #
8
+ # Author:: Jeff Pace <jpace@incava.org>
9
+ # Documentation:: Author
10
+ #
11
+
12
+ require 'riel/ansicolor'
13
+ require 'riel/log/severity'
14
+
15
+ #
16
+ # == Logger
17
+ #
18
+ # This class logs messages. You probably don't want to use this directly; Log is
19
+ # the class containing the necessary class methods.
20
+ #
21
+ # == Examples
22
+ #
23
+ # See the unit tests in log_test.rb
24
+ #
25
+
26
+ module RIEL
27
+ class Logger
28
+ $LOGGING_LEVEL = nil
29
+
30
+ attr_accessor :quiet
31
+ attr_accessor :output
32
+ attr_accessor :colorize_line
33
+ attr_accessor :level
34
+ attr_accessor :ignored_files
35
+ attr_accessor :ignored_methods
36
+ attr_accessor :ignored_classes
37
+ attr_accessor :trim
38
+
39
+ include Log::Severity
40
+
41
+ FRAME_RE = Regexp.new('(.*):(\d+)(?::in \`(.*)\')?')
42
+
43
+ def initialize
44
+ set_defaults
45
+ end
46
+
47
+ def verbose= v
48
+ @level = case v
49
+ when TrueClass
50
+ DEBUG
51
+ when FalseClass
52
+ FATAL
53
+ when Integer
54
+ v
55
+ end
56
+ end
57
+
58
+ def set_defaults
59
+ $LOGGING_LEVEL = @level = FATAL
60
+ @ignored_files = Hash.new
61
+ @ignored_methods = Hash.new
62
+ @ignored_classes = Hash.new
63
+ @width = 0
64
+ @output = $stdout
65
+ @colors = Array.new
66
+ @colorize_line = false
67
+ @quiet = false
68
+ @trim = true
69
+
70
+ set_default_widths
71
+ end
72
+
73
+ def set_default_widths
74
+ set_widths(-25, 4, -20)
75
+ end
76
+
77
+ def verbose
78
+ level <= DEBUG
79
+ end
80
+
81
+ # Assigns output to a file with the given name. Returns the file; client
82
+ # is responsible for closing it.
83
+ def outfile= f
84
+ @output = f.kind_of?(IO) ? f : File.new(f, "w")
85
+ end
86
+
87
+ # Creates a printf format for the given widths, for aligning output. To lead
88
+ # lines with zeros (e.g., "00317") the line_width argument must be a string,
89
+ # not an integer.
90
+ def set_widths file_width, line_width, func_width
91
+ @file_width = file_width
92
+ @line_width = line_width
93
+ @function_width = func_width
94
+
95
+ @format = "[%#{file_width}s:%#{line_width}d] {%#{func_width}s}"
96
+ end
97
+
98
+ def ignore_file fname
99
+ ignored_files[fname] = true
100
+ end
101
+
102
+ def ignore_method methname
103
+ ignored_methods[methname] = true
104
+ end
105
+
106
+ def ignore_class classname
107
+ ignored_classes[classname] = true
108
+ end
109
+
110
+ def log_file fname
111
+ ignored_files.delete fname
112
+ end
113
+
114
+ def log_method methname
115
+ ignored_methods.delete methname
116
+ end
117
+
118
+ def log_class classname
119
+ ignored_classes.delete classname
120
+ end
121
+
122
+ def debug msg = "", depth = 1, &blk
123
+ log msg, DEBUG, depth + 1, &blk
124
+ end
125
+
126
+ def info msg = "", depth = 1, &blk
127
+ log msg, INFO, depth + 1, &blk
128
+ end
129
+
130
+ def warn msg = "", depth = 1, &blk
131
+ log msg, WARN, depth + 1, &blk
132
+ end
133
+
134
+ def error msg = "", depth = 1, &blk
135
+ log msg, ERROR, depth + 1, &blk
136
+ end
137
+
138
+ def fatal msg = "", depth = 1, &blk
139
+ log msg, FATAL, depth + 1, &blk
140
+ end
141
+
142
+ # Logs the given message.
143
+ def log msg = "", lvl = DEBUG, depth = 1, cname = nil, &blk
144
+ if lvl >= level
145
+ frame = nil
146
+
147
+ stk = caller 0
148
+ stk.reverse.each_with_index do |frm, idx|
149
+ if frm.index(%r{riel/log/log.*:\d+:in\b})
150
+ break
151
+ else
152
+ frame = frm
153
+ end
154
+ end
155
+
156
+ print_stack_frame frame, cname, msg, lvl, &blk
157
+ end
158
+ end
159
+
160
+ # Shows the current stack.
161
+ def stack msg = "", lvl = DEBUG, depth = 1, cname = nil, &blk
162
+ if lvl >= level
163
+ stk = caller depth
164
+ for frame in stk
165
+ print_stack_frame frame, cname, msg, lvl, &blk
166
+ msg = ""
167
+ end
168
+ end
169
+ end
170
+
171
+ def print_stack_frame frame, cname, msg, lvl, &blk
172
+ md = FRAME_RE.match frame
173
+ file, line, func = md[1], md[2], (md[3] || "")
174
+ # file.sub!(/.*\//, "")
175
+
176
+ if cname
177
+ func = cname + "#" + func
178
+ end
179
+
180
+ if ignored_files[file] || (cname && ignored_classes[cname]) || ignored_methods[func]
181
+ # skip this one.
182
+ else
183
+ print_formatted(file, line, func, msg, lvl, &blk)
184
+ end
185
+ end
186
+
187
+ def trim_left str, maxlen
188
+ str[0 ... maxlen.to_i.abs]
189
+ end
190
+
191
+ def trim_right str, maxlen
192
+ mxln = maxlen.abs
193
+
194
+ # magic number 3 for the ellipses ...
195
+
196
+ if str.length > mxln
197
+ path = str.split('/')
198
+ newstr = "..."
199
+ path.reverse.each do |element|
200
+ if newstr.length + element.length > mxln
201
+ while newstr.length < mxln
202
+ newstr.insert 0, " "
203
+ end
204
+ return newstr
205
+ else
206
+ if newstr.length > 3
207
+ newstr.insert 3, "/"
208
+ end
209
+ newstr.insert 3, element
210
+ end
211
+ end
212
+ newstr
213
+ else
214
+ str
215
+ end
216
+ end
217
+
218
+ def print_formatted file, line, func, msg, lvl, &blk
219
+ if trim
220
+ file = trim_right file, @file_width
221
+ line = trim_left line, @line_width
222
+ func = trim_left func, @function_width
223
+ end
224
+
225
+ hdr = sprintf @format, file, line, func
226
+ print hdr, msg, lvl, &blk
227
+ end
228
+
229
+ def print hdr, msg, lvl, &blk
230
+ if blk
231
+ x = blk.call
232
+ if x.kind_of? String
233
+ msg = x
234
+ else
235
+ return
236
+ end
237
+ end
238
+
239
+ if @colors[lvl]
240
+ if colorize_line
241
+ @output.puts @colors[lvl] + hdr + " " + msg.to_s.chomp + ANSIColor.reset
242
+ else
243
+ @output.puts hdr + " " + @colors[lvl] + msg.to_s.chomp + ANSIColor.reset
244
+ end
245
+ else
246
+ @output.puts hdr + " " + msg.to_s.chomp
247
+ end
248
+ end
249
+
250
+ def set_color lvl, color
251
+ @colors[lvl] = ANSIColor::code color
252
+ end
253
+
254
+ def self.method_missing(meth, *args, &blk)
255
+ if code = ANSIColor::ATTRIBUTES[meth.to_s]
256
+ add_color_method meth.to_s, code
257
+ send meth, *args, &blk
258
+ else
259
+ super
260
+ end
261
+ end
262
+
263
+ def self.add_color_method color, code
264
+ instmeth = Array.new
265
+ instmeth << "def #{color}(msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk)"
266
+ instmeth << " log(\"\\e[#{code}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
267
+ instmeth << "end"
268
+ instance_eval instmeth.join("\n")
269
+
270
+ clsmeth = Array.new
271
+ clsmeth << "def #{color}(msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk)"
272
+ clsmeth << " logger.#{color}(\"\\e[#{code}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
273
+ clsmeth << "end"
274
+
275
+ class_eval clsmeth.join("\n")
276
+ end
277
+
278
+ if false
279
+ ANSIColor::ATTRIBUTES.sort.each do |attr|
280
+ methname = attr[0]
281
+
282
+ instmeth = Array.new
283
+ instmeth << "def #{methname}(msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk)"
284
+ instmeth << " log(\"\\e[#{attr[1]}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
285
+ instmeth << "end"
286
+ instance_eval instmeth.join("\n")
287
+
288
+ clsmeth = Array.new
289
+ clsmeth << "def #{methname}(msg = \"\", lvl = DEBUG, depth = 1, cname = nil, &blk)"
290
+ clsmeth << " logger.#{methname}(\"\\e[#{attr[1]}m\#{msg\}\\e[0m\", lvl, depth + 1, cname, &blk)"
291
+ clsmeth << "end"
292
+
293
+ class_eval clsmeth.join("\n")
294
+ end
295
+ end
296
+ end
297
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- ruby -*-
3
+ #
4
+ # = severity.rb
5
+ #
6
+ # Logging Module
7
+ #
8
+ # Author:: Jeff Pace <jpace@incava.org>
9
+ # Documentation:: Author
10
+ #
11
+
12
+ module RIEL
13
+ class Log
14
+ module Severity
15
+ DEBUG = 0
16
+ INFO = 1
17
+ WARN = 2
18
+ ERROR = 3
19
+ FATAL = 4
20
+ end
21
+ end
22
+ end