sawmill 0.0.1
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.
- data/History.rdoc +3 -0
- data/README.rdoc +81 -0
- data/Rakefile +147 -0
- data/lib/sawmill/entry.rb +307 -0
- data/lib/sawmill/entry_classifier.rb +75 -0
- data/lib/sawmill/entry_processor/build_records.rb +157 -0
- data/lib/sawmill/entry_processor/conditionals.rb +444 -0
- data/lib/sawmill/entry_processor/filter_basic_fields.rb +145 -0
- data/lib/sawmill/entry_processor/format.rb +228 -0
- data/lib/sawmill/entry_processor/simple_queue.rb +116 -0
- data/lib/sawmill/entry_processor.rb +158 -0
- data/lib/sawmill/errors.rb +66 -0
- data/lib/sawmill/level.rb +264 -0
- data/lib/sawmill/log_record_middleware.rb +93 -0
- data/lib/sawmill/logger.rb +373 -0
- data/lib/sawmill/parser.rb +181 -0
- data/lib/sawmill/record.rb +255 -0
- data/lib/sawmill/record_processor/conditionals.rb +330 -0
- data/lib/sawmill/record_processor/decompose.rb +75 -0
- data/lib/sawmill/record_processor/filter_by_attributes.rb +87 -0
- data/lib/sawmill/record_processor/filter_by_record_id.rb +77 -0
- data/lib/sawmill/record_processor/format.rb +88 -0
- data/lib/sawmill/record_processor/simple_queue.rb +117 -0
- data/lib/sawmill/record_processor.rb +137 -0
- data/lib/sawmill/rotater/base.rb +90 -0
- data/lib/sawmill/rotater/date_based_log_file.rb +145 -0
- data/lib/sawmill/rotater/shifting_log_file.rb +166 -0
- data/lib/sawmill/rotater.rb +236 -0
- data/lib/sawmill/util/queue.rb +138 -0
- data/lib/sawmill/version.rb +47 -0
- data/lib/sawmill.rb +78 -0
- data/tests/tc_entry_processors.rb +138 -0
- data/tests/tc_formatter_parser.rb +144 -0
- data/tests/tc_levels.rb +118 -0
- data/tests/tc_logger.rb +315 -0
- data/tests/tc_record_processors.rb +117 -0
- data/tests/tc_records.rb +206 -0
- metadata +116 -0
@@ -0,0 +1,157 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill entry processor that builds log records
|
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
|
+
# An entry processor that builds log records from a stream of entries,
|
43
|
+
# and passes those log records to the given record processor.
|
44
|
+
|
45
|
+
class BuildRecords < Base
|
46
|
+
|
47
|
+
|
48
|
+
# Create record builder emitting to the given record processor.
|
49
|
+
#
|
50
|
+
# Recognized options include:
|
51
|
+
#
|
52
|
+
# <tt>:emit_incomplete_records_on_close</tt>::
|
53
|
+
# When the processor is closed, any records that are still not
|
54
|
+
# complete will be emitted to the record processor anyway, even
|
55
|
+
# in their incomplete state.
|
56
|
+
|
57
|
+
def initialize(processor_, opts_={})
|
58
|
+
@processor = processor_
|
59
|
+
@records = {}
|
60
|
+
@emit_incomplete_records_on_close = opts_[:emit_incomplete_records_on_close]
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
# Emit all currently incomplete records immediately in their
|
65
|
+
# incomplete state. This clears those incomplete records, so note that
|
66
|
+
# if they do get completed later, they will not be re-emitted.
|
67
|
+
|
68
|
+
def emit_incomplete_records
|
69
|
+
if @records
|
70
|
+
@records.values.each do |record_|
|
71
|
+
@processor.record(record_)
|
72
|
+
end
|
73
|
+
@records.clear
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def begin_record(entry_)
|
79
|
+
return unless @records
|
80
|
+
record_id_ = entry_.record_id
|
81
|
+
if @records.include?(record_id_)
|
82
|
+
@processor.extra_entry(entry_)
|
83
|
+
false
|
84
|
+
else
|
85
|
+
@records[record_id_] = Record.new([entry_])
|
86
|
+
true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
def end_record(entry_)
|
92
|
+
return unless @records
|
93
|
+
record_ = @records.delete(entry_.record_id)
|
94
|
+
if record_
|
95
|
+
record_.add_entry(entry_)
|
96
|
+
@processor.record(record_)
|
97
|
+
true
|
98
|
+
else
|
99
|
+
@processor.extra_entry(entry_)
|
100
|
+
false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
def message(entry_)
|
106
|
+
return unless @records
|
107
|
+
record_ = @records[entry_.record_id]
|
108
|
+
if record_
|
109
|
+
record_.add_entry(entry_)
|
110
|
+
true
|
111
|
+
else
|
112
|
+
@processor.extra_entry(entry_)
|
113
|
+
false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
def attribute(entry_)
|
119
|
+
return unless @records
|
120
|
+
record_ = @records[entry_.record_id]
|
121
|
+
if record_
|
122
|
+
record_.add_entry(entry_)
|
123
|
+
true
|
124
|
+
else
|
125
|
+
@processor.extra_entry(entry_)
|
126
|
+
false
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
def unknown_data(entry_)
|
132
|
+
return unless @records
|
133
|
+
@processor.extra_entry(entry_)
|
134
|
+
false
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def close
|
139
|
+
if @records && @emit_incomplete_records_on_close
|
140
|
+
emit_incomplete_records
|
141
|
+
end
|
142
|
+
@records = nil
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
# Sawmill::RecordBuilder is an alternate name for
|
153
|
+
# Sawmill::EntryProcessor::BuildRecords
|
154
|
+
RecordBuilder = EntryProcessor::BuildRecords
|
155
|
+
|
156
|
+
|
157
|
+
end
|
@@ -0,0 +1,444 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill basic entry processors that implement conditionals
|
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
|
+
# An "if" conditional.
|
43
|
+
#
|
44
|
+
# Takes a boolean condition processor and executes a processor on true
|
45
|
+
# (and optionally another one on false).
|
46
|
+
#
|
47
|
+
# For example, this builds a processor that sends formatted log entries
|
48
|
+
# to STDOUT only if their level is at least INFO:
|
49
|
+
#
|
50
|
+
# processor = Sawmill::EntryProcessor.build do
|
51
|
+
# If(FilterBasicFields(:level => :INFO), Format(STDOUT))
|
52
|
+
# end
|
53
|
+
|
54
|
+
class If < Base
|
55
|
+
|
56
|
+
|
57
|
+
# Create an "if" conditional.
|
58
|
+
#
|
59
|
+
# The first parameter must be a processor whose methods return a
|
60
|
+
# boolean value indicating whether the entry should be accepted.
|
61
|
+
# The second parameter is a processor to run on accepted entries.
|
62
|
+
# The optional third parameter is an "else" processor to run on
|
63
|
+
# rejected entries.
|
64
|
+
|
65
|
+
def initialize(condition_, on_true_, on_false_=nil)
|
66
|
+
@condition = condition_
|
67
|
+
@on_true = on_true_
|
68
|
+
@on_false = on_false_
|
69
|
+
end
|
70
|
+
|
71
|
+
def begin_record(entry_)
|
72
|
+
if @condition.begin_record(entry_)
|
73
|
+
@on_true.begin_record(entry_)
|
74
|
+
elsif @on_false
|
75
|
+
@on_false.begin_record(entry_)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def end_record(entry_)
|
80
|
+
if @condition.end_record(entry_)
|
81
|
+
@on_true.end_record(entry_)
|
82
|
+
elsif @on_false
|
83
|
+
@on_false.end_record(entry_)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def message(entry_)
|
88
|
+
if @condition.message(entry_)
|
89
|
+
@on_true.message(entry_)
|
90
|
+
elsif @on_false
|
91
|
+
@on_false.message(entry_)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def attribute(entry_)
|
96
|
+
if @condition.attribute(entry_)
|
97
|
+
@on_true.attribute(entry_)
|
98
|
+
elsif @on_false
|
99
|
+
@on_false.attribute(entry_)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def unknown_data(entry_)
|
104
|
+
if @condition.unknown_data(entry_)
|
105
|
+
@on_true.unknown_data(entry_)
|
106
|
+
elsif @on_false
|
107
|
+
@on_false.unknown_data(entry_)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def close
|
112
|
+
@on_true.close
|
113
|
+
@on_false.close if @on_false
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# A boolean processor that returns the boolean negation of a given
|
121
|
+
# processor.
|
122
|
+
#
|
123
|
+
# For example, this builds a processor that sends formatted log entries
|
124
|
+
# to STDOUT only if their level is NOT at least INFO:
|
125
|
+
#
|
126
|
+
# processor = Sawmill::EntryProcessor.build do
|
127
|
+
# If(Not(FilterBasicFields(:level => :INFO)), Format(STDOUT))
|
128
|
+
# end
|
129
|
+
|
130
|
+
class Not < Base
|
131
|
+
|
132
|
+
|
133
|
+
# Create a "not" boolean.
|
134
|
+
# The parameter is a boolean processor to run. This processor returns
|
135
|
+
# the boolean negation of its output.
|
136
|
+
|
137
|
+
def initialize(child_)
|
138
|
+
@child = _interpret_processor(child_)
|
139
|
+
end
|
140
|
+
|
141
|
+
def begin_record(entry_)
|
142
|
+
!@child.begin_record(entry_)
|
143
|
+
end
|
144
|
+
|
145
|
+
def end_record(entry_)
|
146
|
+
!@child.end_record(entry_)
|
147
|
+
end
|
148
|
+
|
149
|
+
def message(entry_)
|
150
|
+
!@child.message(entry_)
|
151
|
+
end
|
152
|
+
|
153
|
+
def attribute(entry_)
|
154
|
+
!@child.attribute(entry_)
|
155
|
+
end
|
156
|
+
|
157
|
+
def unknown_data(entry_)
|
158
|
+
!@child.unknown_data(entry_)
|
159
|
+
end
|
160
|
+
|
161
|
+
def close
|
162
|
+
@child.close
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
# A boolean processor that returns true if and only if all its child
|
170
|
+
# processors return true. This version short-circuits the processing,
|
171
|
+
# so once one child returns false, subsequent children are not called
|
172
|
+
# at all.
|
173
|
+
#
|
174
|
+
# For example, this builds a processor that sends formatted log entries
|
175
|
+
# to STDOUT only if their level is at least INFO AND the progname is
|
176
|
+
# is "rails":
|
177
|
+
#
|
178
|
+
# processor = Sawmill::EntryProcessor.build do
|
179
|
+
# If(And(FilterBasicFields(:level => :INFO),
|
180
|
+
# FilterBasicFields(:progname => 'rails')),
|
181
|
+
# Format(STDOUT))
|
182
|
+
# end
|
183
|
+
|
184
|
+
class And < Base
|
185
|
+
|
186
|
+
|
187
|
+
# Create an "and" boolean.
|
188
|
+
# The parameters are child processors whose return values should be
|
189
|
+
# combined with an AND operation.
|
190
|
+
|
191
|
+
def initialize(*children_)
|
192
|
+
@children = _interpret_processor_array(children_)
|
193
|
+
end
|
194
|
+
|
195
|
+
def begin_record(entry_)
|
196
|
+
@children.each do |child_|
|
197
|
+
return false unless child_.begin_record(entry_)
|
198
|
+
end
|
199
|
+
true
|
200
|
+
end
|
201
|
+
|
202
|
+
def end_record(entry_)
|
203
|
+
@children.each do |child_|
|
204
|
+
return false unless child_.end_record(entry_)
|
205
|
+
end
|
206
|
+
true
|
207
|
+
end
|
208
|
+
|
209
|
+
def message(entry_)
|
210
|
+
@children.each do |child_|
|
211
|
+
return false unless child_.message(entry_)
|
212
|
+
end
|
213
|
+
true
|
214
|
+
end
|
215
|
+
|
216
|
+
def attribute(entry_)
|
217
|
+
@children.each do |child_|
|
218
|
+
return false unless child_.attribute(entry_)
|
219
|
+
end
|
220
|
+
true
|
221
|
+
end
|
222
|
+
|
223
|
+
def unknown_data(entry_)
|
224
|
+
@children.each do |child_|
|
225
|
+
return false unless child_.unknown_data(entry_)
|
226
|
+
end
|
227
|
+
true
|
228
|
+
end
|
229
|
+
|
230
|
+
def close
|
231
|
+
@children.each{ |forward_| forward_.close }
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
# A boolean processor that returns true if and only if any of its child
|
239
|
+
# processors returns true. This version short-circuits the processing,
|
240
|
+
# so once one child returns true, subsequent children are not called
|
241
|
+
# at all.
|
242
|
+
#
|
243
|
+
# For example, this builds a processor that sends formatted log entries
|
244
|
+
# to STDOUT only if their level is at least INFO OR the progname is
|
245
|
+
# "rails":
|
246
|
+
#
|
247
|
+
# processor = Sawmill::EntryProcessor.build do
|
248
|
+
# If(Or(FilterBasicFields(:level => :INFO),
|
249
|
+
# FilterBasicFields(:progname => 'rails')),
|
250
|
+
# Format(STDOUT))
|
251
|
+
# end
|
252
|
+
|
253
|
+
class Or < Base
|
254
|
+
|
255
|
+
|
256
|
+
# Create an "or" boolean.
|
257
|
+
# The parameters are child processors whose return values should be
|
258
|
+
# combined with an OR operation.
|
259
|
+
|
260
|
+
def initialize(*children_)
|
261
|
+
@children = _interpret_processor_array(children_)
|
262
|
+
end
|
263
|
+
|
264
|
+
def begin_record(entry_)
|
265
|
+
@children.each do |child_|
|
266
|
+
return true if child_.begin_record(entry_)
|
267
|
+
end
|
268
|
+
false
|
269
|
+
end
|
270
|
+
|
271
|
+
def end_record(entry_)
|
272
|
+
@children.each do |child_|
|
273
|
+
return true if child_.end_record(entry_)
|
274
|
+
end
|
275
|
+
false
|
276
|
+
end
|
277
|
+
|
278
|
+
def message(entry_)
|
279
|
+
@children.each do |child_|
|
280
|
+
return true if child_.message(entry_)
|
281
|
+
end
|
282
|
+
false
|
283
|
+
end
|
284
|
+
|
285
|
+
def attribute(entry_)
|
286
|
+
@children.each do |child_|
|
287
|
+
return true if child_.attribute(entry_)
|
288
|
+
end
|
289
|
+
false
|
290
|
+
end
|
291
|
+
|
292
|
+
def unknown_data(entry_)
|
293
|
+
@children.each do |child_|
|
294
|
+
return true if child_.unknown_data(entry_)
|
295
|
+
end
|
296
|
+
false
|
297
|
+
end
|
298
|
+
|
299
|
+
def close
|
300
|
+
@children.each{ |forward_| forward_.close }
|
301
|
+
end
|
302
|
+
|
303
|
+
|
304
|
+
end
|
305
|
+
|
306
|
+
|
307
|
+
# A boolean processor that returns true if and only if all its child
|
308
|
+
# processors return true. This version does not short-circuit the
|
309
|
+
# processing, so all children are always called even if an early one
|
310
|
+
# returns false. Thus, this processor is also a good one to use as a
|
311
|
+
# multiplexor to simply run a bunch of processors.
|
312
|
+
#
|
313
|
+
# For example, this builds a processor that sends formatted log entries
|
314
|
+
# to STDOUT only if their level is at least INFO AND the progname is
|
315
|
+
# "rails":
|
316
|
+
#
|
317
|
+
# processor = Sawmill::EntryProcessor.build do
|
318
|
+
# If(All(FilterBasicFields(:level => :INFO),
|
319
|
+
# FilterBasicFields(:progname => 'rails')),
|
320
|
+
# Format(STDOUT))
|
321
|
+
# end
|
322
|
+
#
|
323
|
+
# This processor just formats both to STDOUT and STDERR:
|
324
|
+
#
|
325
|
+
# processor = Sawmill::EntryProcessor.build do
|
326
|
+
# All(Format(STDOUT), Format(STDERR))
|
327
|
+
# end
|
328
|
+
|
329
|
+
class All < Base
|
330
|
+
|
331
|
+
|
332
|
+
# Create an "all" boolean.
|
333
|
+
# The parameters are child processors whose return values should be
|
334
|
+
# combined with an AND operation.
|
335
|
+
|
336
|
+
def initialize(*children_)
|
337
|
+
@children = _interpret_processor_array(children_)
|
338
|
+
end
|
339
|
+
|
340
|
+
def begin_record(entry_)
|
341
|
+
@children.inject(true) do |result_, child_|
|
342
|
+
child_.begin_record(entry_) && result_
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
def end_record(entry_)
|
347
|
+
@children.inject(true) do |result_, child_|
|
348
|
+
child_.end_record(entry_) && result_
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
def message(entry_)
|
353
|
+
@children.inject(true) do |result_, child_|
|
354
|
+
child_.message(entry_) && result_
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def attribute(entry_)
|
359
|
+
@children.inject(true) do |result_, child_|
|
360
|
+
child_.attribute(entry_) && result_
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
def unknown_data(entry_)
|
365
|
+
@children.inject(true) do |result_, child_|
|
366
|
+
child_.unknown_data(entry_) && result_
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
def close
|
371
|
+
@children.each{ |forward_| forward_.close }
|
372
|
+
end
|
373
|
+
|
374
|
+
|
375
|
+
end
|
376
|
+
|
377
|
+
|
378
|
+
# A boolean processor that returns true if and only if any of its child
|
379
|
+
# processors returns true. This version does not short-circuit the
|
380
|
+
# processing, so all children are always called even if an early one
|
381
|
+
# returns true.
|
382
|
+
#
|
383
|
+
# For example, this builds a processor that sends formatted log entries
|
384
|
+
# to STDOUT only if their level is at least INFO OR the progname is
|
385
|
+
# "rails":
|
386
|
+
#
|
387
|
+
# processor = Sawmill::EntryProcessor.build do
|
388
|
+
# If(Any(FilterBasicFields(:level => :INFO),
|
389
|
+
# FilterBasicFields(:progname => 'rails')),
|
390
|
+
# Format(STDOUT))
|
391
|
+
# end
|
392
|
+
|
393
|
+
class Any < Base
|
394
|
+
|
395
|
+
|
396
|
+
# Create an "any" boolean.
|
397
|
+
# The parameters are child processors whose return values should be
|
398
|
+
# combined with an OR operation.
|
399
|
+
|
400
|
+
def initialize(*children_)
|
401
|
+
@children = _interpret_processor_array(children_)
|
402
|
+
end
|
403
|
+
|
404
|
+
def begin_record(entry_)
|
405
|
+
@children.inject(false) do |result_, child_|
|
406
|
+
child_.begin_record(entry_) || result_
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
def end_record(entry_)
|
411
|
+
@children.inject(false) do |result_, child_|
|
412
|
+
child_.end_record(entry_) || result_
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
def message(entry_)
|
417
|
+
@children.inject(false) do |result_, child_|
|
418
|
+
child_.message(entry_) || result_
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
def attribute(entry_)
|
423
|
+
@children.inject(false) do |result_, child_|
|
424
|
+
child_.attribute(entry_) || result_
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
def unknown_data(entry_)
|
429
|
+
@children.inject(false) do |result_, child_|
|
430
|
+
child_.unknown_data(entry_) || result_
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def close
|
435
|
+
@children.each{ |forward_| forward_.close }
|
436
|
+
end
|
437
|
+
|
438
|
+
|
439
|
+
end
|
440
|
+
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
end
|