sawmill 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +8 -1
- data/README.rdoc +1 -1
- data/Rakefile +1 -2
- data/lib/sawmill.rb +1 -8
- data/lib/sawmill/interface.rb +19 -16
- data/lib/sawmill/parser.rb +29 -7
- data/lib/sawmill/rotater.rb +47 -2
- data/lib/sawmill/rotater/date_based_log_file.rb +1 -8
- data/lib/sawmill/rotater/shifting_log_file.rb +1 -8
- data/lib/sawmill/version.rb +10 -3
- data/tests/tc_entry_processors.rb +1 -0
- data/tests/tc_formatter_parser.rb +1 -0
- data/tests/tc_levels.rb +1 -0
- data/tests/tc_logger.rb +1 -0
- data/tests/tc_multi_parser.rb +1 -0
- data/tests/tc_record_processors.rb +1 -0
- data/tests/tc_records.rb +4 -2
- data/tests/tc_reports.rb +1 -0
- metadata +3 -13
data/History.rdoc
CHANGED
@@ -1,4 +1,11 @@
|
|
1
|
-
=== 0.0.
|
1
|
+
=== 0.0.5 / 2009-11-08
|
2
|
+
|
3
|
+
* API CHANGE: Reworked how string encoding is specified. Default encoding for both reading and writing is now ASCII-8BIT unless specified in the API or within the file as a parser directive.
|
4
|
+
* Handle encoding errors more gracefully by replacing characters rather than raising exceptions.
|
5
|
+
* Added a parser directive to set logfile encoding.
|
6
|
+
* Versionomy is no longer a hard dependency-- it is now used only if available.
|
7
|
+
|
8
|
+
=== 0.0.4 / 2009-11-06
|
2
9
|
|
3
10
|
* API CHANGE: Renamed DateBasedLogFile options :prefix and :suffix to :path_prefix and :path_suffix
|
4
11
|
* API CHANGE: Renamed ShiftingLogFile options :filepath and :max_logfile_size to :file_path and :max_file_size
|
data/README.rdoc
CHANGED
@@ -26,7 +26,7 @@ Sawmill is an extension to the standard ruby Logger mechanism that enables autom
|
|
26
26
|
=== Requirements
|
27
27
|
|
28
28
|
* Ruby 1.8.6 or later (1.8.7 recommended), Ruby 1.9.1 or later, or JRuby 1.4 or later.
|
29
|
-
*
|
29
|
+
* Blockenspiel 0.3.1 or later.
|
30
30
|
|
31
31
|
=== Installation
|
32
32
|
|
data/Rakefile
CHANGED
@@ -88,8 +88,7 @@ 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.3.
|
92
|
-
s_.add_dependency('versionomy', '>= 0.2.0')
|
91
|
+
s_.add_dependency('blockenspiel', '>= 0.3.1')
|
93
92
|
end
|
94
93
|
::Rake::GemPackageTask.new(gemspec_) do |task_|
|
95
94
|
task_.need_zip = false
|
data/lib/sawmill.rb
CHANGED
@@ -34,14 +34,7 @@
|
|
34
34
|
;
|
35
35
|
|
36
36
|
|
37
|
-
|
38
|
-
require 'blockenspiel'
|
39
|
-
require 'versionomy'
|
40
|
-
rescue ::LoadError
|
41
|
-
require 'rubygems'
|
42
|
-
require 'blockenspiel'
|
43
|
-
require 'versionomy'
|
44
|
-
end
|
37
|
+
require 'blockenspiel'
|
45
38
|
|
46
39
|
|
47
40
|
dir_ = ::File.expand_path('sawmill', ::File.dirname(__FILE__))
|
data/lib/sawmill/interface.rb
CHANGED
@@ -266,11 +266,13 @@ module Sawmill
|
|
266
266
|
# <tt>:encoding</tt>::
|
267
267
|
# Specify an encoding for file data. (Ruby 1.9 only.)
|
268
268
|
# You may specify an encoding name or an encoding object.
|
269
|
-
# If not specified,
|
269
|
+
# If not specified, reads raw bytes (e.g. defaults to 'ASCII-8BIT').
|
270
|
+
# Note that the encoding may also be modified by the file itself,
|
271
|
+
# if an appropriate parser directive is encountered.
|
270
272
|
# <tt>:internal_encoding</tt>::
|
271
273
|
# Specify an encoding to transcode to. (Ruby 1.9 only.)
|
272
274
|
# You may specify an encoding name or an encoding object.
|
273
|
-
# If not specified, uses the
|
275
|
+
# If not specified, uses the encoding as read from the file.
|
274
276
|
|
275
277
|
def open_entries(globs_, opts_={}, &block_)
|
276
278
|
processor_ = EntryProcessor.build(&block_)
|
@@ -297,11 +299,13 @@ module Sawmill
|
|
297
299
|
# <tt>:encoding</tt>::
|
298
300
|
# Specify an encoding for file data. (Ruby 1.9 only.)
|
299
301
|
# You may specify an encoding name or an encoding object.
|
300
|
-
# If not specified,
|
302
|
+
# If not specified, reads raw bytes (e.g. defaults to 'ASCII-8BIT').
|
303
|
+
# Note that the encoding may also be modified by the file itself,
|
304
|
+
# if an appropriate parser directive is encountered.
|
301
305
|
# <tt>:internal_encoding</tt>::
|
302
306
|
# Specify an encoding to transcode to. (Ruby 1.9 only.)
|
303
307
|
# You may specify an encoding name or an encoding object.
|
304
|
-
# If not specified, uses the
|
308
|
+
# If not specified, uses the encoding as read from the file.
|
305
309
|
|
306
310
|
def open_records(globs_, opts_={}, &block_)
|
307
311
|
processor_ = RecordProcessor.build(&block_)
|
@@ -331,11 +335,13 @@ module Sawmill
|
|
331
335
|
# <tt>:encoding</tt>::
|
332
336
|
# Specify an encoding for file data. (Ruby 1.9 only.)
|
333
337
|
# You may specify an encoding name or an encoding object.
|
334
|
-
# If not specified,
|
338
|
+
# If not specified, reads raw bytes (e.g. defaults to 'ASCII-8BIT').
|
339
|
+
# Note that the encoding may also be modified by the file itself,
|
340
|
+
# if an appropriate parser directive is encountered.
|
335
341
|
# <tt>:internal_encoding</tt>::
|
336
342
|
# Specify an encoding to transcode to. (Ruby 1.9 only.)
|
337
343
|
# You may specify an encoding name or an encoding object.
|
338
|
-
# If not specified, uses the
|
344
|
+
# If not specified, uses the encoding as read from the file.
|
339
345
|
|
340
346
|
def open_files(globs_, processor_, opts_={})
|
341
347
|
finish_opt_ = opts_.delete(:finish)
|
@@ -343,20 +349,17 @@ module Sawmill
|
|
343
349
|
internal_encoding_ = opts_.delete(:internal_encoding)
|
344
350
|
mode_ = 'r'
|
345
351
|
if defined?(::Encoding)
|
346
|
-
if encoding_
|
347
|
-
encoding_ = ::Encoding
|
348
|
-
|
352
|
+
if !encoding_
|
353
|
+
encoding_ = ::Encoding::ASCII_8BIT
|
354
|
+
elsif encoding_ && !encoding_.respond_to?(:name)
|
355
|
+
encoding_ = ::Encoding.find(encoding_)
|
349
356
|
end
|
350
|
-
if internal_encoding_
|
351
|
-
internal_encoding_ = ::Encoding.find(internal_encoding_)
|
352
|
-
internal_encoding_ = nil if internal_encoding_ == ::Encoding.default_internal
|
357
|
+
if internal_encoding_ && !internal_encoding_.respond_to?(:name)
|
358
|
+
internal_encoding_ = ::Encoding.find(internal_encoding_)
|
353
359
|
end
|
354
360
|
if encoding_
|
355
361
|
mode_ << ":#{encoding_.name}"
|
356
|
-
elsif internal_encoding_
|
357
|
-
mode_ << ":#{::Encoding.default_external.name}"
|
358
362
|
end
|
359
|
-
mode_ << ":#{internal_encoding_.name}" if internal_encoding_
|
360
363
|
else
|
361
364
|
encoding_ = nil
|
362
365
|
internal_encoding_ = nil
|
@@ -376,7 +379,7 @@ module Sawmill
|
|
376
379
|
else
|
377
380
|
io_array_ << ::File.open(path_, mode_)
|
378
381
|
encoding_array_ << nil
|
379
|
-
internal_encoding_array_ <<
|
382
|
+
internal_encoding_array_ << internal_encoding_
|
380
383
|
end
|
381
384
|
end
|
382
385
|
end
|
data/lib/sawmill/parser.rb
CHANGED
@@ -46,6 +46,8 @@ module Sawmill
|
|
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+)=(.*)$/
|
48
48
|
ATTRIBUTE_REGEXP = /^([[:graph:]]+)\s([=+\/-])\s/
|
49
|
+
SUPPORTS_ENCODING = defined?(::Encoding)
|
50
|
+
ENCODING_OPTS = {:invalid => :replace, :undef => :replace}
|
49
51
|
# :startdoc:
|
50
52
|
|
51
53
|
|
@@ -65,6 +67,16 @@ module Sawmill
|
|
65
67
|
# <tt>:emit_incomplete_records_at_eof</tt>
|
66
68
|
# If set to true, causes any incomplete log records to be emitted
|
67
69
|
# in their incomplete state when EOF is reached.
|
70
|
+
# <tt>:encoding</tt>
|
71
|
+
# Overrides the IO encoding. (Ruby 1.9 only). If specified, lines
|
72
|
+
# read from the stream are assumed to be in this encoding. If not
|
73
|
+
# specified, the IO's default encoding is honored.
|
74
|
+
# Note that the encoding may also be modified by the stream itself,
|
75
|
+
# if an appropriate parser directive is encountered.
|
76
|
+
# <tt>:internal_encoding</tt>
|
77
|
+
# Transcodes strings as they are read. (Ruby 1.9 only). If specified,
|
78
|
+
# lines are transcoded into this encoding after they are read from
|
79
|
+
# the stream. If not specified, no post-transcoding is done.
|
68
80
|
|
69
81
|
def initialize(io_, processor_, opts_={})
|
70
82
|
@io = io_
|
@@ -77,11 +89,10 @@ module Sawmill
|
|
77
89
|
@levels = opts_[:levels] || STANDARD_LEVELS
|
78
90
|
@emit_incomplete_records_at_eof = opts_[:emit_incomplete_records_at_eof]
|
79
91
|
@current_record_id = nil
|
80
|
-
|
81
|
-
|
82
|
-
@internal_encoding = opts_[:internal_encoding]
|
83
|
-
if defined?(::Encoding)
|
92
|
+
if SUPPORTS_ENCODING
|
93
|
+
@encoding = opts_[:encoding]
|
84
94
|
@encoding = ::Encoding.find(@encoding) if @encoding && !@encoding.kind_of?(::Encoding)
|
95
|
+
@internal_encoding = opts_[:internal_encoding]
|
85
96
|
@internal_encoding = ::Encoding.find(@internal_encoding) if @internal_encoding && !@internal_encoding.kind_of?(::Encoding)
|
86
97
|
end
|
87
98
|
end
|
@@ -158,7 +169,7 @@ module Sawmill
|
|
158
169
|
end
|
159
170
|
else
|
160
171
|
if str_ =~ DIRECTIVE_REGEXP
|
161
|
-
|
172
|
+
_set_parser_directive($1, $2)
|
162
173
|
end
|
163
174
|
entry_ = Entry::UnknownData.new(str_.chomp)
|
164
175
|
@processor.unknown_data(entry_) if @processor.respond_to?(:unknown_data)
|
@@ -185,14 +196,25 @@ module Sawmill
|
|
185
196
|
|
186
197
|
def _get_next_line # :nodoc:
|
187
198
|
str_ = @io.gets
|
188
|
-
if str_
|
199
|
+
if str_ && SUPPORTS_ENCODING
|
189
200
|
str_.force_encoding(@encoding) if @encoding
|
190
|
-
str_.encode!(@internal_encoding) if @internal_encoding
|
201
|
+
str_.encode!(@internal_encoding, ENCODING_OPTS) if @internal_encoding
|
191
202
|
end
|
192
203
|
str_
|
193
204
|
end
|
194
205
|
|
195
206
|
|
207
|
+
def _set_parser_directive(key_, value_) # :nodoc:
|
208
|
+
case key_
|
209
|
+
when 'encoding'
|
210
|
+
if SUPPORTS_ENCODING
|
211
|
+
encoding_ = ::Encoding.find(value_) rescue nil
|
212
|
+
@encoding = encoding_ if encoding_
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
|
196
218
|
end
|
197
219
|
|
198
220
|
|
data/lib/sawmill/rotater.rb
CHANGED
@@ -59,6 +59,11 @@ module Sawmill
|
|
59
59
|
|
60
60
|
class Rotater
|
61
61
|
|
62
|
+
# :stopdoc:
|
63
|
+
SUPPORTS_ENCODING = defined?(::Encoding)
|
64
|
+
ENCODING_OPTS = {:invalid => :replace, :undef => :replace}
|
65
|
+
# :startdoc:
|
66
|
+
|
62
67
|
|
63
68
|
# Create a rotater using the given rotation strategy.
|
64
69
|
# See Sawmill::Rotater::DateBasedLogFile and
|
@@ -70,9 +75,26 @@ module Sawmill
|
|
70
75
|
#
|
71
76
|
# <tt>:omit_directives</tt>::
|
72
77
|
# If true, omit standard logfile directives. Default is false.
|
78
|
+
# <tt>:concurrent_writes</tt>::
|
79
|
+
# Set this to true if you expect multiple processes to attempt to
|
80
|
+
# write to the same log file simultaneously. This option causes the
|
81
|
+
# rotater to surround writes with an acquisition of the cooperative
|
82
|
+
# filesystem lock (if available) for the logfile, in an attempt to
|
83
|
+
# prevent lines from interleaving in one another. Default is false.
|
84
|
+
# <tt>:encoding</tt>::
|
85
|
+
# Specify an encoding for file data. (Ruby 1.9 only).
|
86
|
+
# You may pass either an encoding object or an encoding name.
|
87
|
+
# If not specified, writes raw bytes (e.g. defaults to ASCII-8BIT).
|
73
88
|
|
74
89
|
def initialize(io_manager_, opts_={})
|
75
90
|
@omit_directives = opts_.delete(:omit_directives)
|
91
|
+
@concurrent_writes = opts_.delete(:concurrent_writes)
|
92
|
+
if SUPPORTS_ENCODING
|
93
|
+
@encoding = opts_.delete(:encoding)
|
94
|
+
if @encoding && !@encoding.respond_to?(:name)
|
95
|
+
@encoding = ::Encoding.find(@encoding)
|
96
|
+
end
|
97
|
+
end
|
76
98
|
if io_manager_.kind_of?(::Class)
|
77
99
|
@io_manager = io_manager_.new(opts_)
|
78
100
|
else
|
@@ -99,6 +121,23 @@ module Sawmill
|
|
99
121
|
end
|
100
122
|
|
101
123
|
|
124
|
+
def _write_to_stream(io_, str_)
|
125
|
+
if SUPPORTS_ENCODING && @encoding
|
126
|
+
str_ = str_.encode(@encoding, ENCODING_OPTS)
|
127
|
+
end
|
128
|
+
if @concurrent_writes
|
129
|
+
begin
|
130
|
+
io_.flock(::File::LOCK_EX)
|
131
|
+
io_.write(str_)
|
132
|
+
ensure
|
133
|
+
io_.flock(::File::LOCK_UN)
|
134
|
+
end
|
135
|
+
else
|
136
|
+
io_.write(str_)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
102
141
|
def _obtain_handle # :nodoc:
|
103
142
|
handle_ = @io_manager.preferred_handle
|
104
143
|
if @handles.include?(handle_)
|
@@ -106,7 +145,13 @@ module Sawmill
|
|
106
145
|
else
|
107
146
|
io_ = @io_manager.open_handle(handle_)
|
108
147
|
unless @omit_directives
|
109
|
-
io_
|
148
|
+
_write_to_stream(io_, "# sawmill_format: version=1\n")
|
149
|
+
if defined?(::Encoding)
|
150
|
+
encoding_ = io_.encoding
|
151
|
+
if encoding_
|
152
|
+
_write_to_stream(io_, "# sawmill_format: encoding=#{encoding_.name}\n")
|
153
|
+
end
|
154
|
+
end
|
110
155
|
end
|
111
156
|
@handles[handle_] = [handle_, io_, 1]
|
112
157
|
end
|
@@ -149,7 +194,7 @@ module Sawmill
|
|
149
194
|
handle_ = _check_rotate_handle(handle_)
|
150
195
|
end
|
151
196
|
info_ = @handles[handle_]
|
152
|
-
info_[1]
|
197
|
+
_write_to_stream(info_[1], str_)
|
153
198
|
handle_
|
154
199
|
end
|
155
200
|
end
|
@@ -79,9 +79,6 @@ module Sawmill
|
|
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.
|
85
82
|
|
86
83
|
def initialize(options_)
|
87
84
|
@turnover_frequency = options_[:turnover_frequency] || :none
|
@@ -97,10 +94,6 @@ module Sawmill
|
|
97
94
|
when :hourly then "%Y-%m-%d-%H"
|
98
95
|
else nil
|
99
96
|
end
|
100
|
-
@mode = 'a'
|
101
|
-
if defined?(::Encoding) && (encoding_ = options_[:encoding])
|
102
|
-
@mode << ":#{encoding_}"
|
103
|
-
end
|
104
97
|
end
|
105
98
|
|
106
99
|
|
@@ -125,7 +118,7 @@ module Sawmill
|
|
125
118
|
else
|
126
119
|
path_ = @prefix+@suffix
|
127
120
|
end
|
128
|
-
file_ = ::File.open(path_,
|
121
|
+
file_ = ::File.open(path_, 'a')
|
129
122
|
file_.sync = true
|
130
123
|
file_
|
131
124
|
end
|
@@ -76,9 +76,6 @@ 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.
|
82
79
|
|
83
80
|
def initialize(options_)
|
84
81
|
@max_logfile_size = options_[:max_file_size] || options_[:max_logfile_size]
|
@@ -100,10 +97,6 @@ module Sawmill
|
|
100
97
|
@preferred_handle = 0
|
101
98
|
@open_handles = {}
|
102
99
|
@last_shift = ::Time.now
|
103
|
-
@mode = 'a'
|
104
|
-
if defined?(::Encoding) && (encoding_ = options_[:encoding])
|
105
|
-
@mode << ":#{encoding_}"
|
106
|
-
end
|
107
100
|
end
|
108
101
|
|
109
102
|
|
@@ -122,7 +115,7 @@ module Sawmill
|
|
122
115
|
else
|
123
116
|
path_ = "#{@normal_path}.#{@preferred_handle-handle_-1}"
|
124
117
|
end
|
125
|
-
file_ = ::File.open(path_,
|
118
|
+
file_ = ::File.open(path_, 'a')
|
126
119
|
file_.sync = true
|
127
120
|
@open_handles[handle_] = true
|
128
121
|
file_
|
data/lib/sawmill/version.rb
CHANGED
@@ -34,12 +34,19 @@
|
|
34
34
|
;
|
35
35
|
|
36
36
|
|
37
|
+
begin
|
38
|
+
require 'versionomy'
|
39
|
+
rescue ::LoadError
|
40
|
+
end
|
41
|
+
|
42
|
+
|
37
43
|
module Sawmill
|
38
44
|
|
39
45
|
# Current gem version, as a frozen string.
|
40
|
-
VERSION_STRING = '0.0.
|
46
|
+
VERSION_STRING = '0.0.5'.freeze
|
41
47
|
|
42
|
-
# Current gem version, as a Versionomy::Value
|
43
|
-
|
48
|
+
# Current gem version, as a Versionomy::Value if the versionomy library
|
49
|
+
# is available, or as a frozen string if not.
|
50
|
+
VERSION = defined?(::Versionomy) ? ::Versionomy.parse(VERSION_STRING, :standard) : VERSION_STRING
|
44
51
|
|
45
52
|
end
|
data/tests/tc_levels.rb
CHANGED
data/tests/tc_logger.rb
CHANGED
data/tests/tc_multi_parser.rb
CHANGED
data/tests/tc_records.rb
CHANGED
@@ -33,7 +33,9 @@
|
|
33
33
|
# -----------------------------------------------------------------------------
|
34
34
|
|
35
35
|
|
36
|
+
require 'rubygems'
|
36
37
|
require 'test/unit'
|
38
|
+
require 'set'
|
37
39
|
require ::File.expand_path("#{::File.dirname(__FILE__)}/../lib/sawmill.rb")
|
38
40
|
|
39
41
|
|
@@ -108,7 +110,7 @@ module Sawmill
|
|
108
110
|
record_ = @records.dequeue
|
109
111
|
assert_equal(0, record_.message_count)
|
110
112
|
assert_equal(5, record_.entry_count)
|
111
|
-
assert_equal(Set.new(['color', 'size']), Set.new(record_.attribute_keys))
|
113
|
+
assert_equal(::Set.new(['color', 'size']), ::Set.new(record_.attribute_keys))
|
112
114
|
assert_equal('small', record_.attribute('size'))
|
113
115
|
assert_equal('red', record_.attribute('color'))
|
114
116
|
end
|
@@ -125,7 +127,7 @@ module Sawmill
|
|
125
127
|
record_ = @records.dequeue
|
126
128
|
assert_equal(0, record_.message_count)
|
127
129
|
assert_equal(5, record_.entry_count)
|
128
|
-
assert_equal(Set.new(['color', 'size']), Set.new(record_.attribute_keys))
|
130
|
+
assert_equal(::Set.new(['color', 'size']), ::Set.new(record_.attribute_keys))
|
129
131
|
assert_equal(['small'], record_.attribute('size'))
|
130
132
|
assert_equal(['blue', 'red'], record_.attribute('color'))
|
131
133
|
end
|
data/tests/tc_reports.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.5
|
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-08 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,17 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.3.
|
24
|
-
version:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: versionomy
|
27
|
-
type: :runtime
|
28
|
-
version_requirement:
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.2.0
|
23
|
+
version: 0.3.1
|
34
24
|
version:
|
35
25
|
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
26
|
email: dazuma@gmail.com
|