Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/rory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ def root
app = application
app && app.root
end

def env
ENV["RORY_ENV"]
end
end
end
80 changes: 35 additions & 45 deletions lib/rory/application.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
require 'pathname'
require 'rory/logger'
require 'rory/request_id'
require 'rory/route_mapper'
require 'rory/middleware_stack'
require 'rory/initializers'
require 'rack/commonlogger'
require 'rory/request_parameter_logger'
require 'rory/sequel_connect'
require 'rory/logging'
require 'rory/default_initializers/request_middleware'

module Rory
# Main application superclass. Applications should subclass this class,
Expand All @@ -14,16 +13,19 @@ module Rory
class Application
# Exception raised if no root has been set for this Rory::Application subclass
class RootNotConfigured < StandardError; end
include SequelConnect
include Logging

attr_reader :db, :db_config
attr_accessor :config_path
attr_accessor :config_path, :controller_logger

attr_writer :auto_require_paths

class << self
private :new
attr_reader :root

def inherited(subclass)
super
Rory.application = subclass.instance
end

Expand All @@ -33,7 +35,7 @@ def method_missing(*args, &block)

# @return [Rory::Initializers]
def initializers
@initializers ||= Initializers.new
@@initializers ||= Initializers.new
end

def respond_to?(method, private=false)
Expand All @@ -49,14 +51,16 @@ def root=(root_path)
$:.unshift @root = Pathname.new(root_path).realpath
end

def initializer_default_middleware
Rory::Application.initializers.add "rory.request_middleware" do |app|
app.request_middleware
end
def warmup
self.warmed_up = true
run_initializers
end
end

initializer_default_middleware
attr_writer :warmed_up
def warmed_up?
!!@warmed_up
end
end

def auto_require_paths
@auto_require_paths ||= %w(models controllers helpers)
Expand All @@ -80,41 +84,25 @@ def config_path
@config_path ||= root_path.join('config')
end

def log_path
@log_path ||= root_path.join('log')
end

def set_routes(&block)
@routes = RouteMapper.set_routes(&block)
end

def routes
unless @routes
load(File.join(config_path, 'routes.rb'))
end
load(File.join(config_path, 'routes.rb')) unless @routes
@routes
end

def configure
yield self
end

def spin_up
connect_db
end

def load_config_data(config_type)
YAML.load_file(
File.expand_path(File.join(config_path, "#{config_type}.yml"))
)
end

def connect_db(environment = ENV['RORY_ENV'])
@db_config = load_config_data(:database)
@db = Sequel.connect(@db_config[environment.to_s])
@db.loggers << logger
end

def use_middleware(*args, &block)
middleware.use *args, &block
end
Expand All @@ -128,12 +116,14 @@ def dispatcher
end

def request_logging_on?
@request_logging != false
!!(Rory::Application.initializers.detect { |init| init.name == "rory.request_logging_middleware" } ||
Rory::Application.initializers.detect { |init| init.name == "rory.controller_logger" })
end

def turn_off_request_logging!
reset_stack
@request_logging = false
Rory::Application.initializers.delete("rory.request_logging_middleware")
Rory::Application.initializers.delete("rory.controller_logger")
end

def parameters_to_filter
Expand All @@ -146,28 +136,27 @@ def filter_parameters(*params)
end

def reset_stack
self.class.warmed_up = nil
@stack = nil
end

def uuid_prefix
Support.tokenize(self.class.name.gsub("::Application", ""))
end

def request_middleware
return unless request_logging_on?
use_middleware Rory::RequestId, :uuid_prefix => uuid_prefix
use_middleware Rack::PostBodyContentTypeParser
use_middleware Rack::CommonLogger, logger
use_middleware Rory::RequestParameterLogger, logger, :filters => parameters_to_filter
def initialize_default_middleware
Rory::RequestMiddleware.initialize_default_middleware
end

initialize_default_middleware

def run_initializers
Rory::Application.initializers.run(self)
end

def stack
@stack ||= Rack::Builder.new.tap { |builder|
run_initializers
warmup_check
middleware.each do |m|
builder.use m.klass, *m.args, &m.block
end
Expand All @@ -179,13 +168,14 @@ def call(env)
stack.call(env)
end

def log_file
Dir.mkdir(log_path) unless File.exists?(log_path)
File.open(log_path.join("#{ENV['RORY_ENV']}.log"), 'a').tap { |file| file.sync = true }
end
private

def logger
@logger ||= Logger.new(log_file)
def warmup_check
unless self.class.warmed_up?
logger.warn("#{self.class.name} was not warmed up before the first request. "\
"Call #{self.class.name}.warmup on boot to ensure a quick first response.")
self.class.warmup
end
end
end
end
17 changes: 17 additions & 0 deletions lib/rory/controller/request_logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Rory
class Controller
class RequestLogger
def initialize(logger:)
@logger = logger
end

def call(controller:, action:, params:, path:)
logger.info("request -- #{{path: path, action: action, controller: controller, params: params }}")
end

private

attr_reader :logger
end
end
end
42 changes: 42 additions & 0 deletions lib/rory/default_initializers/request_middleware.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require 'rack/commonlogger'
require 'rory/request_parameter_logger'
require 'rory/request_id'
require 'rory/controller/request_logger'

module Rory
module RequestMiddleware
class << self
def initialize_post_body_type_parser
Rory::Application.initializers.add "rory.post_body_type_parser" do |app|
app.use_middleware Rack::PostBodyContentTypeParser
end
end

def initialize_controller_logger
Rory::Application.initializers.add "rory.controller_logger" do |app|
app.controller_logger = Controller::RequestLogger.new(logger: app.logger)
end
end

def initialize_logging
Rory::Application.initializers.add "rory.request_logging_middleware" do |app|
app.use_middleware Rack::CommonLogger, app.logger
app.use_middleware Rory::RequestParameterLogger, app.logger, :filters => app.parameters_to_filter
end
end

def initialize_request_id
Rory::Application.initializers.add "rory.request_id_middleware" do |app|
app.use_middleware Rory::RequestId, :uuid_prefix => app.uuid_prefix
end
end

def initialize_default_middleware
initialize_post_body_type_parser
initialize_controller_logger
initialize_logging
initialize_request_id
end
end
end
end
23 changes: 16 additions & 7 deletions lib/rory/dispatcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def self.rack_app(app)

def override_method
requested_override = request.params['_method']
return nil unless requested_override
if ['put', 'patch', 'delete'].include?(requested_override.downcase)
return unless requested_override
if %w(put patch delete).include?(requested_override.downcase)
requested_override.downcase
end
end
Expand Down Expand Up @@ -48,8 +48,9 @@ def route
end

def dispatch
if controller
controller.present
_controller = controller
if _controller
_controller.present
else
render_not_found
end
Expand All @@ -59,22 +60,30 @@ def redirect(path = '/')
unless path =~ /\:\/\//
path = "#{@request.scheme}://#{@request.host_with_port}#{path}"
end
return [ 302, {'Content-type' => 'text/html', 'Location'=> path }, ['Redirecting...'] ]
[ 302, {'Content-type' => 'text/html', 'Location'=> path }, ['Redirecting...'] ]
end

def render_not_found
return [ 404, {'Content-type' => 'text/html' }, ['Four, oh, four.'] ]
[ 404, {'Content-type' => 'text/html' }, ['Four, oh, four.'] ]
end

private

def controller
if klass = controller_class
if (klass = controller_class)
@routing.merge!(:dispatcher => self)
log_request
klass.new(request, @routing, @app)
end
end

def log_request
(@app.controller_logger || Proc.new {}).call(controller: @routing[:route].controller,
action: @routing[:route].action,
params: @request.params,
path: full_path)
end

def controller_class
if route
controller_name = Rory::Support.camelize("#{route.controller}_controller")
Expand Down
Loading