class Rack::CommonLogger

to the configured logger.
logs a line in the
Rack::CommonLogger forwards every request to the given app, and

def call(env)

cause the request not to be logged.
exceptions raised during the sending of the response body will
the logging happens after the request body has been fully sent, any
they should be loaded after this middleware. Additionally, because
will not be logged, so if exception handling middleware are used,
returned. Note that if the app raises an exception, the request
Log all requests in common_log format after a response has been
def call(env)
  began_at = Utils.clock_time
  status, headers, body = response = @app.call(env)
  response[2] = BodyProxy.new(body) { log(env, status, headers, began_at) }
  response
end

def extract_content_length(headers)

include it in the logged data.
Attempt to determine the content length for the response to
def extract_content_length(headers)
  value = headers[CONTENT_LENGTH]
  !value || value.to_s == '0' ? '-' : value
end

def initialize(app, logger = nil)

If +logger+ is nil, CommonLogger will fall back env['rack.errors'].
with a single string argument, the log message.
which includes the standard library Logger. These methods are called
+logger+ can be any object that supports the +write+ or +<<+ methods,
def initialize(app, logger = nil)
  @app = app
  @logger = logger
end

def log(env, status, response_headers, began_at)

Log the request to the configured logger.
def log(env, status, response_headers, began_at)
  request = Rack::Request.new(env)
  length = extract_content_length(response_headers)
  msg = sprintf(FORMAT,
    request.ip || "-",
    request.get_header("REMOTE_USER") || "-",
    Time.now.strftime("%d/%b/%Y:%H:%M:%S %z"),
    request.request_method,
    request.script_name,
    request.path_info,
    request.query_string.empty? ? "" : "?#{request.query_string}",
    request.get_header(SERVER_PROTOCOL),
    status.to_s[0..3],
    length,
    Utils.clock_time - began_at)
  msg.gsub!(/[^[:print:]\n]/) { |c| sprintf("\\x%x", c.ord) }
  logger = @logger || request.get_header(RACK_ERRORS)
  # Standard library logger doesn't support write but it supports << which actually
  # calls to write on the log device without formatting
  if logger.respond_to?(:write)
    logger.write(msg)
  else
    logger << msg
  end
end