Sha256: 03e3a9cb2a01226b603d85a66852ccf5ac5569c713642f98b13c3cc16bc1c657

Contents?: true

Size: 1.71 KB

Versions: 1

Compression:

Stored size: 1.71 KB

Contents

# frozen_string_literal: true

require "json"
require "rack/request"

module Snowpack
  module Web
    class RackLogger
      attr_reader :logger
      attr_reader :filter_params

      def initialize(logger, filter_params: [])
        @logger = logger
        @filter_params = filter_params
      end

      def attach(rack_monitor)
        rack_monitor.on :stop do |env:, status:, time:|
          log_request env, status, time
        end

        rack_monitor.on :error do |event|
          log_exception event[:exception]
        end
      end

      def log_request(env, status, time)
        request = Rack::Request.new(env)

        params = request.GET
        params = params.merge(Hash(request.POST))

        # TODO: support both roda and hanami params
        json_params = Hash(request.get_header("roda.json_params"))
        params = params.merge(json_params)

        data = {
          method: request.request_method,
          path: request.path,
          for: request.get_header("REMOTE_ADDR"),
          status: status,
          duration: time,
          params: filter(params),
        }

        logger.info JSON.generate(data)
      end

      def log_exception(e)
        logger.error e.message
        logger.error (e.backtrace).join("\n")
      end

      private

      FILTERED = "[FILTERED]"

      def filter(params)
        params.each_with_object({}) do |(k, v), h|
          if filter_params.include?(k)
            h.update(k => FILTERED)
          elsif v.is_a?(Hash)
            h.update(k => filter_params(v))
          elsif v.is_a?(Array)
            h.update(k => v.map { |m| m.is_a?(Hash) ? filter_params(m) : m })
          else
            h[k] = v
          end
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
snowpack-1.0.0.alpha2 lib/snowpack/web/rack_logger.rb