sawmill 0.1.15 → 0.1.16
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +7 -0
- data/Version +1 -1
- data/lib/sawmill.rb +6 -6
- data/lib/sawmill/entry.rb +108 -108
- data/lib/sawmill/entry_classifier.rb +19 -19
- data/lib/sawmill/entry_processor.rb +63 -63
- data/lib/sawmill/entry_processor/build_records.rb +39 -39
- data/lib/sawmill/entry_processor/compile_report.rb +32 -32
- data/lib/sawmill/entry_processor/conditionals.rb +110 -110
- data/lib/sawmill/entry_processor/count_entries.rb +27 -27
- data/lib/sawmill/entry_processor/filter_by_basic_fields.rb +32 -32
- data/lib/sawmill/entry_processor/filter_by_block.rb +28 -28
- data/lib/sawmill/entry_processor/format.rb +41 -36
- data/lib/sawmill/entry_processor/interpret_stats.rb +24 -24
- data/lib/sawmill/entry_processor/simple_queue.rb +38 -38
- data/lib/sawmill/errors.rb +28 -28
- data/lib/sawmill/interface.rb +51 -51
- data/lib/sawmill/level.rb +75 -75
- data/lib/sawmill/log_record_middleware.rb +21 -21
- data/lib/sawmill/logger.rb +94 -94
- data/lib/sawmill/multi_parser.rb +28 -28
- data/lib/sawmill/parser.rb +32 -32
- data/lib/sawmill/railtie.rb +31 -31
- data/lib/sawmill/record.rb +74 -74
- data/lib/sawmill/record_processor.rb +54 -54
- data/lib/sawmill/record_processor/compile_report.rb +32 -32
- data/lib/sawmill/record_processor/conditionals.rb +92 -92
- data/lib/sawmill/record_processor/count_records.rb +24 -24
- data/lib/sawmill/record_processor/decompose.rb +21 -21
- data/lib/sawmill/record_processor/filter_by_attributes.rb +22 -22
- data/lib/sawmill/record_processor/filter_by_block.rb +29 -29
- data/lib/sawmill/record_processor/filter_by_record_id.rb +22 -22
- data/lib/sawmill/record_processor/format.rb +24 -24
- data/lib/sawmill/record_processor/simple_queue.rb +44 -44
- data/lib/sawmill/rotater.rb +60 -60
- data/lib/sawmill/rotater/base.rb +28 -28
- data/lib/sawmill/rotater/date_based_log_file.rb +50 -50
- data/lib/sawmill/rotater/shifting_log_file.rb +34 -34
- data/lib/sawmill/stats_middleware.rb +21 -21
- data/lib/sawmill/stats_railtie.rb +33 -33
- data/lib/sawmill/util/heap.rb +41 -41
- data/lib/sawmill/util/processor_tools.rb +17 -17
- data/lib/sawmill/util/queue.rb +33 -33
- data/lib/sawmill/version.rb +9 -9
- data/test/tc_entry_processors.rb +27 -27
- data/test/tc_formatter_parser.rb +40 -40
- data/test/tc_levels.rb +27 -27
- data/test/tc_logger.rb +49 -49
- data/test/tc_multi_parser.rb +18 -18
- data/test/tc_record_processors.rb +21 -21
- data/test/tc_records.rb +39 -39
- data/test/tc_reports.rb +19 -19
- metadata +10 -5
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Sawmill entry sorter utility
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2009 Daniel Azuma
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# All rights reserved.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Redistribution and use in source and binary forms, with or without
|
11
11
|
# modification, are permitted provided that the following conditions are met:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# * Redistributions of source code must retain the above copyright notice,
|
14
14
|
# this list of conditions and the following disclaimer.
|
15
15
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# * Neither the name of the copyright holder, nor the names of any other
|
19
19
|
# contributors to this software, may be used to endorse or promote products
|
20
20
|
# derived from this software without specific prior written permission.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
23
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
24
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
@@ -35,24 +35,24 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
module Sawmill
|
38
|
-
|
39
|
-
|
38
|
+
|
39
|
+
|
40
40
|
# An object that classifies log entry objects, calling the proper methods
|
41
41
|
# on a Sawmill::EntryProcessor.
|
42
|
-
|
42
|
+
|
43
43
|
class EntryClassifier
|
44
|
-
|
45
|
-
|
44
|
+
|
45
|
+
|
46
46
|
# Create a classifier that sends entries to the given
|
47
47
|
# Sawmill::EntryProcessor.
|
48
|
-
|
48
|
+
|
49
49
|
def initialize(processor_)
|
50
50
|
@processor = processor_
|
51
51
|
end
|
52
|
-
|
53
|
-
|
52
|
+
|
53
|
+
|
54
54
|
# Call this method to classify a log entry and send it to the processor.
|
55
|
-
|
55
|
+
|
56
56
|
def entry(entry_)
|
57
57
|
case entry_.type
|
58
58
|
when :unknown_data
|
@@ -67,9 +67,9 @@ module Sawmill
|
|
67
67
|
@processor.attribute(entry_)
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
71
|
-
|
70
|
+
|
71
|
+
|
72
72
|
end
|
73
|
-
|
74
|
-
|
73
|
+
|
74
|
+
|
75
75
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Sawmill entry processor interface
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2009 Daniel Azuma
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# All rights reserved.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Redistribution and use in source and binary forms, with or without
|
11
11
|
# modification, are permitted provided that the following conditions are met:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# * Redistributions of source code must retain the above copyright notice,
|
14
14
|
# this list of conditions and the following disclaimer.
|
15
15
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# * Neither the name of the copyright holder, nor the names of any other
|
19
19
|
# contributors to this software, may be used to endorse or promote products
|
20
20
|
# derived from this software without specific prior written permission.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
23
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
24
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
@@ -35,83 +35,83 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
module Sawmill
|
38
|
-
|
39
|
-
|
38
|
+
|
39
|
+
|
40
40
|
# Entry processors are objects that receive a stream of log entries and
|
41
41
|
# perform some action. Some processors perform their own action, while
|
42
42
|
# others could filter entries and forward them to other processors.
|
43
|
-
#
|
43
|
+
#
|
44
44
|
# The API contract for an entry processor is specified by the class
|
45
45
|
# Sawmill::EntryProcessor::Base. Processors could subclass that base
|
46
46
|
# class, or could just duck-type the methods.
|
47
|
-
#
|
47
|
+
#
|
48
48
|
# Sawmill's basic entry processor classes live into this module's
|
49
49
|
# namespace, but this is not a requirement for your own processors.
|
50
|
-
|
50
|
+
|
51
51
|
module EntryProcessor
|
52
|
-
|
53
|
-
|
52
|
+
|
53
|
+
|
54
54
|
class Builder # :nodoc:
|
55
55
|
include ::Blockenspiel::DSL
|
56
56
|
end
|
57
|
-
|
58
|
-
|
57
|
+
|
58
|
+
|
59
59
|
# A base class for entry processors.
|
60
|
-
#
|
60
|
+
#
|
61
61
|
# Entry processors need not necessarily subclass this class, but should
|
62
62
|
# at least duck-type the methods.
|
63
|
-
#
|
63
|
+
#
|
64
64
|
# If a class subclasses this class, *and* lives in the EntryProcessor
|
65
65
|
# namespace, then it will automatically be available in the build
|
66
66
|
# interface. See EntryProcessor#build.
|
67
|
-
|
67
|
+
|
68
68
|
class Base
|
69
|
-
|
70
|
-
|
69
|
+
|
70
|
+
|
71
71
|
# Receive and process a Sawmill::Entry::BeginRecord.
|
72
|
-
|
72
|
+
|
73
73
|
def begin_record(entry_)
|
74
74
|
true
|
75
75
|
end
|
76
|
-
|
77
|
-
|
76
|
+
|
77
|
+
|
78
78
|
# Receive and process a Sawmill::Entry::EndRecord.
|
79
|
-
|
79
|
+
|
80
80
|
def end_record(entry_)
|
81
81
|
true
|
82
82
|
end
|
83
|
-
|
84
|
-
|
83
|
+
|
84
|
+
|
85
85
|
# Receive and process a Sawmill::Entry::Message.
|
86
|
-
|
86
|
+
|
87
87
|
def message(entry_)
|
88
88
|
true
|
89
89
|
end
|
90
|
-
|
91
|
-
|
90
|
+
|
91
|
+
|
92
92
|
# Receive and process a Sawmill::Entry::Attribute.
|
93
|
-
|
93
|
+
|
94
94
|
def attribute(entry_)
|
95
95
|
true
|
96
96
|
end
|
97
|
-
|
98
|
-
|
97
|
+
|
98
|
+
|
99
99
|
# Receive and process a Sawmill::Entry::UnknownData.
|
100
|
-
|
100
|
+
|
101
101
|
def unknown_data(entry_)
|
102
102
|
true
|
103
103
|
end
|
104
|
-
|
105
|
-
|
104
|
+
|
105
|
+
|
106
106
|
# Close down the processor, perform any finishing tasks, and return
|
107
107
|
# any final calculated value.
|
108
|
-
#
|
108
|
+
#
|
109
109
|
# After this is called, the processor should ignore any further entries.
|
110
|
-
#
|
110
|
+
#
|
111
111
|
# The return value can be used to communicate a final computed value,
|
112
112
|
# analysis report, or other data back to the caller. It may also be
|
113
113
|
# nil, signalling no finish value.
|
114
|
-
#
|
114
|
+
#
|
115
115
|
# Note that some processors function to multiplex other processors. In
|
116
116
|
# such a case, their finish value needs to be an aggregate of the
|
117
117
|
# values returned by their descendants. To handle these cases, we
|
@@ -124,12 +124,12 @@ module Sawmill
|
|
124
124
|
# actually return an array _as_ a value, you must wrap it in another
|
125
125
|
# array, indicating "an array of one finish value, and that finish
|
126
126
|
# value also happens to be an array itself".
|
127
|
-
|
127
|
+
|
128
128
|
def finish
|
129
129
|
nil
|
130
130
|
end
|
131
|
-
|
132
|
-
|
131
|
+
|
132
|
+
|
133
133
|
def self.inherited(subclass_) # :nodoc:
|
134
134
|
if subclass_.name =~ /^Sawmill::EntryProcessor::([^:]+)$/
|
135
135
|
name_ = $1
|
@@ -140,23 +140,23 @@ module Sawmill
|
|
140
140
|
end
|
141
141
|
end
|
142
142
|
end
|
143
|
-
|
144
|
-
|
143
|
+
|
144
|
+
|
145
145
|
# Add a method to the processor building DSL. You may call this method
|
146
146
|
# in the DSL to create an instance of this entry processor.
|
147
147
|
# You must pass a method name that begins with a lower-case letter or
|
148
148
|
# underscore.
|
149
|
-
#
|
149
|
+
#
|
150
150
|
# Processors that subclass Sawmill::EntryProcessor::Base and live in
|
151
151
|
# the Sawmill::EntryProcessor namespace will have their class name
|
152
152
|
# automatically added to the DSL. This method is primarily for other
|
153
153
|
# processors that do not live in that module namespace.
|
154
|
-
#
|
154
|
+
#
|
155
155
|
# See Sawmill::EntryProcessor#build for more information.
|
156
|
-
#
|
156
|
+
#
|
157
157
|
# Raises Sawmill::Errors::DSLMethodError if the given name is already
|
158
158
|
# taken.
|
159
|
-
|
159
|
+
|
160
160
|
def self.add_dsl_method(name_)
|
161
161
|
klass_ = self
|
162
162
|
if name_.to_s !~ /^[a-z_]/
|
@@ -171,14 +171,14 @@ module Sawmill
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
end
|
174
|
-
|
175
|
-
|
174
|
+
|
175
|
+
|
176
176
|
private
|
177
|
-
|
177
|
+
|
178
178
|
def _interpret_processor_array(param_) # :nodoc:
|
179
179
|
param_.flatten.map{ |processor_| _interpret_processor(processor_) }
|
180
180
|
end
|
181
|
-
|
181
|
+
|
182
182
|
def _interpret_processor(param_) # :nodoc:
|
183
183
|
case param_
|
184
184
|
when ::Class
|
@@ -189,33 +189,33 @@ module Sawmill
|
|
189
189
|
raise ::ArgumentError, "Unknown processor object of type #{param_.class.name}"
|
190
190
|
end
|
191
191
|
end
|
192
|
-
|
193
|
-
|
192
|
+
|
193
|
+
|
194
194
|
end
|
195
|
-
|
196
|
-
|
195
|
+
|
196
|
+
|
197
197
|
# A convenience DSL for building sets of processors. This is typically
|
198
198
|
# useful for constructing if-expressions using the boolean operation
|
199
199
|
# processors.
|
200
|
-
#
|
200
|
+
#
|
201
201
|
# Every entry processor that lives in the Sawmill::EntryProcessor
|
202
202
|
# module and subclasses Sawmill::EntryProcessor::Base can be
|
203
203
|
# instantiated by using its name as a function call. Other processors
|
204
204
|
# may also add themselves to the DSL by calling
|
205
205
|
# Sawmill::EntryProcessor::Base#add_dsl_method.
|
206
|
-
#
|
206
|
+
#
|
207
207
|
# For example:
|
208
|
-
#
|
208
|
+
#
|
209
209
|
# Sawmill::EntryProcessor.build do
|
210
210
|
# If(FilterByBasicFields(:level => :WARN), Format(STDOUT))
|
211
211
|
# end
|
212
|
-
|
212
|
+
|
213
213
|
def self.build(&block_)
|
214
214
|
::Blockenspiel.invoke(block_, Builder.new)
|
215
215
|
end
|
216
|
-
|
217
|
-
|
216
|
+
|
217
|
+
|
218
218
|
end
|
219
|
-
|
220
|
-
|
219
|
+
|
220
|
+
|
221
221
|
end
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Sawmill entry processor that builds log records
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2009 Daniel Azuma
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# All rights reserved.
|
9
|
-
#
|
9
|
+
#
|
10
10
|
# Redistribution and use in source and binary forms, with or without
|
11
11
|
# modification, are permitted provided that the following conditions are met:
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# * Redistributions of source code must retain the above copyright notice,
|
14
14
|
# this list of conditions and the following disclaimer.
|
15
15
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# * Neither the name of the copyright holder, nor the names of any other
|
19
19
|
# contributors to this software, may be used to endorse or promote products
|
20
20
|
# derived from this software without specific prior written permission.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
23
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
24
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
@@ -35,36 +35,36 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
module Sawmill
|
38
|
-
|
38
|
+
|
39
39
|
module EntryProcessor
|
40
|
-
|
41
|
-
|
40
|
+
|
41
|
+
|
42
42
|
# An entry processor that builds log records from a stream of entries,
|
43
43
|
# and passes those log records to the given record processor.
|
44
|
-
|
44
|
+
|
45
45
|
class BuildRecords < Base
|
46
|
-
|
47
|
-
|
46
|
+
|
47
|
+
|
48
48
|
# Create record builder emitting to the given record processor.
|
49
|
-
#
|
49
|
+
#
|
50
50
|
# Recognized options include:
|
51
|
-
#
|
51
|
+
#
|
52
52
|
# [<tt>:emit_incomplete_records_on_finish</tt>]
|
53
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
|
-
|
63
|
-
|
62
|
+
|
63
|
+
|
64
64
|
# Emit all currently incomplete records immediately in their
|
65
65
|
# incomplete state. This clears those incomplete records, so note that
|
66
66
|
# if they do get completed later, they will not be re-emitted.
|
67
|
-
|
67
|
+
|
68
68
|
def emit_incomplete_records
|
69
69
|
if @records
|
70
70
|
@records.values.each do |record_|
|
@@ -73,8 +73,8 @@ module Sawmill
|
|
73
73
|
@records.clear
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
77
|
-
|
76
|
+
|
77
|
+
|
78
78
|
def begin_record(entry_)
|
79
79
|
return unless @records
|
80
80
|
record_id_ = entry_.record_id
|
@@ -86,8 +86,8 @@ module Sawmill
|
|
86
86
|
true
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
90
|
-
|
89
|
+
|
90
|
+
|
91
91
|
def end_record(entry_)
|
92
92
|
return unless @records
|
93
93
|
record_ = @records.delete(entry_.record_id)
|
@@ -100,8 +100,8 @@ module Sawmill
|
|
100
100
|
false
|
101
101
|
end
|
102
102
|
end
|
103
|
-
|
104
|
-
|
103
|
+
|
104
|
+
|
105
105
|
def message(entry_)
|
106
106
|
return unless @records
|
107
107
|
record_ = @records[entry_.record_id]
|
@@ -113,8 +113,8 @@ module Sawmill
|
|
113
113
|
false
|
114
114
|
end
|
115
115
|
end
|
116
|
-
|
117
|
-
|
116
|
+
|
117
|
+
|
118
118
|
def attribute(entry_)
|
119
119
|
return unless @records
|
120
120
|
record_ = @records[entry_.record_id]
|
@@ -126,35 +126,35 @@ module Sawmill
|
|
126
126
|
false
|
127
127
|
end
|
128
128
|
end
|
129
|
-
|
130
|
-
|
129
|
+
|
130
|
+
|
131
131
|
def unknown_data(entry_)
|
132
132
|
return unless @records
|
133
133
|
@processor.extra_entry(entry_)
|
134
134
|
false
|
135
135
|
end
|
136
|
-
|
137
|
-
|
136
|
+
|
137
|
+
|
138
138
|
def finish
|
139
139
|
if @records
|
140
|
-
emit_incomplete_records if @
|
140
|
+
emit_incomplete_records if @emit_incomplete_records_on_finish
|
141
141
|
@records = nil
|
142
142
|
@processor.finish
|
143
143
|
else
|
144
144
|
nil
|
145
145
|
end
|
146
146
|
end
|
147
|
-
|
148
|
-
|
147
|
+
|
148
|
+
|
149
149
|
end
|
150
|
-
|
151
|
-
|
150
|
+
|
151
|
+
|
152
152
|
end
|
153
|
-
|
154
|
-
|
153
|
+
|
154
|
+
|
155
155
|
# Sawmill::RecordBuilder is an alternate name for
|
156
156
|
# Sawmill::EntryProcessor::BuildRecords
|
157
157
|
RecordBuilder = EntryProcessor::BuildRecords
|
158
|
-
|
159
|
-
|
158
|
+
|
159
|
+
|
160
160
|
end
|