reevoo/sapience-rb

View on GitHub
lib/sapience/extensions/sinatra/middleware/logging.rb

Summary

Maintainability
A
0 mins
Test Coverage
# 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