class DeinterleavingLogger < ActiveSupport::BufferedLogger
  def initialize(*args)
    super
    @writers = Hash.new
    @writer_guard = Mutex.new
  end

  def add_writer
    @writers[Thread.current] ||= Hash.new
    @writers[Thread.current][Fiber.current] ||= Array.new
  end

  def flush_writer
    return unless current_queue
    @writer_guard.synchronize { current_queue.each { |args, block| add_without_deinterleaving *args, &block } }
    @writers[Thread.current].delete Fiber.current
  end

  def add_with_deinterleaving(*args, &block)
    if current_queue then
      current_queue << [ args, block ]
    else
      add_without_deinterleaving *args, &block
    end
  end
  alias_method_chain :add, :deinterleaving

  private

  def current_queue
    @writers[Thread.current].try(:[], Fiber.current)
  end

  class Middleware
    def initialize(app)
      @app = app
    end

    def call(env)
      Rails.logger.add_writer
      status, headers, response = @app.call(env)
      Rails.logger.flush_writer
      return [ status, headers, response ]
    end
  end
end

If you use something like Rack::FiberPool, you'll find your server logs interleaved due to parallelization of requests. This middleware and logger replacement will buffer each request's logs until the request is finished, then dump it in an exclusive block.

To use, add the middleware after you've fibered your request, and replace config.logger with the DeinterleavingLogger.