sawmill 0.0.2 → 0.0.3

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.
Files changed (33) hide show
  1. data/History.rdoc +17 -0
  2. data/lib/sawmill/entry.rb +17 -1
  3. data/lib/sawmill/entry_processor/build_records.rb +10 -7
  4. data/lib/sawmill/entry_processor/compile_report.rb +115 -0
  5. data/lib/sawmill/entry_processor/conditionals.rb +22 -23
  6. data/lib/sawmill/entry_processor/count_entries.rb +112 -0
  7. data/lib/sawmill/entry_processor/{filter_basic_fields.rb → filter_by_basic_fields.rb} +3 -3
  8. data/lib/sawmill/entry_processor/filter_by_block.rb +96 -0
  9. data/lib/sawmill/entry_processor/format.rb +9 -1
  10. data/lib/sawmill/entry_processor/simple_queue.rb +2 -1
  11. data/lib/sawmill/entry_processor.rb +68 -5
  12. data/lib/sawmill/errors.rb +7 -0
  13. data/lib/sawmill/interface.rb +324 -0
  14. data/lib/sawmill/logger.rb +8 -7
  15. data/lib/sawmill/record.rb +14 -0
  16. data/lib/sawmill/record_processor/compile_report.rb +113 -0
  17. data/lib/sawmill/record_processor/conditionals.rb +12 -13
  18. data/lib/sawmill/record_processor/count_records.rb +84 -0
  19. data/lib/sawmill/record_processor/decompose.rb +2 -2
  20. data/lib/sawmill/record_processor/filter_by_attributes.rb +2 -1
  21. data/lib/sawmill/record_processor/filter_by_block.rb +95 -0
  22. data/lib/sawmill/record_processor/filter_by_record_id.rb +2 -1
  23. data/lib/sawmill/record_processor/format.rb +8 -2
  24. data/lib/sawmill/record_processor/simple_queue.rb +2 -1
  25. data/lib/sawmill/record_processor.rb +69 -5
  26. data/lib/sawmill/rotater/date_based_log_file.rb +8 -8
  27. data/lib/sawmill/rotater/shifting_log_file.rb +7 -6
  28. data/lib/sawmill/util/processor_tools.rb +71 -0
  29. data/lib/sawmill/version.rb +1 -3
  30. data/lib/sawmill.rb +9 -1
  31. data/tests/tc_entry_processors.rb +7 -7
  32. data/tests/tc_reports.rb +101 -0
  33. 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
- # The operation, which can be :set, :append, :remove, :unset
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>:emit_incomplete_records_on_close</tt>::
53
- # When the processor is closed, any records that are still not
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
- @emit_incomplete_records_on_close = opts_[:emit_incomplete_records_on_close]
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 close
139
- if @records && @emit_incomplete_records_on_close
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(FilterBasicFields(:level => :INFO), Format(STDOUT))
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 close
112
- @on_true.close
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(FilterBasicFields(:level => :INFO)), Format(STDOUT))
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 close
162
- @child.close
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(FilterBasicFields(:level => :INFO),
180
- # FilterBasicFields(:progname => 'rails')),
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 close
231
- @children.each{ |forward_| forward_.close }
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(FilterBasicFields(:level => :INFO),
249
- # FilterBasicFields(:progname => 'rails')),
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 close
300
- @children.each{ |forward_| forward_.close }
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(FilterBasicFields(:level => :INFO),
319
- # FilterBasicFields(:progname => 'rails')),
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 close
371
- @children.each{ |forward_| forward_.close }
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(FilterBasicFields(:level => :INFO),
389
- # FilterBasicFields(:progname => 'rails')),
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 close
435
- @children.each{ |forward_| forward_.close }
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 FilterBasicFields < Base
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
- def close
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 close
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
 
@@ -109,8 +109,9 @@ module Sawmill
109
109
  !@closed
110
110
  end
111
111
 
112
- def close
112
+ def finish
113
113
  @closed = true
114
+ nil
114
115
  end
115
116
 
116
117