lib/sawmill/rotater.rb in sawmill-0.0.4 vs lib/sawmill/rotater.rb in sawmill-0.0.5
- old
+ new
@@ -57,24 +57,46 @@
# break the file anywhere it wants. See the create_channel method
# and the Channel object for more details.
class Rotater
+ # :stopdoc:
+ SUPPORTS_ENCODING = defined?(::Encoding)
+ ENCODING_OPTS = {:invalid => :replace, :undef => :replace}
+ # :startdoc:
+
# Create a rotater using the given rotation strategy.
# See Sawmill::Rotater::DateBasedLogFile and
# Sawmill::Rotater::ShiftingLogFile for examples of common strategies.
#
# The rotation strategy can be passed as an object or as a class with a
# set of options that will be used to instantiate the strategy.
# In addition to those options, the following options are recognized:
#
# <tt>:omit_directives</tt>::
# If true, omit standard logfile directives. Default is false.
+ # <tt>:concurrent_writes</tt>::
+ # Set this to true if you expect multiple processes to attempt to
+ # write to the same log file simultaneously. This option causes the
+ # rotater to surround writes with an acquisition of the cooperative
+ # filesystem lock (if available) for the logfile, in an attempt to
+ # prevent lines from interleaving in one another. Default is false.
+ # <tt>:encoding</tt>::
+ # Specify an encoding for file data. (Ruby 1.9 only).
+ # You may pass either an encoding object or an encoding name.
+ # If not specified, writes raw bytes (e.g. defaults to ASCII-8BIT).
def initialize(io_manager_, opts_={})
@omit_directives = opts_.delete(:omit_directives)
+ @concurrent_writes = opts_.delete(:concurrent_writes)
+ if SUPPORTS_ENCODING
+ @encoding = opts_.delete(:encoding)
+ if @encoding && !@encoding.respond_to?(:name)
+ @encoding = ::Encoding.find(@encoding)
+ end
+ end
if io_manager_.kind_of?(::Class)
@io_manager = io_manager_.new(opts_)
else
@io_manager = io_manager_
end
@@ -97,18 +119,41 @@
def create_channel(opts_={})
Channel.new(self, opts_)
end
+ def _write_to_stream(io_, str_)
+ if SUPPORTS_ENCODING && @encoding
+ str_ = str_.encode(@encoding, ENCODING_OPTS)
+ end
+ if @concurrent_writes
+ begin
+ io_.flock(::File::LOCK_EX)
+ io_.write(str_)
+ ensure
+ io_.flock(::File::LOCK_UN)
+ end
+ else
+ io_.write(str_)
+ end
+ end
+
+
def _obtain_handle # :nodoc:
handle_ = @io_manager.preferred_handle
if @handles.include?(handle_)
@handles[handle_][2] += 1
else
io_ = @io_manager.open_handle(handle_)
unless @omit_directives
- io_.write("# sawmill_format: version=1\n")
+ _write_to_stream(io_, "# sawmill_format: version=1\n")
+ if defined?(::Encoding)
+ encoding_ = io_.encoding
+ if encoding_
+ _write_to_stream(io_, "# sawmill_format: encoding=#{encoding_.name}\n")
+ end
+ end
end
@handles[handle_] = [handle_, io_, 1]
end
handle_
end
@@ -147,10 +192,10 @@
@io_manager.before_write
if auto_rotate_
handle_ = _check_rotate_handle(handle_)
end
info_ = @handles[handle_]
- info_[1].write(str_)
+ _write_to_stream(info_[1], str_)
handle_
end
end