sawmill 0.1.15 → 0.1.16
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 +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
data/lib/sawmill/multi_parser.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Sawmill multi-stream parser 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,31 +35,31 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
module Sawmill
|
38
|
-
|
39
|
-
|
38
|
+
|
39
|
+
|
40
40
|
# A logfile parser that parses log entries from multiple logfile streams,
|
41
41
|
# sorts by timestamp, and sends them to a processor.
|
42
|
-
|
42
|
+
|
43
43
|
class MultiParser
|
44
|
-
|
45
|
-
|
44
|
+
|
45
|
+
|
46
46
|
# Create a new parser that reads from the given streams.
|
47
|
-
#
|
47
|
+
#
|
48
48
|
# You should provide a processor to receive the data from the logfile.
|
49
49
|
# The processor may be either an entry processor or a record processor.
|
50
50
|
# You may also pass nil for the processor. In this case, the generated
|
51
51
|
# log entries will not be sent to a processor but will still be returned
|
52
52
|
# by the parse_one_entry method.
|
53
|
-
#
|
53
|
+
#
|
54
54
|
# Recognized options include:
|
55
|
-
#
|
55
|
+
#
|
56
56
|
# [<tt>:levels</tt>]
|
57
57
|
# Sawmill::LevelGroup to use to parse log levels.
|
58
58
|
# If not specified, Sawmill::STANDARD_LEVELS is used by default.
|
59
59
|
# [<tt>:emit_incomplete_records_at_eof</tt>]
|
60
60
|
# If set to true, causes any incomplete log records to be emitted
|
61
61
|
# in their incomplete state when EOF is reached on all streams.
|
62
|
-
|
62
|
+
|
63
63
|
def initialize(io_array_, processor_, opts_={})
|
64
64
|
@emit_incomplete_records_at_eof = opts_.delete(:emit_incomplete_records_at_eof)
|
65
65
|
@heap = Util::Heap.new{ |a_, b_| a_[1].timestamp <=> b_[1].timestamp }
|
@@ -80,12 +80,12 @@ module Sawmill
|
|
80
80
|
end
|
81
81
|
@classifier = @processor ? EntryClassifier.new(@processor) : nil
|
82
82
|
end
|
83
|
-
|
84
|
-
|
83
|
+
|
84
|
+
|
85
85
|
# Parse one log entry from the streams and emit it to the processor.
|
86
86
|
# Also returns the log entry.
|
87
87
|
# Returns nil if EOF has been reached on all streams.
|
88
|
-
|
88
|
+
|
89
89
|
def parse_one_entry
|
90
90
|
entry_ = @queue.dequeue
|
91
91
|
unless entry_
|
@@ -102,18 +102,18 @@ module Sawmill
|
|
102
102
|
@classifier.entry(entry_) if entry_
|
103
103
|
entry_
|
104
104
|
end
|
105
|
-
|
106
|
-
|
105
|
+
|
106
|
+
|
107
107
|
# Parse until EOF is reached on all streams, and emit the log
|
108
108
|
# entries to the processor.
|
109
|
-
|
109
|
+
|
110
110
|
def parse_all
|
111
111
|
while parse_one_entry; end
|
112
112
|
end
|
113
|
-
|
114
|
-
|
113
|
+
|
114
|
+
|
115
115
|
private
|
116
|
-
|
116
|
+
|
117
117
|
def _enqueue(parser_) # :nodoc:
|
118
118
|
loop do
|
119
119
|
entry_ = parser_.parse_one_entry
|
@@ -126,9 +126,9 @@ module Sawmill
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
end
|
129
|
-
|
130
|
-
|
129
|
+
|
130
|
+
|
131
131
|
end
|
132
|
-
|
133
|
-
|
132
|
+
|
133
|
+
|
134
134
|
end
|
data/lib/sawmill/parser.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Sawmill stream parser 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,13 +35,13 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
module Sawmill
|
38
|
-
|
39
|
-
|
38
|
+
|
39
|
+
|
40
40
|
# A logfile parser that parses log entries from a logfile and sends them
|
41
41
|
# to an entry processor.
|
42
|
-
|
42
|
+
|
43
43
|
class Parser
|
44
|
-
|
44
|
+
|
45
45
|
# :stopdoc:
|
46
46
|
LINE_REGEXP = /^\[\s*([[:graph:]]+)\s+(\d{4})-(\d{2})-(\d{2})(T|\s)(\d{2}):(\d{2}):(\d{2})(.(\d{1,6}))?Z?\s?([+-]\d{4})?\s+([[:graph:]]+)(\s+([[:graph:]]+))?\s+([\^$.=])\]\s(.*)$/
|
47
47
|
DIRECTIVE_REGEXP = /^#\s+sawmill_format:\s+(\w+)=(.*)$/
|
@@ -49,18 +49,18 @@ module Sawmill
|
|
49
49
|
SUPPORTS_ENCODING = defined?(::Encoding)
|
50
50
|
ENCODING_OPTS = {:invalid => :replace, :undef => :replace}
|
51
51
|
# :startdoc:
|
52
|
-
|
53
|
-
|
52
|
+
|
53
|
+
|
54
54
|
# Create a new parser that reads from the given stream.
|
55
|
-
#
|
55
|
+
#
|
56
56
|
# You should provide a processor to receive the data from the logfile.
|
57
57
|
# The processor may be either an entry processor or a record processor.
|
58
58
|
# You may also pass nil for the processor. In this case, the generated
|
59
59
|
# log entries will not be sent to a processor but will still be returned
|
60
60
|
# by the parse_one_entry method.
|
61
|
-
#
|
61
|
+
#
|
62
62
|
# Recognized options include:
|
63
|
-
#
|
63
|
+
#
|
64
64
|
# [<tt>:levels</tt>]
|
65
65
|
# Sawmill::LevelGroup to use to parse log levels.
|
66
66
|
# If not specified, Sawmill::STANDARD_LEVELS is used by default.
|
@@ -77,7 +77,7 @@ module Sawmill
|
|
77
77
|
# Transcodes strings as they are read. (Ruby 1.9 only). If specified,
|
78
78
|
# lines are transcoded into this encoding after they are read from
|
79
79
|
# the stream. If not specified, no post-transcoding is done.
|
80
|
-
|
80
|
+
|
81
81
|
def initialize(io_, processor_, opts_={})
|
82
82
|
@io = io_
|
83
83
|
@processor = nil
|
@@ -96,12 +96,12 @@ module Sawmill
|
|
96
96
|
@internal_encoding = ::Encoding.find(@internal_encoding) if @internal_encoding && !@internal_encoding.kind_of?(::Encoding)
|
97
97
|
end
|
98
98
|
end
|
99
|
-
|
100
|
-
|
99
|
+
|
100
|
+
|
101
101
|
# Parse one log entry from the stream and emit it to the processor.
|
102
102
|
# Also returns the log entry.
|
103
103
|
# Returns nil if EOF has been reached.
|
104
|
-
|
104
|
+
|
105
105
|
def parse_one_entry
|
106
106
|
str_ = _get_next_line
|
107
107
|
entry_ = nil
|
@@ -181,19 +181,19 @@ module Sawmill
|
|
181
181
|
end
|
182
182
|
entry_
|
183
183
|
end
|
184
|
-
|
185
|
-
|
184
|
+
|
185
|
+
|
186
186
|
# Parse the rest of the stream until EOF is reached, and emit the log
|
187
187
|
# entries to the processor.
|
188
|
-
|
188
|
+
|
189
189
|
def parse_all
|
190
190
|
while parse_one_entry; end
|
191
191
|
end
|
192
|
-
|
193
|
-
|
192
|
+
|
193
|
+
|
194
194
|
private
|
195
|
-
|
196
|
-
|
195
|
+
|
196
|
+
|
197
197
|
def _get_next_line # :nodoc:
|
198
198
|
str_ = @io.gets
|
199
199
|
if str_ && SUPPORTS_ENCODING
|
@@ -202,8 +202,8 @@ module Sawmill
|
|
202
202
|
end
|
203
203
|
str_
|
204
204
|
end
|
205
|
-
|
206
|
-
|
205
|
+
|
206
|
+
|
207
207
|
def _set_parser_directive(key_, value_) # :nodoc:
|
208
208
|
case key_
|
209
209
|
when 'encoding'
|
@@ -213,9 +213,9 @@ module Sawmill
|
|
213
213
|
end
|
214
214
|
end
|
215
215
|
end
|
216
|
-
|
217
|
-
|
216
|
+
|
217
|
+
|
218
218
|
end
|
219
|
-
|
220
|
-
|
219
|
+
|
220
|
+
|
221
221
|
end
|
data/lib/sawmill/railtie.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Sawmill railtie
|
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
|
@@ -39,29 +39,29 @@ require 'rails/railtie'
|
|
39
39
|
|
40
40
|
|
41
41
|
module Sawmill
|
42
|
-
|
43
|
-
|
42
|
+
|
43
|
+
|
44
44
|
# Railtie that replaces the default Rails logger with a Sawmill logger.
|
45
45
|
# Sets the Rails logger to a Sawmill::Logger, and installs a
|
46
46
|
# Sawmill::LogRecordMiddleware to enable record-based logging.
|
47
|
-
#
|
47
|
+
#
|
48
48
|
# To install into a Rails app, include this line in your
|
49
49
|
# config/application.rb:
|
50
50
|
# require 'sawmill/railtie'
|
51
51
|
# It should appear before your application configuration.
|
52
|
-
#
|
52
|
+
#
|
53
53
|
# You can then configure sawmill using the standard rails configuration
|
54
54
|
# mechanism. The sawmill configuration lives in the config.sawmill
|
55
55
|
# configuration namespace. See Sawmill::Railtie::Configuration for the
|
56
56
|
# configuration options.
|
57
|
-
|
57
|
+
|
58
58
|
class Railtie < ::Rails::Railtie
|
59
|
-
|
60
|
-
|
59
|
+
|
60
|
+
|
61
61
|
# Configuration options. These are attributes of config.sawmill.
|
62
|
-
|
62
|
+
|
63
63
|
class Configuration
|
64
|
-
|
64
|
+
|
65
65
|
def initialize # :nodoc:
|
66
66
|
@logfile = ::STDERR
|
67
67
|
@include_id = false
|
@@ -82,11 +82,11 @@ module Sawmill
|
|
82
82
|
@pre_logger = nil
|
83
83
|
@post_logger = nil
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
# The log file to write to. This should be either an IO object, or
|
87
87
|
# a Sawmill::Rotater. Default is STDERR.
|
88
88
|
attr_accessor :logfile
|
89
|
-
|
89
|
+
|
90
90
|
# This option is passed to Sawmill::EntryProcessor::Format::new
|
91
91
|
attr_accessor :include_id
|
92
92
|
# This option is passed to Sawmill::EntryProcessor::Format::new
|
@@ -99,7 +99,7 @@ module Sawmill
|
|
99
99
|
attr_accessor :iso_8601_time
|
100
100
|
# This option is passed to Sawmill::EntryProcessor::Format::new
|
101
101
|
attr_accessor :length_limit
|
102
|
-
|
102
|
+
|
103
103
|
# This option is passed to Sawmill::Logger::new
|
104
104
|
attr_accessor :level
|
105
105
|
# This option is passed to Sawmill::Logger::new
|
@@ -110,7 +110,7 @@ module Sawmill
|
|
110
110
|
attr_accessor :record_progname
|
111
111
|
# This option is passed to Sawmill::Logger::new
|
112
112
|
attr_accessor :record_id_generator
|
113
|
-
|
113
|
+
|
114
114
|
# This option is passed to Sawmill::LogRecordMiddleware::new
|
115
115
|
attr_accessor :request_id_key
|
116
116
|
# This option is passed to Sawmill::LogRecordMiddleware::new
|
@@ -119,8 +119,8 @@ module Sawmill
|
|
119
119
|
attr_accessor :end_time_attribute
|
120
120
|
# This option is passed to Sawmill::LogRecordMiddleware::new
|
121
121
|
attr_accessor :elapsed_time_attribute
|
122
|
-
|
123
|
-
|
122
|
+
|
123
|
+
|
124
124
|
def pre_logger(proc_=false, &block_)
|
125
125
|
if block_
|
126
126
|
@pre_logger = block_
|
@@ -130,7 +130,7 @@ module Sawmill
|
|
130
130
|
@pre_logger
|
131
131
|
end
|
132
132
|
attr_writer :pre_logger
|
133
|
-
|
133
|
+
|
134
134
|
def post_logger(proc_=false, &block_)
|
135
135
|
if block_
|
136
136
|
@post_logger = block_
|
@@ -140,13 +140,13 @@ module Sawmill
|
|
140
140
|
@post_logger
|
141
141
|
end
|
142
142
|
attr_writer :post_logger
|
143
|
-
|
143
|
+
|
144
144
|
end
|
145
|
-
|
146
|
-
|
145
|
+
|
146
|
+
|
147
147
|
config.sawmill = Configuration.new
|
148
|
-
|
149
|
-
|
148
|
+
|
149
|
+
|
150
150
|
initializer :initialize_sawmill, :before => :initialize_logger do |app_|
|
151
151
|
myconfig_ = app_.config.sawmill
|
152
152
|
formatter_ = Formatter.new(myconfig_.logfile || ::STDERR,
|
@@ -173,9 +173,9 @@ module Sawmill
|
|
173
173
|
:pre_logger => myconfig_.pre_logger,
|
174
174
|
:post_logger => myconfig_.post_logger)
|
175
175
|
end
|
176
|
-
|
177
|
-
|
176
|
+
|
177
|
+
|
178
178
|
end
|
179
|
-
|
180
|
-
|
179
|
+
|
180
|
+
|
181
181
|
end
|
data/lib/sawmill/record.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
|
-
#
|
2
|
+
#
|
3
3
|
# Sawmill log record class
|
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,15 +35,15 @@
|
|
35
35
|
|
36
36
|
|
37
37
|
module Sawmill
|
38
|
-
|
39
|
-
|
38
|
+
|
39
|
+
|
40
40
|
# A log record.
|
41
|
-
#
|
41
|
+
#
|
42
42
|
# Log records are sequences of related log entries with a common record
|
43
43
|
# ID, beginning with a begin_record and ending with an end_record. Log
|
44
44
|
# records therefore can be analyzed as a group, for example to measure the
|
45
45
|
# time taken by an aggregate action such as a website request.
|
46
|
-
#
|
46
|
+
#
|
47
47
|
# Log records must follow a particular protocol:
|
48
48
|
#
|
49
49
|
# * The first entry must be begin_record.
|
@@ -51,21 +51,21 @@ module Sawmill
|
|
51
51
|
# * No other begin_record or end_record entries may be present.
|
52
52
|
# * All entries must have the same non-nil record_id.
|
53
53
|
# * Entries must be in nondecreasing order of timestamp.
|
54
|
-
#
|
54
|
+
#
|
55
55
|
# The only exception to these rules are incomplete log records, in which
|
56
56
|
# the final end_record is not present.
|
57
|
-
|
57
|
+
|
58
58
|
class Record
|
59
|
-
|
60
|
-
|
59
|
+
|
60
|
+
|
61
61
|
# Create a log record.
|
62
|
-
#
|
62
|
+
#
|
63
63
|
# You may optionally pass in an array of log entries to populate the
|
64
64
|
# record either partially or completely. If you do, note that
|
65
65
|
# Errors::IllegalRecordError may be raised if the log entries do not
|
66
66
|
# follow the log record protocol-- e.g. if the first entry is not a
|
67
67
|
# begin_record, etc.
|
68
|
-
|
68
|
+
|
69
69
|
def initialize(entries_=nil)
|
70
70
|
@started = false
|
71
71
|
@complete = false
|
@@ -79,32 +79,32 @@ module Sawmill
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
82
|
-
|
83
|
-
|
82
|
+
|
83
|
+
|
84
84
|
def to_s # :nodoc:
|
85
85
|
"#{type}: #{@line}"
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
def inspect # :nodoc:
|
89
89
|
"#<#{self.class}:0x#{object_id.to_s(16)} record_id=#{record_id.inspect}>"
|
90
90
|
end
|
91
|
-
|
92
|
-
|
91
|
+
|
92
|
+
|
93
93
|
def eql?(obj_) # :nodoc:
|
94
94
|
return false unless obj_.kind_of?(Record)
|
95
95
|
return @entries == obj_.instance_variable_get(:@entries)
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
def ==(obj_) # :nodoc:
|
99
99
|
eql?(obj_)
|
100
100
|
end
|
101
|
-
|
102
|
-
|
101
|
+
|
102
|
+
|
103
103
|
# Append a log entry to this record.
|
104
|
-
#
|
104
|
+
#
|
105
105
|
# Entries must be added in order. Raises Errors::IllegalRecordError if
|
106
106
|
# the log record protocol is violated
|
107
|
-
|
107
|
+
|
108
108
|
def add_entry(entry_)
|
109
109
|
empty_ = @entries.size == 0
|
110
110
|
if entry_.type == :unknown_data
|
@@ -156,70 +156,70 @@ module Sawmill
|
|
156
156
|
end
|
157
157
|
@entries << entry_
|
158
158
|
end
|
159
|
-
|
160
|
-
|
159
|
+
|
160
|
+
|
161
161
|
# Returns true if the initial begin_record has been added.
|
162
|
-
|
162
|
+
|
163
163
|
def started?
|
164
164
|
@started
|
165
165
|
end
|
166
|
-
|
167
|
-
|
166
|
+
|
167
|
+
|
168
168
|
# Returns true if the final end_record has been added.
|
169
|
-
|
169
|
+
|
170
170
|
def complete?
|
171
171
|
@complete
|
172
172
|
end
|
173
|
-
|
174
|
-
|
173
|
+
|
174
|
+
|
175
175
|
# Returns the record ID as a string.
|
176
|
-
|
176
|
+
|
177
177
|
def record_id
|
178
178
|
@entries.size > 0 ? @entries.first.record_id : nil
|
179
179
|
end
|
180
|
-
|
181
|
-
|
180
|
+
|
181
|
+
|
182
182
|
# Returns the beginning timestamp as a Time object, if the log record
|
183
183
|
# has been started, or nil otherwise.
|
184
|
-
|
184
|
+
|
185
185
|
def begin_timestamp
|
186
186
|
@started ? @entries.first.timestamp : nil
|
187
187
|
end
|
188
|
-
|
189
|
-
|
188
|
+
|
189
|
+
|
190
190
|
# Returns the ending timestamp as a Time object, if the log record
|
191
191
|
# has been completed, or nil otherwise.
|
192
|
-
|
192
|
+
|
193
193
|
def end_timestamp
|
194
194
|
@complete ? @entries.last.timestamp : nil
|
195
195
|
end
|
196
|
-
|
197
|
-
|
196
|
+
|
197
|
+
|
198
198
|
# Returns the number of log entries currently in this record.
|
199
|
-
|
199
|
+
|
200
200
|
def entry_count
|
201
201
|
@entries.size
|
202
202
|
end
|
203
|
-
|
203
|
+
|
204
204
|
alias_method :size, :entry_count
|
205
|
-
|
206
|
-
|
205
|
+
|
206
|
+
|
207
207
|
# Returns the number of message entries currently in this record.
|
208
|
-
|
208
|
+
|
209
209
|
def message_count
|
210
210
|
@message_count
|
211
211
|
end
|
212
|
-
|
213
|
-
|
212
|
+
|
213
|
+
|
214
214
|
# Iterate over all log entries, passing each to the given block.
|
215
|
-
|
215
|
+
|
216
216
|
def each_entry(&block_)
|
217
217
|
@entries.each(&block_)
|
218
218
|
end
|
219
|
-
|
220
|
-
|
219
|
+
|
220
|
+
|
221
221
|
# Iterate over all log message entries, passing each to the given block.
|
222
|
-
|
222
|
+
|
223
223
|
def each_message
|
224
224
|
@entries.each do |entry_|
|
225
225
|
if entry_.type == :message
|
@@ -227,53 +227,53 @@ module Sawmill
|
|
227
227
|
end
|
228
228
|
end
|
229
229
|
end
|
230
|
-
|
231
|
-
|
230
|
+
|
231
|
+
|
232
232
|
# Returns an array of all log entries.
|
233
|
-
|
233
|
+
|
234
234
|
def all_entries
|
235
235
|
@entries.dup
|
236
236
|
end
|
237
|
-
|
238
|
-
|
237
|
+
|
238
|
+
|
239
239
|
# Returns an array of all log message entries.
|
240
|
-
|
240
|
+
|
241
241
|
def all_messages
|
242
242
|
@entries.find_all{ |entry_| entry_.type == :message }
|
243
243
|
end
|
244
|
-
|
245
|
-
|
244
|
+
|
245
|
+
|
246
246
|
# Get the value of the given attribute.
|
247
247
|
# Returns a string if the attribute has a single value.
|
248
248
|
# Returns an array of strings if the attribute has multiple values.
|
249
249
|
# Returns nil if the attribute is not set.
|
250
|
-
|
250
|
+
|
251
251
|
def attribute(key_)
|
252
252
|
@attributes[key_.to_s]
|
253
253
|
end
|
254
|
-
|
255
|
-
|
254
|
+
|
255
|
+
|
256
256
|
# Get an array of attribute keys present in this log record.
|
257
|
-
|
257
|
+
|
258
258
|
def attribute_keys
|
259
259
|
@attributes.keys
|
260
260
|
end
|
261
|
-
|
262
|
-
|
261
|
+
|
262
|
+
|
263
263
|
# Compute and cache a value.
|
264
264
|
# This is a convenient way for RecordProcessor objects to share
|
265
265
|
# computed information about a record.
|
266
|
-
#
|
266
|
+
#
|
267
267
|
# Returns the computed value with the given key.
|
268
268
|
# If the given key has not been computed yet, computes it by
|
269
269
|
# calling the given block and passing self.
|
270
|
-
|
270
|
+
|
271
271
|
def compute(key_)
|
272
272
|
@computations[key_] ||= yield self
|
273
273
|
end
|
274
|
-
|
275
|
-
|
274
|
+
|
275
|
+
|
276
276
|
end
|
277
|
-
|
278
|
-
|
277
|
+
|
278
|
+
|
279
279
|
end
|