sawmill 0.0.3 → 0.0.4
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 +6 -0
- data/Rakefile +2 -2
- data/lib/sawmill/interface.rb +83 -10
- data/lib/sawmill/multi_parser.rb +8 -1
- data/lib/sawmill/parser.rb +21 -2
- data/lib/sawmill/rotater/date_based_log_file.rb +12 -5
- data/lib/sawmill/rotater/shifting_log_file.rb +12 -5
- data/lib/sawmill/version.rb +1 -1
- metadata +4 -4
data/History.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
=== 0.0.4 / 2009-??-??
|
2
|
+
|
3
|
+
* API CHANGE: Renamed DateBasedLogFile options :prefix and :suffix to :path_prefix and :path_suffix
|
4
|
+
* API CHANGE: Renamed ShiftingLogFile options :filepath and :max_logfile_size to :file_path and :max_file_size
|
5
|
+
* Encoding can now be specified in file reading and writing methods (Rotaters and convenience interface methods)
|
6
|
+
|
1
7
|
=== 0.0.3 / 2009-10-31
|
2
8
|
|
3
9
|
* API CHANGE: Renamed processor close methods to "finish" and introduced return value semantics for passing "final" information back up the processor tree.
|
data/Rakefile
CHANGED
@@ -88,8 +88,8 @@ gemspec_ = ::Gem::Specification.new do |s_|
|
|
88
88
|
s_.has_rdoc = true
|
89
89
|
s_.test_files = ::FileList['tests/tc_*.rb']
|
90
90
|
s_.platform = ::Gem::Platform::RUBY
|
91
|
-
s_.add_dependency('blockenspiel', '>= 0.
|
92
|
-
s_.add_dependency('versionomy', '>= 0.
|
91
|
+
s_.add_dependency('blockenspiel', '>= 0.3.0')
|
92
|
+
s_.add_dependency('versionomy', '>= 0.2.0')
|
93
93
|
end
|
94
94
|
::Rake::GemPackageTask.new(gemspec_) do |task_|
|
95
95
|
task_.need_zip = false
|
data/lib/sawmill/interface.rb
CHANGED
@@ -164,10 +164,13 @@ module Sawmill
|
|
164
164
|
# The maximum number of old logfiles (files with indexes) to
|
165
165
|
# keep. Files beyond this history size will be automatically
|
166
166
|
# deleted. Default is 1. This value must be at least 1.
|
167
|
+
# <tt>:encoding</tt>::
|
168
|
+
# Specify an encoding name for file data. (Ruby 1.9 only)
|
169
|
+
# If not specified, uses the default external encoding.
|
167
170
|
|
168
171
|
def shifting_logfile(filepath_, period_, max_size_, opts_={})
|
169
|
-
rotater_ = Rotater.new(Rotater::ShiftingLogFile, opts_.merge(:
|
170
|
-
:
|
172
|
+
rotater_ = Rotater.new(Rotater::ShiftingLogFile, opts_.merge(:file_path => filepath_,
|
173
|
+
:max_file_size => max_size_, :shift_period => period_))
|
171
174
|
processor_ = EntryProcessor::Format.new(rotater_, opts_)
|
172
175
|
Logger.new(opts_.merge(:processor => processor_))
|
173
176
|
end
|
@@ -225,16 +228,19 @@ module Sawmill
|
|
225
228
|
# <tt>:basedir</tt>::
|
226
229
|
# The base directory used if the filepath is a relative path.
|
227
230
|
# If not specified, the current working directory is used.
|
228
|
-
# <tt>:
|
229
|
-
# The logfile name
|
231
|
+
# <tt>:name_suffix</tt>::
|
232
|
+
# The logfile name suffix.
|
230
233
|
# In the filename "rails.2009-10-11.log", the suffix is ".log".
|
231
234
|
# If not specified, defaults to ".log".
|
232
235
|
# <tt>:local_datestamps</tt>::
|
233
236
|
# If true, use the local timezone to create datestamps.
|
234
237
|
# The default is to use UTC.
|
238
|
+
# <tt>:encoding</tt>::
|
239
|
+
# Specify an encoding name for file data. (Ruby 1.9 only)
|
240
|
+
# If not specified, uses the default external encoding.
|
235
241
|
|
236
242
|
def date_based_logfile(filepath_, frequency_, opts_={})
|
237
|
-
rotater_ = Rotater.new(Rotater::DateBasedLogFile, opts_.merge(:
|
243
|
+
rotater_ = Rotater.new(Rotater::DateBasedLogFile, opts_.merge(:path_prefix => filepath_,
|
238
244
|
:turnover_frequency => frequency_))
|
239
245
|
processor_ = EntryProcessor::Format.new(rotater_, opts_)
|
240
246
|
Logger.new(opts_.merge(:processor => processor_))
|
@@ -254,6 +260,17 @@ module Sawmill
|
|
254
260
|
# <tt>:emit_incomplete_records_at_eof</tt>::
|
255
261
|
# If set to true, causes any incomplete log records to be emitted
|
256
262
|
# in their incomplete state when EOF is reached on all streams.
|
263
|
+
#
|
264
|
+
# Additionally, these options are recognized:
|
265
|
+
#
|
266
|
+
# <tt>:encoding</tt>::
|
267
|
+
# Specify an encoding for file data. (Ruby 1.9 only.)
|
268
|
+
# You may specify an encoding name or an encoding object.
|
269
|
+
# If not specified, uses the default external encoding.
|
270
|
+
# <tt>:internal_encoding</tt>::
|
271
|
+
# Specify an encoding to transcode to. (Ruby 1.9 only.)
|
272
|
+
# You may specify an encoding name or an encoding object.
|
273
|
+
# If not specified, uses the default internal encoding.
|
257
274
|
|
258
275
|
def open_entries(globs_, opts_={}, &block_)
|
259
276
|
processor_ = EntryProcessor.build(&block_)
|
@@ -274,6 +291,17 @@ module Sawmill
|
|
274
291
|
# <tt>:emit_incomplete_records_at_eof</tt>::
|
275
292
|
# If set to true, causes any incomplete log records to be emitted
|
276
293
|
# in their incomplete state when EOF is reached on all streams.
|
294
|
+
#
|
295
|
+
# Additionally, these options are recognized:
|
296
|
+
#
|
297
|
+
# <tt>:encoding</tt>::
|
298
|
+
# Specify an encoding for file data. (Ruby 1.9 only.)
|
299
|
+
# You may specify an encoding name or an encoding object.
|
300
|
+
# If not specified, uses the default external encoding.
|
301
|
+
# <tt>:internal_encoding</tt>::
|
302
|
+
# Specify an encoding to transcode to. (Ruby 1.9 only.)
|
303
|
+
# You may specify an encoding name or an encoding object.
|
304
|
+
# If not specified, uses the default internal encoding.
|
277
305
|
|
278
306
|
def open_records(globs_, opts_={}, &block_)
|
279
307
|
processor_ = RecordProcessor.build(&block_)
|
@@ -293,29 +321,74 @@ module Sawmill
|
|
293
321
|
# <tt>:emit_incomplete_records_at_eof</tt>::
|
294
322
|
# If set to true, causes any incomplete log records to be emitted
|
295
323
|
# in their incomplete state when EOF is reached on all streams.
|
324
|
+
#
|
325
|
+
# Additionally, these options are recognized:
|
326
|
+
#
|
296
327
|
# <tt>:finish</tt>::
|
297
328
|
# If set to true, the "finish" method is called on the processor
|
298
329
|
# after all files have been parsed, and the return value is returned.
|
299
330
|
# Otherwise, the processor is left open and nil is returned.
|
331
|
+
# <tt>:encoding</tt>::
|
332
|
+
# Specify an encoding for file data. (Ruby 1.9 only.)
|
333
|
+
# You may specify an encoding name or an encoding object.
|
334
|
+
# If not specified, uses the default external encoding.
|
335
|
+
# <tt>:internal_encoding</tt>::
|
336
|
+
# Specify an encoding to transcode to. (Ruby 1.9 only.)
|
337
|
+
# You may specify an encoding name or an encoding object.
|
338
|
+
# If not specified, uses the default internal encoding.
|
300
339
|
|
301
340
|
def open_files(globs_, processor_, opts_={})
|
302
|
-
|
341
|
+
finish_opt_ = opts_.delete(:finish)
|
342
|
+
encoding_ = opts_.delete(:encoding)
|
343
|
+
internal_encoding_ = opts_.delete(:internal_encoding)
|
344
|
+
mode_ = 'r'
|
345
|
+
if defined?(::Encoding)
|
346
|
+
if encoding_
|
347
|
+
encoding_ = ::Encoding.find(encoding_) unless encoding_.respond_to?(:name)
|
348
|
+
encoding_ = nil if encoding_ == ::Encoding.default_external
|
349
|
+
end
|
350
|
+
if internal_encoding_
|
351
|
+
internal_encoding_ = ::Encoding.find(internal_encoding_) unless internal_encoding_.respond_to?(:name)
|
352
|
+
internal_encoding_ = nil if internal_encoding_ == ::Encoding.default_internal
|
353
|
+
end
|
354
|
+
if encoding_
|
355
|
+
mode_ << ":#{encoding_.name}"
|
356
|
+
elsif internal_encoding_
|
357
|
+
mode_ << ":#{::Encoding.default_external.name}"
|
358
|
+
end
|
359
|
+
mode_ << ":#{internal_encoding_.name}" if internal_encoding_
|
360
|
+
else
|
361
|
+
encoding_ = nil
|
362
|
+
internal_encoding_ = nil
|
363
|
+
end
|
303
364
|
globs_ = [globs_] unless globs_.kind_of?(::Array)
|
365
|
+
io_array_ = []
|
366
|
+
encoding_array_ = []
|
367
|
+
internal_encoding_array_ = []
|
304
368
|
begin
|
305
369
|
globs_.each do |glob_|
|
306
370
|
::Dir.glob(glob_).each do |path_|
|
307
|
-
|
308
|
-
|
309
|
-
|
371
|
+
if path_ =~ /\.gz$/
|
372
|
+
io_ = ::File.open(path_, 'rb')
|
373
|
+
io_array_ << ::Zlib::GzipReader.new(io_)
|
374
|
+
encoding_array_ << encoding_
|
375
|
+
internal_encoding_array_ << internal_encoding_
|
376
|
+
else
|
377
|
+
io_array_ << ::File.open(path_, mode_)
|
378
|
+
encoding_array_ << nil
|
379
|
+
internal_encoding_array_ << nil
|
380
|
+
end
|
310
381
|
end
|
311
382
|
end
|
383
|
+
opts_[:encoding_array] = encoding_array_ if encoding_array_.find{ |elem_| elem_ }
|
384
|
+
opts_[:internal_encoding_array] = internal_encoding_array_ if internal_encoding_array_.find{ |elem_| elem_ }
|
312
385
|
MultiParser.new(io_array_, processor_, opts_).parse_all
|
313
386
|
ensure
|
314
387
|
io_array_.each do |io_|
|
315
388
|
io_.close rescue nil
|
316
389
|
end
|
317
390
|
end
|
318
|
-
|
391
|
+
finish_opt_ ? processor_.finish : nil
|
319
392
|
end
|
320
393
|
|
321
394
|
|
data/lib/sawmill/multi_parser.rb
CHANGED
@@ -64,7 +64,14 @@ module Sawmill
|
|
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 }
|
66
66
|
@queue = Util::Queue.new
|
67
|
-
|
67
|
+
encoding_array_ = opts_.delete(:encoding_array)
|
68
|
+
internal_encoding_array_ = opts_.delete(:internal_encoding_array)
|
69
|
+
io_array_.each_with_index do |io_, index_|
|
70
|
+
opts2_ = opts_.dup
|
71
|
+
opts2_[:encoding] = encoding_array_[index_] if encoding_array_
|
72
|
+
opts2_[:internal_encoding] = internal_encoding_array_[index_] if internal_encoding_array_
|
73
|
+
_enqueue(Parser.new(io_, nil, opts2_))
|
74
|
+
end
|
68
75
|
@processor = nil
|
69
76
|
if processor_.respond_to?(:record) && processor_.respond_to?(:extra_entry)
|
70
77
|
@processor = RecordBuilder.new(processor_)
|
data/lib/sawmill/parser.rb
CHANGED
@@ -78,6 +78,12 @@ module Sawmill
|
|
78
78
|
@emit_incomplete_records_at_eof = opts_[:emit_incomplete_records_at_eof]
|
79
79
|
@current_record_id = nil
|
80
80
|
@parser_directives = {}
|
81
|
+
@encoding = opts_[:encoding]
|
82
|
+
@internal_encoding = opts_[:internal_encoding]
|
83
|
+
if defined?(::Encoding)
|
84
|
+
@encoding = ::Encoding.find(@encoding) if @encoding && !@encoding.kind_of?(::Encoding)
|
85
|
+
@internal_encoding = ::Encoding.find(@internal_encoding) if @internal_encoding && !@internal_encoding.kind_of?(::Encoding)
|
86
|
+
end
|
81
87
|
end
|
82
88
|
|
83
89
|
|
@@ -86,7 +92,7 @@ module Sawmill
|
|
86
92
|
# Returns nil if EOF has been reached.
|
87
93
|
|
88
94
|
def parse_one_entry
|
89
|
-
str_ =
|
95
|
+
str_ = _get_next_line
|
90
96
|
entry_ = nil
|
91
97
|
if str_
|
92
98
|
match_ = LINE_REGEXP.match(str_)
|
@@ -113,7 +119,7 @@ module Sawmill
|
|
113
119
|
count_ = $1.length
|
114
120
|
str_ = $` + "\\"*(count_/2)
|
115
121
|
while count_ % 2 == 1
|
116
|
-
str2_ =
|
122
|
+
str2_ = _get_next_line
|
117
123
|
if str2_ && str2_ =~ /(\\*)\n?$/
|
118
124
|
count_ = $1.length
|
119
125
|
str_ << "\n" << $` << "\\"*(count_/2)
|
@@ -174,6 +180,19 @@ module Sawmill
|
|
174
180
|
end
|
175
181
|
|
176
182
|
|
183
|
+
private
|
184
|
+
|
185
|
+
|
186
|
+
def _get_next_line # :nodoc:
|
187
|
+
str_ = @io.gets
|
188
|
+
if str_
|
189
|
+
str_.force_encoding(@encoding) if @encoding
|
190
|
+
str_.encode!(@internal_encoding) if @internal_encoding
|
191
|
+
end
|
192
|
+
str_
|
193
|
+
end
|
194
|
+
|
195
|
+
|
177
196
|
end
|
178
197
|
|
179
198
|
|
@@ -68,23 +68,26 @@ module Sawmill
|
|
68
68
|
# <tt>:basedir</tt>::
|
69
69
|
# The base directory used if the filepath is a relative path.
|
70
70
|
# If not specified, the current working directory is used.
|
71
|
-
# <tt>:
|
71
|
+
# <tt>:path_prefix</tt>::
|
72
72
|
# The logfile path prefix.
|
73
73
|
# In the filename "rails.2009-10-11.log", the prefix is "rails".
|
74
74
|
# If not specified, defaults to "sawmill".
|
75
|
-
# <tt>:
|
75
|
+
# <tt>:path_suffix</tt>::
|
76
76
|
# The logfile name prefix.
|
77
77
|
# In the filename "rails.2009-10-11.log", the suffix is ".log".
|
78
78
|
# If not specified, defaults to ".log".
|
79
79
|
# <tt>:local_datestamps</tt>::
|
80
80
|
# If true, use the local timezone to create datestamps.
|
81
81
|
# The default is to use UTC.
|
82
|
+
# <tt>:encoding</tt>::
|
83
|
+
# Specify an encoding name for file data. (Ruby 1.9 only)
|
84
|
+
# If not specified, uses the default external encoding.
|
82
85
|
|
83
86
|
def initialize(options_)
|
84
87
|
@turnover_frequency = options_[:turnover_frequency] || :none
|
85
|
-
@prefix = ::File.expand_path(options_[:prefix] || 'sawmill',
|
88
|
+
@prefix = ::File.expand_path(options_[:path_prefix] || options_[:prefix] || 'sawmill',
|
86
89
|
options_[:basedir] || options_[:dirname] || ::Dir.getwd)
|
87
|
-
@suffix = options_[:suffix] || '.log'
|
90
|
+
@suffix = options_[:path_suffix] || options_[:suffix] || '.log'
|
88
91
|
@local_datestamps = options_[:local_datestamps]
|
89
92
|
@date_pattern =
|
90
93
|
case @turnover_frequency
|
@@ -94,6 +97,10 @@ module Sawmill
|
|
94
97
|
when :hourly then "%Y-%m-%d-%H"
|
95
98
|
else nil
|
96
99
|
end
|
100
|
+
@mode = 'a'
|
101
|
+
if defined?(::Encoding) && (encoding_ = options_[:encoding])
|
102
|
+
@mode << ":#{encoding_}"
|
103
|
+
end
|
97
104
|
end
|
98
105
|
|
99
106
|
|
@@ -118,7 +125,7 @@ module Sawmill
|
|
118
125
|
else
|
119
126
|
path_ = @prefix+@suffix
|
120
127
|
end
|
121
|
-
file_ = ::File.open(path_,
|
128
|
+
file_ = ::File.open(path_, @mode)
|
122
129
|
file_.sync = true
|
123
130
|
file_
|
124
131
|
end
|
@@ -59,11 +59,11 @@ module Sawmill
|
|
59
59
|
# <tt>:basedir</tt>::
|
60
60
|
# The base directory used if the filepath is a relative path.
|
61
61
|
# If not specified, the current working directory is used.
|
62
|
-
# <tt>:
|
62
|
+
# <tt>:file_path</tt>::
|
63
63
|
# The path to the log file. This may be an absolute path or a
|
64
64
|
# path relative to basedir.
|
65
65
|
# If not specified, defaults to "sawmill.log".
|
66
|
-
# <tt>:
|
66
|
+
# <tt>:max_file_size</tt>::
|
67
67
|
# A logfile will try to rotate once it has reached this size in
|
68
68
|
# bytes. If not specified, the file size is not checked.
|
69
69
|
# <tt>:shift_period</tt>::
|
@@ -76,9 +76,12 @@ module Sawmill
|
|
76
76
|
# The maximum number of old logfiles (files with indexes) to
|
77
77
|
# keep. Files beyond this history size will be automatically
|
78
78
|
# deleted. Default is 1. This value must be at least 1.
|
79
|
+
# <tt>:encoding</tt>::
|
80
|
+
# Specify an encoding name for file data. (Ruby 1.9 only)
|
81
|
+
# If not specified, uses the default external encoding.
|
79
82
|
|
80
83
|
def initialize(options_)
|
81
|
-
@max_logfile_size = options_[:max_logfile_size]
|
84
|
+
@max_logfile_size = options_[:max_file_size] || options_[:max_logfile_size]
|
82
85
|
@shift_period = options_[:shift_period]
|
83
86
|
case @shift_period
|
84
87
|
when :yearly
|
@@ -92,11 +95,15 @@ module Sawmill
|
|
92
95
|
end
|
93
96
|
@history_size = options_[:history_size].to_i
|
94
97
|
@history_size = 1 if @history_size < 1 && (@max_logfile_size || @shift_period)
|
95
|
-
@normal_path = ::File.expand_path(options_[:filepath] || 'sawmill.log',
|
98
|
+
@normal_path = ::File.expand_path(options_[:file_path] || options_[:filepath] || 'sawmill.log',
|
96
99
|
options_[:basedir] || ::Dir.getwd)
|
97
100
|
@preferred_handle = 0
|
98
101
|
@open_handles = {}
|
99
102
|
@last_shift = ::Time.now
|
103
|
+
@mode = 'a'
|
104
|
+
if defined?(::Encoding) && (encoding_ = options_[:encoding])
|
105
|
+
@mode << ":#{encoding_}"
|
106
|
+
end
|
100
107
|
end
|
101
108
|
|
102
109
|
|
@@ -115,7 +122,7 @@ module Sawmill
|
|
115
122
|
else
|
116
123
|
path_ = "#{@normal_path}.#{@preferred_handle-handle_-1}"
|
117
124
|
end
|
118
|
-
file_ = ::File.open(path_,
|
125
|
+
file_ = ::File.open(path_, @mode)
|
119
126
|
file_.sync = true
|
120
127
|
@open_handles[handle_] = true
|
121
128
|
file_
|
data/lib/sawmill/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sawmill
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-06 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.
|
23
|
+
version: 0.3.0
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: versionomy
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.2.0
|
34
34
|
version:
|
35
35
|
description: Sawmill is a logging and log analysis system for Ruby. It extends the basic Ruby logging facility with log records and parsing abilities.
|
36
36
|
email: dazuma@gmail.com
|