diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-09-03 09:20:42 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-09-03 09:20:42 -0700 |
commit | b7c6846e317b0f2bfe4807aab34524c2a633947c (patch) | |
tree | 013a4590fada5dd821b5f85a376d54ffda7897b8 | |
parent | afaa8efb31094a831a68b383523f9bac46a244ac (diff) | |
download | clogger-b7c6846e317b0f2bfe4807aab34524c2a633947c.tar.gz |
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.
-rw-r--r-- | ext/clogger_ext/clogger.c | 9 | ||||
-rw-r--r-- | lib/clogger/pure.rb | 1 | ||||
-rw-r--r-- | test/test_clogger.rb | 19 |
3 files changed, 28 insertions, 1 deletions
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 |