Skip to content

Instantly share code, notes, and snippets.

@feksai
Last active September 21, 2016 12:56
Show Gist options
  • Save feksai/d712b8007acd70b3f02fd4604e356de2 to your computer and use it in GitHub Desktop.
Save feksai/d712b8007acd70b3f02fd4604e356de2 to your computer and use it in GitHub Desktop.
require 'sinatra/base'
require 'logger'
module Sinatra
class CustomFormatMiddleware
FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n}
def initialize(app, logger)
@app, @logger = app, logger
end
def call(env)
began_at = Time.now
status, header, body = @app.call(env)
header = Rack::Utils::HeaderHash.new(header)
body = Rack::BodyProxy.new(body) { log(env, status, header, began_at) }
[status, header, body]
end
private
def log(env, status, header, began_at)
now = Time.now
length = extract_content_length(header)
msg = FORMAT % [
now.strftime("%Y-%m-%d %H:%M:%S.%L") + " INFO:",
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
env["REMOTE_USER"] || "-",
env['REQUEST_METHOD'],
env['PATH_INFO'],
env['QUERY_STRING'].empty? ? "" : "?"+env['QUERY_STRING'],
env["HTTP_VERSION"],
status.to_s[0..3],
length,
now - began_at ]
logger = @logger || env['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
def extract_content_length(headers)
value = headers['Content-Length'] or return '-'
value.to_s == '0' ? '-' : value
end
end
module CustomFormat
def self.registered(app)
app.use Sinatra::CustomFormatMiddleware, Logger.new(STDOUT)
::Sinatra::Base.class_eval do
def dump_errors!(boom)
msg = ["#{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")} FATAL: #{boom.class} - #{boom.message}:", *boom.backtrace].join("\n\t")
@env['rack.errors'].puts(msg)
end
end
end #/ self.registered
end
register(Sinatra::CustomFormat)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment