wapa5pow/rack-action_logger

View on GitHub
lib/rack/action_logger/metrics/rack_metrics.rb

Summary

Maintainability
A
0 mins
Test Coverage
require 'rack/action_logger'
require 'rack/mock'
require 'woothee'

module Rack::ActionLogger::Metrics
  class RackMetrics
    METRICS = [
      :path, :method, :params, :request_headers, :status_code, :ip, :remote_ip, :user_agent, :device, :os, :browser,
      :browser_version, :request_id, :response_headers, :response_json_body,
    ]
    RACK_TAG_PREFIX = 'rack'
    EXCLUDE_PATH_PREFIX = '/asset'

    attr_reader :status_code

    def initialize(env, status_code, headers, body)
      @env = env
      @status_code = status_code
      @headers = headers
      @body = body
      @request = Rack::Request.new(env)
      @response = Rack::Response.new(body, status_code, headers)
      @ua = Woothee.parse(@request.user_agent)
    end

    def tag_suffix
      return RACK_TAG_PREFIX if Rack::ActionLogger.configuration.rack_unified_tag
      if @status_code == 404
        tags = ['not_found']
      else
        tags = URI(path).path.split('/').reject { |c| c.empty? }
      end
      (Array(RACK_TAG_PREFIX) + tags).join('.')
    end

    def metrics
      return unless enable_metrics
      METRICS.inject({}) do |result, metric|
        result[metric] = self.send(metric) unless
            Rack::ActionLogger.configuration.rack_request_blacklist.include? metric
        result
      end
    end

    def path
      @request.path
    end

    def method
      @request.request_method
    end

    def params
      Rack::ActionLogger::ParameterFiltering.apply_filter(@request.params)
    end

    def request_headers
      @env.select { |v| v.start_with? 'HTTP_' }
    end

    def enable_metrics
      Rack::ActionLogger.configuration.rack_content_types.any? { |c| content_type.to_s.include?(c) } || action_controller
    end

    def action_controller
      @env['action_controller.instance']
    end

    def content_type
      @response.content_type
    end

    def remote_ip
      @env['action_dispatch.remote_ip']
    end

    def ip
      @request.ip
    end

    def user_agent
      @request.user_agent
    end

    def device
      @ua[:category]
    end

    def os
      @ua[:os]
    end

    def browser
      @ua[:name]
    end

    def browser_version
      @ua[:version]
    end

    def request_id
      @env['action_dispatch.request_id']
    end

    def response_headers
      @headers
    end

    def response_json_body
      response_bodies = []
      @body.each { |part| response_bodies << part } if @body
      result = JSON.parse(response_bodies.join('')) rescue {}
      Rack::ActionLogger::ParameterFiltering.apply_filter(result)
    end
  end
end