From b7c6846e317b0f2bfe4807aab34524c2a633947c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 3 Sep 2009 09:20:42 -0700 Subject: Ensure underlying logger objects are sync=true Userspace buffering defaults are dangerous as the Ruby default IO objects do not do line-aware buffering. This makes the README examples with File.open much safer to use out-of-the-box for users of the pure-Ruby version. For users on the MRI C extension logging to regular files, this should not have any effect as we've optimized those to do unbuffered write(2) syscalls anyways. --- ext/clogger_ext/clogger.c | 9 ++++++++- lib/clogger/pure.rb | 1 + test/test_clogger.rb | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ext/clogger_ext/clogger.c b/ext/clogger_ext/clogger.c index 2dc1ddc..de58a9e 100644 --- a/ext/clogger_ext/clogger.c +++ b/ext/clogger_ext/clogger.c @@ -287,6 +287,11 @@ static VALUE obj_fileno(VALUE obj) return rb_funcall(obj, rb_intern("fileno"), 0); } +static VALUE obj_enable_sync(VALUE obj) +{ + return rb_funcall(obj, rb_intern("sync="), 1, Qtrue); +} + /* only for writing to regular files, not stupid crap like NFS */ static void write_full(int fd, const void *buf, size_t count) { @@ -658,8 +663,10 @@ static VALUE clogger_init(int argc, VALUE *argv, VALUE self) VALUE tmp; c->logger = rb_hash_aref(o, ID2SYM(rb_intern("logger"))); - if (!NIL_P(c->logger)) + if (!NIL_P(c->logger)) { + rb_rescue(obj_enable_sync, c->logger, 0, 0); c->fd = raw_fd(rb_rescue(obj_fileno, c->logger, 0, 0)); + } tmp = rb_hash_aref(o, ID2SYM(rb_intern("format"))); if (!NIL_P(tmp)) diff --git a/lib/clogger/pure.rb b/lib/clogger/pure.rb index d8752b3..57e727b 100644 --- a/lib/clogger/pure.rb +++ b/lib/clogger/pure.rb @@ -8,6 +8,7 @@ class Clogger def initialize(app, opts = {}) @app = app @logger = opts[:logger] + (@logger.sync = true) rescue nil @fmt_ops = compile_format(opts[:format] || Format::Common) @wrap_body = need_wrap_body?(@fmt_ops) @reentrant = nil diff --git a/test/test_clogger.rb b/test/test_clogger.rb index 8e6604e..d3e315e 100644 --- a/test/test_clogger.rb +++ b/test/test_clogger.rb @@ -434,4 +434,23 @@ class TestClogger < Test::Unit::TestCase assert_equal "text/plain\n", str.string end + def test_clogger_synced + io = StringIO.new + logger = Struct.new(:sync, :io).new(false, io) + assert ! logger.sync + def logger.<<(str) + io << str + end + app = lambda { |env| [302, [ %w(a) ], []] } + cl = Clogger.new(app, :logger => logger) + assert logger.sync + end + + def test_clogger_unsyncable + logger = '' + assert ! logger.respond_to?('sync=') + app = lambda { |env| [302, [ %w(a) ], []] } + assert_nothing_raised { Clogger.new(app, :logger => logger) } + end + end -- cgit v1.2.3-24-ge0c7