sawmill 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +17 -0
- data/lib/sawmill/entry.rb +17 -1
- data/lib/sawmill/entry_processor/build_records.rb +10 -7
- data/lib/sawmill/entry_processor/compile_report.rb +115 -0
- data/lib/sawmill/entry_processor/conditionals.rb +22 -23
- data/lib/sawmill/entry_processor/count_entries.rb +112 -0
- data/lib/sawmill/entry_processor/{filter_basic_fields.rb → filter_by_basic_fields.rb} +3 -3
- data/lib/sawmill/entry_processor/filter_by_block.rb +96 -0
- data/lib/sawmill/entry_processor/format.rb +9 -1
- data/lib/sawmill/entry_processor/simple_queue.rb +2 -1
- data/lib/sawmill/entry_processor.rb +68 -5
- data/lib/sawmill/errors.rb +7 -0
- data/lib/sawmill/interface.rb +324 -0
- data/lib/sawmill/logger.rb +8 -7
- data/lib/sawmill/record.rb +14 -0
- data/lib/sawmill/record_processor/compile_report.rb +113 -0
- data/lib/sawmill/record_processor/conditionals.rb +12 -13
- data/lib/sawmill/record_processor/count_records.rb +84 -0
- data/lib/sawmill/record_processor/decompose.rb +2 -2
- data/lib/sawmill/record_processor/filter_by_attributes.rb +2 -1
- data/lib/sawmill/record_processor/filter_by_block.rb +95 -0
- data/lib/sawmill/record_processor/filter_by_record_id.rb +2 -1
- data/lib/sawmill/record_processor/format.rb +8 -2
- data/lib/sawmill/record_processor/simple_queue.rb +2 -1
- data/lib/sawmill/record_processor.rb +69 -5
- data/lib/sawmill/rotater/date_based_log_file.rb +8 -8
- data/lib/sawmill/rotater/shifting_log_file.rb +7 -6
- data/lib/sawmill/util/processor_tools.rb +71 -0
- data/lib/sawmill/version.rb +1 -3
- data/lib/sawmill.rb +9 -1
- data/tests/tc_entry_processors.rb +7 -7
- data/tests/tc_reports.rb +101 -0
- metadata +13 -3
data/History.rdoc
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
=== 0.0.3 / 2009-10-31
|
2
|
+
|
3
|
+
* API CHANGE: Renamed processor close methods to "finish" and introduced return value semantics for passing "final" information back up the processor tree.
|
4
|
+
* API CHANGE: Renamed :dirname options to :basedir on both rotater strategies
|
5
|
+
* API CHANGE: Renamed :filename option to :filepath on ShiftingLogFile
|
6
|
+
* API CHANGE: Renamed :local_timezone option to :local_datestamps on DateBasedLogFile
|
7
|
+
* API CHANGE: Renamed FilterBasicFields to FilterByBasicFields
|
8
|
+
* Added FilterByBlock processors
|
9
|
+
* Added CompileReport processors
|
10
|
+
* Processors can now add custom methods to the processor building DSL.
|
11
|
+
* Added a bunch of convenience methods to the toplevel Sawmill module.
|
12
|
+
* Entries can be truncated at a particular length when formatting.
|
13
|
+
* Records can compute and cache values.
|
14
|
+
* Support length limits when formatting entries.
|
15
|
+
* Fixed a few more bugs related to processors.
|
16
|
+
* More work on the RDocs
|
17
|
+
|
1
18
|
=== 0.0.2 / 2009-10-28
|
2
19
|
|
3
20
|
* Added multi-parser utility.
|
data/lib/sawmill/entry.rb
CHANGED
@@ -103,12 +103,16 @@ module Sawmill
|
|
103
103
|
|
104
104
|
# The log level as a Sawmill::Level object
|
105
105
|
attr_reader :level
|
106
|
+
|
106
107
|
# The timestamp as a Time object
|
107
108
|
attr_reader :timestamp
|
109
|
+
|
108
110
|
# The progname as a string
|
109
111
|
attr_reader :progname
|
112
|
+
|
110
113
|
# The record ID as a string
|
111
114
|
attr_reader :record_id
|
115
|
+
|
112
116
|
# The message as a string
|
113
117
|
attr_reader :message
|
114
118
|
|
@@ -157,10 +161,13 @@ module Sawmill
|
|
157
161
|
|
158
162
|
# The log level as a Sawmill::Level object
|
159
163
|
attr_reader :level
|
164
|
+
|
160
165
|
# The timestamp as a Time object
|
161
166
|
attr_reader :timestamp
|
167
|
+
|
162
168
|
# The progname as a string
|
163
169
|
attr_reader :progname
|
170
|
+
|
164
171
|
# The record ID as a string
|
165
172
|
attr_reader :record_id
|
166
173
|
|
@@ -207,10 +214,13 @@ module Sawmill
|
|
207
214
|
|
208
215
|
# The log level as a Sawmill::Level object
|
209
216
|
attr_reader :level
|
217
|
+
|
210
218
|
# The timestamp as a Time object
|
211
219
|
attr_reader :timestamp
|
220
|
+
|
212
221
|
# The progname as a string
|
213
222
|
attr_reader :progname
|
223
|
+
|
214
224
|
# The record ID as a string
|
215
225
|
attr_reader :record_id
|
216
226
|
|
@@ -263,16 +273,22 @@ module Sawmill
|
|
263
273
|
|
264
274
|
# The log level as a Sawmill::Level object
|
265
275
|
attr_reader :level
|
276
|
+
|
266
277
|
# The timestamp as a Time object
|
267
278
|
attr_reader :timestamp
|
279
|
+
|
268
280
|
# The progname as a string
|
269
281
|
attr_reader :progname
|
282
|
+
|
270
283
|
# The record ID as a string
|
271
284
|
attr_reader :record_id
|
272
|
-
|
285
|
+
|
286
|
+
# The operation, which can currently be :set or :append
|
273
287
|
attr_reader :operation
|
288
|
+
|
274
289
|
# The attribute key as a string
|
275
290
|
attr_reader :key
|
291
|
+
|
276
292
|
# The attribute value as a string
|
277
293
|
attr_reader :value
|
278
294
|
|
@@ -49,15 +49,15 @@ module Sawmill
|
|
49
49
|
#
|
50
50
|
# Recognized options include:
|
51
51
|
#
|
52
|
-
# <tt>:
|
53
|
-
# When the processor is
|
52
|
+
# <tt>:emit_incomplete_records_on_finish</tt>::
|
53
|
+
# When the processor is finished, any records that are still not
|
54
54
|
# complete will be emitted to the record processor anyway, even
|
55
55
|
# in their incomplete state.
|
56
56
|
|
57
57
|
def initialize(processor_, opts_={})
|
58
58
|
@processor = processor_
|
59
59
|
@records = {}
|
60
|
-
@
|
60
|
+
@emit_incomplete_records_on_finish = opts_[:emit_incomplete_records_on_finish]
|
61
61
|
end
|
62
62
|
|
63
63
|
|
@@ -135,11 +135,14 @@ module Sawmill
|
|
135
135
|
end
|
136
136
|
|
137
137
|
|
138
|
-
def
|
139
|
-
if @records
|
140
|
-
emit_incomplete_records
|
138
|
+
def finish
|
139
|
+
if @records
|
140
|
+
emit_incomplete_records if @emit_incomplete_records_on_close
|
141
|
+
@records = nil
|
142
|
+
@processor.finish
|
143
|
+
else
|
144
|
+
nil
|
141
145
|
end
|
142
|
-
@records = nil
|
143
146
|
end
|
144
147
|
|
145
148
|
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill entry processor that generates reports
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2009 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module Sawmill
|
38
|
+
|
39
|
+
|
40
|
+
module EntryProcessor
|
41
|
+
|
42
|
+
|
43
|
+
# This processor collects and formats reports from descendant
|
44
|
+
# entry processors.
|
45
|
+
|
46
|
+
class CompileReport < All
|
47
|
+
|
48
|
+
|
49
|
+
# Create a report collection.
|
50
|
+
#
|
51
|
+
# Recognized options include:
|
52
|
+
#
|
53
|
+
# <tt>:postprocessor</tt>::
|
54
|
+
# Postprocessor proc for individual reports.
|
55
|
+
# See to_postprocess_value.
|
56
|
+
# <tt>:separator</tt>::
|
57
|
+
# Separator string to be inserted between individual reports.
|
58
|
+
# Default is a single newline.
|
59
|
+
# <tt>:header</tt>::
|
60
|
+
# Header string for the final compiled report.
|
61
|
+
# Default is the empty string.
|
62
|
+
# <tt>:footer</tt>::
|
63
|
+
# Footer string for the final compiled report.
|
64
|
+
# Default is the empty string.
|
65
|
+
|
66
|
+
def initialize(*children_)
|
67
|
+
opts_ = children_.last.kind_of?(::Hash) ? children_.pop : {}
|
68
|
+
@postprocessor = opts_[:postprocessor]
|
69
|
+
@separator = opts_[:separator] || "\n"
|
70
|
+
@header = opts_[:header] || ''
|
71
|
+
@footer = opts_[:footer] || ''
|
72
|
+
super(*children_)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Separator string to be inserted between individual reports.
|
77
|
+
attr_accessor :separator
|
78
|
+
|
79
|
+
# Header string for the final compiled report.
|
80
|
+
attr_accessor :header
|
81
|
+
|
82
|
+
# Footer string for the final compiled report.
|
83
|
+
attr_accessor :footer
|
84
|
+
|
85
|
+
|
86
|
+
# Provide a postprocessor block for individual report values.
|
87
|
+
# This block should take a single parameter and return a string
|
88
|
+
# that should be included in the compiled report. It may also
|
89
|
+
# return nil to indicate that the data should not be included.
|
90
|
+
|
91
|
+
def to_postprocess_value(&block_)
|
92
|
+
@postprocessor = block_
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# On finish, this processor calls finish on its descendants, converts
|
97
|
+
# their values into strings and compiles them into a report. It then
|
98
|
+
# returns that report as a string.
|
99
|
+
|
100
|
+
def finish
|
101
|
+
values_ = super || []
|
102
|
+
values_ = [values_] unless values_.kind_of?(::Array)
|
103
|
+
values_.map!{ |val_| @postprocessor.call(val_) } if @postprocessor
|
104
|
+
values_.compact!
|
105
|
+
"#{@header}#{values_.join(@separator)}#{@footer}"
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
end
|
@@ -48,7 +48,7 @@ module Sawmill
|
|
48
48
|
# to STDOUT only if their level is at least INFO:
|
49
49
|
#
|
50
50
|
# processor = Sawmill::EntryProcessor.build do
|
51
|
-
# If(
|
51
|
+
# If(FilterByBasicFields(:level => :INFO), Format(STDOUT))
|
52
52
|
# end
|
53
53
|
|
54
54
|
class If < Base
|
@@ -108,9 +108,8 @@ module Sawmill
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
-
def
|
112
|
-
@on_true
|
113
|
-
@on_false.close if @on_false
|
111
|
+
def finish
|
112
|
+
Util::ProcessorTools.collect_finish_values([@on_true, @on_false])
|
114
113
|
end
|
115
114
|
|
116
115
|
|
@@ -124,7 +123,7 @@ module Sawmill
|
|
124
123
|
# to STDOUT only if their level is NOT at least INFO:
|
125
124
|
#
|
126
125
|
# processor = Sawmill::EntryProcessor.build do
|
127
|
-
# If(Not(
|
126
|
+
# If(Not(FilterByBasicFields(:level => :INFO)), Format(STDOUT))
|
128
127
|
# end
|
129
128
|
|
130
129
|
class Not < Base
|
@@ -158,8 +157,8 @@ module Sawmill
|
|
158
157
|
!@child.unknown_data(entry_)
|
159
158
|
end
|
160
159
|
|
161
|
-
def
|
162
|
-
@child.
|
160
|
+
def finish
|
161
|
+
@child.finish
|
163
162
|
end
|
164
163
|
|
165
164
|
|
@@ -176,8 +175,8 @@ module Sawmill
|
|
176
175
|
# is "rails":
|
177
176
|
#
|
178
177
|
# processor = Sawmill::EntryProcessor.build do
|
179
|
-
# If(And(
|
180
|
-
#
|
178
|
+
# If(And(FilterByBasicFields(:level => :INFO),
|
179
|
+
# FilterByBasicFields(:progname => 'rails')),
|
181
180
|
# Format(STDOUT))
|
182
181
|
# end
|
183
182
|
|
@@ -227,8 +226,8 @@ module Sawmill
|
|
227
226
|
true
|
228
227
|
end
|
229
228
|
|
230
|
-
def
|
231
|
-
@children
|
229
|
+
def finish
|
230
|
+
Util::ProcessorTools.collect_finish_values(@children)
|
232
231
|
end
|
233
232
|
|
234
233
|
|
@@ -245,8 +244,8 @@ module Sawmill
|
|
245
244
|
# "rails":
|
246
245
|
#
|
247
246
|
# processor = Sawmill::EntryProcessor.build do
|
248
|
-
# If(Or(
|
249
|
-
#
|
247
|
+
# If(Or(FilterByBasicFields(:level => :INFO),
|
248
|
+
# FilterByBasicFields(:progname => 'rails')),
|
250
249
|
# Format(STDOUT))
|
251
250
|
# end
|
252
251
|
|
@@ -296,8 +295,8 @@ module Sawmill
|
|
296
295
|
false
|
297
296
|
end
|
298
297
|
|
299
|
-
def
|
300
|
-
@children
|
298
|
+
def finish
|
299
|
+
Util::ProcessorTools.collect_finish_values(@children)
|
301
300
|
end
|
302
301
|
|
303
302
|
|
@@ -315,8 +314,8 @@ module Sawmill
|
|
315
314
|
# "rails":
|
316
315
|
#
|
317
316
|
# processor = Sawmill::EntryProcessor.build do
|
318
|
-
# If(All(
|
319
|
-
#
|
317
|
+
# If(All(FilterByBasicFields(:level => :INFO),
|
318
|
+
# FilterByBasicFields(:progname => 'rails')),
|
320
319
|
# Format(STDOUT))
|
321
320
|
# end
|
322
321
|
#
|
@@ -367,8 +366,8 @@ module Sawmill
|
|
367
366
|
end
|
368
367
|
end
|
369
368
|
|
370
|
-
def
|
371
|
-
@children
|
369
|
+
def finish
|
370
|
+
Util::ProcessorTools.collect_finish_values(@children)
|
372
371
|
end
|
373
372
|
|
374
373
|
|
@@ -385,8 +384,8 @@ module Sawmill
|
|
385
384
|
# "rails":
|
386
385
|
#
|
387
386
|
# processor = Sawmill::EntryProcessor.build do
|
388
|
-
# If(Any(
|
389
|
-
#
|
387
|
+
# If(Any(FilterByBasicFields(:level => :INFO),
|
388
|
+
# FilterByBasicFields(:progname => 'rails')),
|
390
389
|
# Format(STDOUT))
|
391
390
|
# end
|
392
391
|
|
@@ -431,8 +430,8 @@ module Sawmill
|
|
431
430
|
end
|
432
431
|
end
|
433
432
|
|
434
|
-
def
|
435
|
-
@children
|
433
|
+
def finish
|
434
|
+
Util::ProcessorTools.collect_finish_values(@children)
|
436
435
|
end
|
437
436
|
|
438
437
|
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill entry processor that generates reports
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2009 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module Sawmill
|
38
|
+
|
39
|
+
module EntryProcessor
|
40
|
+
|
41
|
+
|
42
|
+
# This processor reports the number of entries processed.
|
43
|
+
|
44
|
+
class CountEntries < Base
|
45
|
+
|
46
|
+
|
47
|
+
# Create a count-entries report.
|
48
|
+
#
|
49
|
+
# Recognized options include:
|
50
|
+
#
|
51
|
+
# <tt>:label</tt>::
|
52
|
+
# Label to use for the report.
|
53
|
+
# If provided, the report is returned as a string of the form
|
54
|
+
# "#{label}#{value}"
|
55
|
+
# If set to nil or absent, the report is returned as an integer.
|
56
|
+
# <tt>:omit_unknown_data</tt>::
|
57
|
+
# If set to true, omits unknown_data from the count.
|
58
|
+
# Default is false.
|
59
|
+
# <tt>:omit_attributes</tt>::
|
60
|
+
# If set to true, omits attributes from the count.
|
61
|
+
# Default is false.
|
62
|
+
# <tt>:omit_record_delimiters</tt>::
|
63
|
+
# If set to true, omits begin_record and end_record from the count.
|
64
|
+
# Default is false.
|
65
|
+
|
66
|
+
def initialize(opts_={})
|
67
|
+
@label = opts_[:label]
|
68
|
+
@omit_unknown_data = opts_[:omit_unknown_data]
|
69
|
+
@omit_attributes = opts_[:omit_attributes]
|
70
|
+
@omit_record_delimiters = opts_[:omit_record_delimiters]
|
71
|
+
@finished = false
|
72
|
+
@count = 0
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def begin_record(entry_)
|
77
|
+
@count += 1 unless @finished || @omit_record_delimiters
|
78
|
+
true
|
79
|
+
end
|
80
|
+
|
81
|
+
def end_record(entry_)
|
82
|
+
@count += 1 unless @finished || @omit_record_delimiters
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
def message(entry_)
|
87
|
+
@count += 1 unless @finished
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def attribute(entry_)
|
92
|
+
@count += 1 unless @finished || @omit_attributes
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
def unknown_data(entry_)
|
97
|
+
@count += 1 unless @finished || @omit_unknown_data
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
def finish
|
102
|
+
@finished = true
|
103
|
+
@label ? "#{@label}#{@count}" : @count
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
@@ -45,7 +45,7 @@ module Sawmill
|
|
45
45
|
# on the filter result. Use this in conjunction with an If processor to
|
46
46
|
# actually perform other actions based on the result.
|
47
47
|
|
48
|
-
class
|
48
|
+
class FilterByBasicFields < Base
|
49
49
|
|
50
50
|
|
51
51
|
# Create a new filter.
|
@@ -108,8 +108,8 @@ module Sawmill
|
|
108
108
|
@accept_unknown
|
109
109
|
end
|
110
110
|
|
111
|
-
|
112
|
-
|
111
|
+
def finish
|
112
|
+
nil
|
113
113
|
end
|
114
114
|
|
115
115
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill entry processor that calls a block
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2009 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module Sawmill
|
38
|
+
|
39
|
+
module EntryProcessor
|
40
|
+
|
41
|
+
|
42
|
+
# A entry filter that calls a block to perform its check.
|
43
|
+
#
|
44
|
+
# This is a boolean processor, so it merely returns true or false based
|
45
|
+
# on the filter result. Use this in conjunction with an If processor to
|
46
|
+
# actually perform other actions based on the result.
|
47
|
+
|
48
|
+
class FilterByBlock < Base
|
49
|
+
|
50
|
+
|
51
|
+
# Create a new filter. Provide the block, which should take an entry
|
52
|
+
# object as the parameter and return a boolean.
|
53
|
+
|
54
|
+
def initialize(&block_)
|
55
|
+
to_filter_entry(&block_)
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# Provide a block to filter entries. It should take an entry object
|
60
|
+
# as the parameter, and return a boolean.
|
61
|
+
|
62
|
+
def to_filter_entry(&block_)
|
63
|
+
@block = block_ || Proc.new{ |entry_| false }
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def begin_record(entry_)
|
68
|
+
@block.call(entry_)
|
69
|
+
end
|
70
|
+
|
71
|
+
def end_record(entry_)
|
72
|
+
@block.call(entry_)
|
73
|
+
end
|
74
|
+
|
75
|
+
def message(entry_)
|
76
|
+
@block.call(entry_)
|
77
|
+
end
|
78
|
+
|
79
|
+
def attribute(entry_)
|
80
|
+
@block.call(entry_)
|
81
|
+
end
|
82
|
+
|
83
|
+
def unknown_data(entry_)
|
84
|
+
@block.call(entry_)
|
85
|
+
end
|
86
|
+
|
87
|
+
def finish
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -65,6 +65,9 @@ module Sawmill
|
|
65
65
|
# <tt>:iso_8601_time</tt>::
|
66
66
|
# If true, outputs time in strict ISO 8601 format.
|
67
67
|
# If false (the default), outputs a slightly more readable format.
|
68
|
+
# <tt>:length_limit</tt>::
|
69
|
+
# Limit to the entry length. Entries are truncated to this length
|
70
|
+
# when written. If not specified, entries are not truncated.
|
68
71
|
|
69
72
|
def initialize(destination_, opts_={})
|
70
73
|
if destination_.kind_of?(Rotater)
|
@@ -83,6 +86,7 @@ module Sawmill
|
|
83
86
|
@usec_factor = 1
|
84
87
|
(6 - @fractional_second_digits).times{ @usec_factor *= 10 }
|
85
88
|
@level_width = opts_[:level_width]
|
89
|
+
@length_limit = opts_[:length_limit]
|
86
90
|
end
|
87
91
|
|
88
92
|
|
@@ -143,7 +147,7 @@ module Sawmill
|
|
143
147
|
true
|
144
148
|
end
|
145
149
|
|
146
|
-
def
|
150
|
+
def finish
|
147
151
|
if @rotater
|
148
152
|
@default_channel.close
|
149
153
|
@channels.values.each{ |channel_| channel_.close }
|
@@ -152,6 +156,7 @@ module Sawmill
|
|
152
156
|
@io.close
|
153
157
|
@io = nil
|
154
158
|
end
|
159
|
+
nil
|
155
160
|
end
|
156
161
|
|
157
162
|
private
|
@@ -211,6 +216,9 @@ module Sawmill
|
|
211
216
|
end
|
212
217
|
levelstr_ = entry_.level.name.to_s
|
213
218
|
levelstr_ = levelstr_.rjust(@level_width) if @level_width
|
219
|
+
if @length_limit && @length_limit < str_.length
|
220
|
+
str_ = str_[0, @length_limit] + "... (and #{str_.length-@length_limit} more characters) ..."
|
221
|
+
end
|
214
222
|
"[#{levelstr_} #{timestr_} #{entry_.progname}#{id_} #{marker_}] #{str_}\n"
|
215
223
|
end
|
216
224
|
|