Rails Environments

The environment is specified in the RAILS_ENV variable; the name corresponds to the environment definition file in the config/environment folder.  Since the environment governs fundamental aspects of Rails, it is important to understand the settings.  You should examine the boot.rb and environments.rb files to get a feeling for the settings.

Startup
Whenever you start a Rails process, the config/environment.rb is loaded.  Look at public/dispatch.rb:
require File.dirname(__FILE__) + “/../config/environment”

Defaults
# Uncomment below to force Rails into production mode when you don’t contorol web/app server and can’t set it the proper way.
# ENV['RAILS_ENV'] ||= ‘production’

# specifies gem version of Rails to use when vendor/rails is not present.
RAILS_GEM_VERSION = 2.1.0

# If you are running edge, a frozen snapshot of Rails in vendor/rails, the previous setting is not used.
jruby -S rake rails:freeze:edge # copies the repository version of Rails into vendor/rails.

Bootstrapping

# In config/environment.rb
require Fle.join( File.dirname(__FILE__), ‘boot’ )  # loads config/boot.rb

  1. Ensures RAILS_ROOT environment variable is set.  Holds the path to the root of the current project.
  2. Figure out which version of rails to use.  First check vendor/rails.
    File.directory?(“#{RAILS_ROOT}/vendor/rails”)
    Otherwise, try to find Rails as a RubyGem.

RubyGems

require rubygems
require gem rails

# If the Rails version specified in environment.rb is out of synch, you’ll get an error message.
# Install with `jruby -S gem install -v=1.1.5 rails’ or change environment.rb to redefine RAILS_GEM_VERSION.

Initializer

The boot script then requires the Rails script initializer.rb — set up default load paths — assembled from a list of component frameworks that make up Rails and the folders of your application that contain code.

# In railties/lib/initializer.rb
def default_frameworks
[:active_record, :action_controller, :action_view, :action_mailer, :action_web_service]
end

def default_load_paths

paths= ["#{root_path}/test/mocks/#{environment}"]
paths.concat(Dir["#{root_path}/app/controllers/"])
paths.concat(Dir["#{root_path}/components/[_a-z]*”])

paths.concat(
['app', 'app/models', 'app/controllers', 'app/helpers',
'app/services', 'app/apis', 'components', 'config', 'lib', 'vendor'].
map { |dir| “#{root_path}/#{dir}” }.select{ |dir| File.directory?(dir) } )

paths.concat Dir["#{root_path}/vendor/plugins/*/lib/" ]
paths.concat builtin_directories

end

# The place for Rails to include app behavior (models, helpers, controllers), @see localhost:3000/rails/info/properties
def builtin_directories
( environment == ‘development’) ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
end

# All of this clever loading allows you to write application code without making you add require all over the place.
# If Rails encounters a class or module that is not already defined, Rails uses conventions to guess which files to load:

  • EstimationCalculator becomes require ‘estimation_calculator’
  • KittTurboBoost becomes require ‘kitt_turbo_boost’
  • MacGyver::SwissArmyKnife becomes require ‘mac_gyver/swiss_army_knife.rb’
  • Some::ReallyRatherDeeply::NestedClass becomes require ’some/really_rather_deeply/nested_class.rb’

Configuration

Rails::Initializer.run do |config|
# Settings in config/environments/* take precedence over these…
# Skip frameworks you are not using (only works if using vendor/rails)
config.frameworks -= [:action_web_service, :action_mailer]
# Additional load paths for custom directories
config.load_paths += %W( #{RAILS_ROOT}/extras )
# Logging
config.log_level = :debug
# User/Session storage – create the session table with ‘jruby -S rake db:sessions:create’
config.action_controller.session_store = :active_record_store

Schema Dumper

When you run tests, Rails dumps the schema of your database and copies it to the test database using schema.rb.
# Use sql instead of ActiveRecord’s schema dumper when creating the test database for custom constraints.
# config.active_record.schema_format = :sql

Observers

First class objects that perform specific tasks such as clearing caches and managing data.
# config.active_record.observers = :cacher, :garbage_collector

Additional Configuration

environment.rb & starting around line 400 of railties/lib/initializer.rb

Development Mode

config.cache_classes = false
config.whiny_nils = true
config.breakpoint_server = true
config.action_controller.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_view.cache_template_extensions = false
config.action_view.debug_rjs = true
config.action_mailer.raise_delivery_errors = false

Test Mode

config.cache_classes = true
config.whiny_nils = true
config.action_controller.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_mailer.delivery_method = :test

Production Mode

config.cache_classes = true
config.action_controller.consider_all_requests_local = false
config.action_controller.perform_caching = true
# config.action_controller.asset_host = “http://assets.example.com”
# config.action_mailer.raise_delivery_errors = false

Logging

Most programming contexts in Rails have a logger attribute, which holds a reference to a logger conforming to the Log4r or Logger class.  RAILS_DEFAULT_LOGGER constant has a reference to the logger you can use anywhere.
Textmate shortcut rdb.

require ‘logger’
logger = Logger.new STDOUT
logger.warn “This is a warning message”
logger.info “This is an info message”
logger.debug “This is a debug message”
logger.error “This is an error message”
logger.fatal “This is a fatal message”

Log files

The log folder of the Rails app holds three log files; one log file corresponds to each environment (and pid for mongrel).

# clears the log files
jruby -S rake log:clear

# continuous display of development log file
tail -f log/development.log

You can obtain a lot of information from an incoming request within the development log file:

  • Controller / Action invoked
  • Remote IP of the computer making the request
  • Timestamp of the request
  • Session ID associated with the request
  • hash of parameters associated with the request
  • database request info including the time and SQL of the statement executed
  • query cache hit info including time and the SQL triggering results from the cache instead of DB
  • rendering info for each template involved in rendering the output and time consumed by each
  • Total time used in completing the request and request per second calculation
  • Time spent in the DB versus rendering
  • HTTP status code and URL of the response sent back to the client

# Alternate logging scheme: ActiveRecord::Base.logger described by Jamis Buck, as used by David H. Hansson

Log file analysis

  • Performance (relative DB time versus rendering time)
  • SQL queries
  • Identification of N+1 select problems (a series of many select statements for association lookup queries)
  • Separation of concerns – Controller should query data from the model and make it available to the view

Syslog

UNIX-like systems have a service called syslog.

  • Finer-grained control over logging levels and content
  • Consolidation of logger output for multiple Rails applications
  • Consolidation of logger output for multiple servers is possible.
  • Setup: downloading the library, require ’sys-log’, and replace the RAILS_DEFAULT_LOGGER instance.

~ by bandwagonblog on January 19, 2009.

Leave a Reply