lib/sapience/extensions/sinatra/middleware/logging.rb
# frozen_string_literal: true
module Sapience
module Extensions
module Sinatra
module Middleware
class Logging
if defined?(ActiveRecord)
ActiveSupport::Notifications.subscribe("sql.active_record") do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
Sinatra::Timings.append_db_runtime(event)
end
end
def initialize(app, options = {})
@app = app
@logger = options[:logger]
end
def call(env)
call!(env)
end
protected
def call!(env)
@env = env
before
error = catch(:error) do
begin
@app_response = @app.call(@env)
rescue StandardError => e
after_exception(e)
raise e
end
nil
end
if error
after_failure(error)
throw(:error, error)
else
@status, = *@app_response
after
end
@app_response
end
def before
reset_db_runtime
start_time
end
def after
stop_time
@logger.info(parameters)
end
def after_exception(exc) # rubocop:disable Lint/UnusedMethodArgument
@status = 500
after
end
def after_failure(error)
@status = error[:status]
after
end
def parameters # rubocop:disable AbcSize
{
method: request.request_method,
request_path: @env["REQUEST_URI"] || @env["PATH_INFO"],
status: @status,
route: @env["sinatra.route"].to_s,
host: request.host,
ip: (request.env["HTTP_X_FORWARDED_FOR"] || request.env["REMOTE_ADDR"]),
ua: request.env["HTTP_USER_AGENT"],
tags: Sapience.tags,
params: request.params,
runtimes: {
total: total_runtime,
view: view_runtime,
db: db_runtime,
},
}
end
private
def request
@request ||= ::Rack::Request.new(@env)
end
def total_runtime
((stop_time - start_time) * 1000).round(3)
end
def view_runtime
total_runtime - db_runtime
end
def db_runtime
Sinatra::Timings.db_runtime.round(3)
end
def reset_db_runtime
Sinatra::Timings.reset_db_runtime
end
def start_time
@start_time ||= Time.now
end
def stop_time
@stop_time ||= Time.now
end
end
end
end
end
end