sawmill 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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.2.2')
92
- s_.add_dependency('versionomy', '>= 0.1.2')
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
@@ -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(:filepath => filepath_,
170
- :max_logfile_size => max_size_, :shift_period => period_))
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>:suffix</tt>::
229
- # The logfile name prefix.
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(:prefix => filepath_,
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
- io_array_ = []
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
- io_ = ::File.open(path_)
308
- io_ = ::Zlib::GzipReader.new(io_) if path_ =~ /\.gz$/
309
- io_array_ << io_
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
- opts_[:finish] ? processor_.finish : nil
391
+ finish_opt_ ? processor_.finish : nil
319
392
  end
320
393
 
321
394
 
@@ -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
- io_array_.each{ |io_| _enqueue(Parser.new(io_, nil, opts_)) }
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_)
@@ -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_ = @io.gets
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_ = @io.gets
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>:prefix</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>:suffix</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_, ::File::CREAT | ::File::WRONLY | ::File::APPEND)
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>:filepath</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>:max_logfile_size</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_, ::File::CREAT | ::File::WRONLY | ::File::APPEND)
125
+ file_ = ::File.open(path_, @mode)
119
126
  file_.sync = true
120
127
  @open_handles[handle_] = true
121
128
  file_
@@ -37,7 +37,7 @@
37
37
  module Sawmill
38
38
 
39
39
  # Current gem version, as a frozen string.
40
- VERSION_STRING = '0.0.3'.freeze
40
+ VERSION_STRING = '0.0.4'.freeze
41
41
 
42
42
  # Current gem version, as a Versionomy::Value.
43
43
  VERSION = ::Versionomy.parse(VERSION_STRING, :standard)
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.3
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-01 01:00:00 -07:00
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.2.2
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.1.2
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