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,87 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill record processor that checks record attribute values
|
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 RecordProcessor
|
40
|
+
|
41
|
+
|
42
|
+
# A record filter that checks attribute values.
|
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 FilterByAttributes < Base
|
49
|
+
|
50
|
+
|
51
|
+
# Create a new filter. Pass the attribute names and values to check
|
52
|
+
# as a hash.
|
53
|
+
|
54
|
+
def initialize(attributes_)
|
55
|
+
@attributes = {}
|
56
|
+
attributes_.each{ |key_, value_| @attributes[key_.to_s] = value_ }
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def record(record_)
|
61
|
+
@attributes.each do |key_, value_|
|
62
|
+
record_value_ = record_.attribute(key_.to_s)
|
63
|
+
case record_value_
|
64
|
+
when Array
|
65
|
+
return false unless record_value_.find{ |rval_| value_ === rval_ }
|
66
|
+
when String
|
67
|
+
return false unless value_ === record_value_
|
68
|
+
when nil
|
69
|
+
return false unless value_.nil?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def extra_entry(entry_)
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
def close
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill record processor that checks record IDs
|
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 RecordProcessor
|
40
|
+
|
41
|
+
|
42
|
+
# A record filter that checks record IDs.
|
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 FilterByRecordID < Base
|
49
|
+
|
50
|
+
|
51
|
+
# Create a new filter that checks against the given record ID.
|
52
|
+
# The given ID may be a string or a Regexp, in which case the filter
|
53
|
+
# will check for equality or regular expression match, respectively.
|
54
|
+
|
55
|
+
def initialize(id_)
|
56
|
+
@record_id = id_
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def record(record_)
|
61
|
+
@record_id === record_.record_id
|
62
|
+
end
|
63
|
+
|
64
|
+
def extra_entry(entry_)
|
65
|
+
id_ = entry_.respond_to?(:record_id) ? entry_.record_id : nil
|
66
|
+
@record_id === id_
|
67
|
+
end
|
68
|
+
|
69
|
+
def close
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill record processor that formats for log files
|
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 RecordProcessor
|
40
|
+
|
41
|
+
|
42
|
+
# This processor formats log records and writes them to a destination.
|
43
|
+
|
44
|
+
class Format < Base
|
45
|
+
|
46
|
+
|
47
|
+
# Create a formatter.
|
48
|
+
#
|
49
|
+
# The destination can be a ruby IO object, a Sawmill::Rotater, or any
|
50
|
+
# object that responds to the "write" and "close" methods as defined
|
51
|
+
# by the ruby IO class.
|
52
|
+
#
|
53
|
+
# Recognized options include:
|
54
|
+
#
|
55
|
+
# <tt>:include_id</tt>::
|
56
|
+
# Include the record ID in every log entry. Default is false.
|
57
|
+
# <tt>:fractional_second_digits</tt>::
|
58
|
+
# Number of digits of fractional seconds to display in timestamps.
|
59
|
+
# Default is 2. Accepted values are 0 to 6.
|
60
|
+
# <tt>:level_width</tt>::
|
61
|
+
# Column width of the level field.
|
62
|
+
|
63
|
+
def initialize(destination_, opts_={})
|
64
|
+
@formatter = EntryProcessor::Format.new(destination_, opts_)
|
65
|
+
@classifier = EntryClassifier.new(@formatter)
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def record(record_)
|
70
|
+
record_.each_entry{ |entry_| @classifier.entry(entry_) }
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
74
|
+
def extra_entry(entry_)
|
75
|
+
@classifier.entry(entry_)
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
def close
|
80
|
+
@formatter.close
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill record processor queues 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
|
+
|
40
|
+
module RecordProcessor
|
41
|
+
|
42
|
+
|
43
|
+
# This processor simply queues up log records for later use.
|
44
|
+
|
45
|
+
class SimpleQueue < Base
|
46
|
+
|
47
|
+
|
48
|
+
# Create a queue. This processor actually maintains two separate
|
49
|
+
# queues, one for records and another for extra entries.
|
50
|
+
#
|
51
|
+
# Recognized options include:
|
52
|
+
#
|
53
|
+
# <tt>:limit</tt>::
|
54
|
+
# Size limit for the queue. If not specified, the queue can grow
|
55
|
+
# arbitrarily large.
|
56
|
+
# <tt>:drop_oldest</tt>::
|
57
|
+
# If set to true, then when an item is added to a full queue, the
|
58
|
+
# oldest item is dropped. If set to false or not specified, then
|
59
|
+
# the new item is not added.
|
60
|
+
|
61
|
+
def initialize(opts_={})
|
62
|
+
@queue = Util::Queue.new(opts_)
|
63
|
+
@extra_entries_queue = Util::Queue.new(opts_)
|
64
|
+
@closed = false
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
# Return the oldest record in the record queue, or nil if the record
|
69
|
+
# queue is empty.
|
70
|
+
|
71
|
+
def dequeue
|
72
|
+
@queue.dequeue
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Return the number of records in the record queue.
|
77
|
+
|
78
|
+
def size
|
79
|
+
@queue.size
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# Return the oldest entry in the extra entry queue, or nil if the
|
84
|
+
# extra entry queue is empty.
|
85
|
+
|
86
|
+
def dequeue_extra_entry
|
87
|
+
@extra_entries_queue.dequeue
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
# Return the number of entries in the extra entry queue.
|
92
|
+
|
93
|
+
def extra_entries_size
|
94
|
+
@extra_entries_queue.size
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def record(record_)
|
99
|
+
@queue.enqueue(record_) unless @closed
|
100
|
+
end
|
101
|
+
|
102
|
+
def extra_entry(entry_)
|
103
|
+
@extra_entries_queue.enqueue(entry_) unless @closed
|
104
|
+
end
|
105
|
+
|
106
|
+
def close
|
107
|
+
@closed = true
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill record processor interface
|
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
|
+
# Entry processors are objects that receive a stream of log records and
|
41
|
+
# perform some action. Some processors perform their own action, while
|
42
|
+
# others could filter records and forward them to other processors.
|
43
|
+
#
|
44
|
+
# The API contract for a record processor is specified by the class
|
45
|
+
# Sawmill::RecordProcessor::Base. Processors could subclass that base
|
46
|
+
# class, or could just duck-type the methods.
|
47
|
+
#
|
48
|
+
# Sawmill's basic record processor classes live into this module's
|
49
|
+
# namespace, but this is not a requirement for your own processors.
|
50
|
+
|
51
|
+
module RecordProcessor
|
52
|
+
|
53
|
+
|
54
|
+
class Builder # :nodoc:
|
55
|
+
include ::Blockenspiel::DSL
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
# A base class for record processors.
|
60
|
+
#
|
61
|
+
# Record processors need not necessarily subclass this class, but should
|
62
|
+
# at least duck-type the methods.
|
63
|
+
#
|
64
|
+
# If a class subclasses this class, *and* lives in the RecordProcessor
|
65
|
+
# namespace, then it will automatically be available in the build
|
66
|
+
# interface. See RecordProcessor#build.
|
67
|
+
|
68
|
+
class Base
|
69
|
+
|
70
|
+
|
71
|
+
# Receive and process a Sawmill::Record.
|
72
|
+
|
73
|
+
def record(record_)
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# Receive and process an entry that falls outside a record.
|
79
|
+
|
80
|
+
def extra_entry(entry_)
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# Close down the processor. After this is called, the processor should
|
86
|
+
# ignore any further records.
|
87
|
+
|
88
|
+
def close
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
def self.inherited(subclass_) # :nodoc:
|
93
|
+
if subclass_.name =~ /^Sawmill::RecordProcessor::(.*)$/
|
94
|
+
name_ = $1
|
95
|
+
Builder.class_eval do
|
96
|
+
define_method(name_) do |*args_|
|
97
|
+
subclass_.new(*args_)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
def _interpret_processor_array(param_) # :nodoc:
|
107
|
+
param_.flatten.map{ |processor_| _interpret_processor(processor_) }
|
108
|
+
end
|
109
|
+
|
110
|
+
def _interpret_processor(param_) # :nodoc:
|
111
|
+
case param_
|
112
|
+
when Class
|
113
|
+
param_.new
|
114
|
+
when Base
|
115
|
+
param_
|
116
|
+
else
|
117
|
+
raise ArgumentError, "Unknown processor object of type #{param_.class.name}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
# A convenience DSL for building sets of processors. This is typically
|
126
|
+
# useful for constructing if-expressions using the boolean operation
|
127
|
+
# processors.
|
128
|
+
|
129
|
+
def self.build(&block_)
|
130
|
+
::Blockenspiel.invoke(block_, Builder.new)
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Sawmill formatter utility
|
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
|
+
class Rotater
|
40
|
+
|
41
|
+
|
42
|
+
# This class defines the rotation strategy contract. Classes that
|
43
|
+
# implement rotation strategies need not subclass this base class, but
|
44
|
+
# must implement the methods defined here.
|
45
|
+
#
|
46
|
+
# This base class itself merely writes to STDOUT and does not do
|
47
|
+
# any rotation.
|
48
|
+
|
49
|
+
class Base
|
50
|
+
|
51
|
+
|
52
|
+
# Return the currently preferred handle, identifying which io stream
|
53
|
+
# should be written to preferentially unless a channel is constrained
|
54
|
+
# to use an earlier stream.
|
55
|
+
|
56
|
+
def preferred_handle
|
57
|
+
0
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# Open and return an IO object for the given handle.
|
62
|
+
# This is guaranteed not to be called twice unless the stream has been
|
63
|
+
# closed in the meantime.
|
64
|
+
|
65
|
+
def open_handle(handle_)
|
66
|
+
STDOUT
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# Close the IO object for the given handle.
|
71
|
+
# This is guaranteed not be called unless the stream has been opened.
|
72
|
+
|
73
|
+
def close_handle(handle_, io_)
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# This is a hook that is called before every write request to any
|
78
|
+
# stream managed by this rotater. You may optionally perform any
|
79
|
+
# periodic tasks here, such as renaming log files.
|
80
|
+
|
81
|
+
def before_write
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|