<commit_before>gem "rack", "~> 0.4.0"
require "rack"

require "yaml"
require "thread"

require Pathname(__FILE__).dirname + "rack/utils"
require Pathname(__FILE__).dirname + "request"
require Pathname(__FILE__).dirname + "response"
require Pathname(__FILE__).dirname + "block_io"

module Wheels
  class Application

    def self.routes(services = self.class.services)
      raise NotImplementedError.new("Your application must redefine #{self}#routes.")
    end

    def self.services=(container)
      @services = container
    end

    def self.services
      @services ||= Wheels::Container.new
    end

    attr_reader :environment, :logger

    def initialize(router = self.class.routes, environment = ENV["ENVIRONMENT"])
      @router = router
      @environment = (environment || "development").to_s
      @logger = self.class.services.get("logger") rescue nil
    end

    def default_layout
      "layouts/application"
    end

    ##
    # Request entry point called by Rack. It creates a request and response
    # object based on the incoming request environment, checks for public
    # files, and dispatches the request.
    # 
    # It returns a rack response hash.
    ##
    def call(env)
      env["APP_ENVIRONMENT"] = environment
      request = Request.new(self, env)
      response = Response.new(request)

      if file = find_public_file(request.path_info[1..-1])
        response.stream_file(file)
        return response.to_a
      end

      handler = @router.match(request)

      catch(:abort_request) do
        dispatch_request(handler, request, response)
      end

      response.to_a
    end

    ##
    # Request dispatch function, which handles 404's, exceptions,
    # and logs requests.
    ##
    def dispatch_request(handler, request, response)
      start = Time.now

      return handle_not_found(request, response) unless handler

      handler.call(request, response)
    rescue StandardError, LoadError, SyntaxError => e
      handle_exception(e, request, response)
    ensure
      log_request(request, response, start, Time.now)
    end

    ##
    # Logs requests and their params the logger registered in the
    # application's services, or to stdout.
    # 
    # Format:
    # 
    #   [172.16.31.10] [GET] /products (200)     {"order" => "desc"}
    ##
    def log_request(request, response, start_time, end_time)
      message = "[#{request.remote_ip}] [#{request.request_method}] #{request.path_info} (#{response.status})"
      message << "\t#{request.params.inspect}" unless request.params.empty?

      if @logger
        logger.info message
      else
        $stdout.puts "[#{start_time.strftime('%m-%d-%Y @ %H:%M:%S')}] #{message}"
      end<commit_msg>Updating log_request to log request duration.<commit_after>gem "rack", "~> 0.4.0"
require "rack"

require "yaml"
require "thread"

require Pathname(__FILE__).dirname + "rack/utils"
require Pathname(__FILE__).dirname + "request"
require Pathname(__FILE__).dirname + "response"
require Pathname(__FILE__).dirname + "block_io"

module Wheels
  class Application

    def self.routes(services = self.class.services)
      raise NotImplementedError.new("Your application must redefine #{self}#routes.")
    end

    def self.services=(container)
      @services = container
    end

    def self.services
      @services ||= Wheels::Container.new
    end

    attr_reader :environment, :logger

    def initialize(router = self.class.routes, environment = ENV["ENVIRONMENT"])
      @router = router
      @environment = (environment || "development").to_s
      @logger = self.class.services.get("logger") rescue nil
    end

    def default_layout
      "layouts/application"
    end

    ##
    # Request entry point called by Rack. It creates a request and response
    # object based on the incoming request environment, checks for public
    # files, and dispatches the request.
    # 
    # It returns a rack response hash.
    ##
    def call(env)
      env["APP_ENVIRONMENT"] = environment
      request = Request.new(self, env)
      response = Response.new(request)

      if file = find_public_file(request.path_info[1..-1])
        response.stream_file(file)
        return response.to_a
      end

      handler = @router.match(request)

      catch(:abort_request) do
        dispatch_request(handler, request, response)
      end

      response.to_a
    end

    ##
    # Request dispatch function, which handles 404's, exceptions,
    # and logs requests.
    ##
    def dispatch_request(handler, request, response)
      start = Time.now

      return handle_not_found(request, response) unless handler

      handler.call(request, response)
    rescue StandardError, LoadError, SyntaxError => e
      handle_exception(e, request, response)
    ensure
      log_request(request, response, start, Time.now)
    end

    ##
    # Logs requests and their params the logger registered in the
    # application's services, or to stdout.
    # 
    # Format:
    # 
    #   # duration #ip              #method #uri      #status   #params
    #   [0.12s]     [172.16.31.10] [GET]    /products (200)     {"order" => "desc"}
    ##
    def log_request(request, response, start_time, end_time)
      message = "[#{"%2.2fs" % (end_time - start_time)}] [#{request.remote_ip}] [#{request.request_method}] #{request.path_info} (#{response.status})"
      message << "\t#{request.params.inspect}" unless request.params.empty?

      if @logger
        logger.info message
      else
        $stdout.puts "[#{start_time.strftime('%m-%d-%Y @ %H:%M:%S')}] #{message}"
      end
{'fraction_non_alphanumeric': 0.11495076096687556, 'fraction_numerical': 0.008057296329453895, 'mean_word_length': 2.92, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2455415', 'n_tokens_mistral': 1691, 'n_tokens_neox': 1628, 'n_words': 432}