<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -47,8 +47,9 @@ module Merb
     #   staging.rb:
     #     Merb.merge_env &quot;production&quot;         #We want to use all the settings production uses
     #     Merb::Config.use { |c|
-    #       c[:log_level]         = &quot;debug&quot;   #except we want debug log level
-    #       c[:exception_details] = true      #and we want to see exception details
+    #       c[:log_level]         = &quot;debug&quot;   # except we want debug log level
+    #       c[:log_stream]        = @some_io  # and log to this IO handle
+    #       c[:exception_details] = true      # and we want to see exception details
     #     }
     #
     # ==== Parameters
@@ -477,9 +478,11 @@ module Merb
     #                             flush after new messages are
     #                             added, defaults to true.
     #
-    # :log_file&lt;IO&gt;::             IO for logger. Default is STDOUT.
+    # :log_stream&lt;IO&gt;::           IO handle for logger. Defaults to STDOUT.
     #
-    # :log_level&lt;Symbol&gt;::        logger level, default is :warn
+    # :log_file&lt;String&gt;::         File path for logger. Overrides :log_stream.
+    #
+    # :log_level&lt;Symbol&gt;::        logger level, default is :info
     #
     # :disabled_components&lt;Array[Symbol]&gt;::
     #   array of disabled component names,
@@ -495,7 +498,7 @@ module Merb
     # application start, some of them are set in Merb init file
     # or environment-specific.
     def load_config(options = {})
-      Merb::Config.setup({ :log_file =&gt; STDOUT, :log_level =&gt; :warn, :log_auto_flush =&gt; true }.merge(options))
+      Merb::Config.setup(Merb::Config.defaults.merge(options))
       Merb::BootLoader::Logger.run
     end
 </diff>
      <filename>lib/merb-core.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@ module Merb
     #---
     # @semipublic
     cattr_accessor :subclasses, :after_load_callbacks, :before_load_callbacks, :finished
-    self.subclasses, self.after_load_callbacks, 
+    self.subclasses, self.after_load_callbacks,
       self.before_load_callbacks, self.finished = [], [], [], []
 
     class &lt;&lt; self
@@ -75,7 +75,7 @@ module Merb
         end
         self.subclasses = subklasses
       end
-      
+
       # Determines whether or not a specific bootloader has finished yet.
       #
       # ==== Parameters
@@ -150,14 +150,14 @@ class Merb::BootLoader::Logger &lt; Merb::BootLoader
         Merb::Logger::Levels[:warn]
       else
         Merb::Logger::Levels[:debug]
-      end          
+      end
     end
-    
+
     Merb::Config[:log_stream] = Merb.log_stream
-    
+
     print_warnings
   end
-  
+
   def self.print_warnings
     if Gem::Version.new(Gem::RubyGemsVersion) &lt; Gem::Version.new(&quot;1.1&quot;)
       Merb.fatal! &quot;Merb requires Rubygems 1.1 and later. &quot; \
@@ -269,6 +269,9 @@ class Merb::BootLoader::Dependencies &lt; Merb::BootLoader
 
   def self.run
     set_encoding
+    # this is crucial: load init file with all the preferences
+    # then environment init file, then start enabling specific
+    # components, load dependencies and update logger.
     load_initfile
     load_env_config
     enable_json_gem unless Merb::disabled?(:json)
@@ -290,10 +293,18 @@ class Merb::BootLoader::Dependencies &lt; Merb::BootLoader
 
   def self.update_logger
     Merb.logger = nil
-    STDOUT.puts &quot;Logging to #{Merb::Config[:log_file] || 'stdout'}&quot; unless Merb.testing?
-    Merb::Config[:log_stream] = File.open(Merb::Config[:log_file], &quot;w+&quot;) if Merb::Config[:log_file]
+
+    # If log file is given, use it and not log stream we have.
+    if Merb::Config[:log_file]
+      raise &quot;log file should be a string, got: #{Merb::Config[:log_file].inspect}&quot; unless Merb::Config[:log_file].is_a?(String)
+      STDOUT.puts &quot;Logging to file at #{Merb::Config[:log_file]}&quot; unless Merb.testing?
+      Merb::Config[:log_stream] = File.open(Merb::Config[:log_file], &quot;w+&quot;)
+    # but if it's not given, fallback to log stream or stdout
+    else
+      Merb::Config[:log_stream] ||= STDOUT
+    end
   end
-  
+
   def self.set_encoding
     $KCODE = 'UTF8' if $KCODE == 'NONE' || $KCODE.blank?
   end
@@ -312,7 +323,10 @@ class Merb::BootLoader::Dependencies &lt; Merb::BootLoader
 
     # Loads the environment configuration file, if any
     def self.load_env_config
-      load(env_config) if env_config?
+      if env_config?
+        STDOUT.puts &quot;Loading #{env_config}&quot; unless Merb.testing?
+        load(env_config)
+      end
     end
 
     # Determines the init file to use, if any.
@@ -327,9 +341,11 @@ class Merb::BootLoader::Dependencies &lt; Merb::BootLoader
 
     # Loads the init file, should one exist
     def self.load_initfile
-      load(initfile) if File.exists?(initfile)
+      if File.exists?(initfile)
+        STDOUT.puts &quot;Loading init file from #{initfile}&quot; unless Merb.testing?
+        load(initfile)
+      end
     end
-
 end
 
 class Merb::BootLoader::MixinSession &lt; Merb::BootLoader
@@ -339,7 +355,7 @@ class Merb::BootLoader::MixinSession &lt; Merb::BootLoader
   # plugin session stores for example - these need to be loaded in a
   # before_app_loads block or a BootLoader that runs after MixinSession.
   #
-  # Note: access to Merb::Config is needed, so it needs to run after 
+  # Note: access to Merb::Config is needed, so it needs to run after
   # Merb::BootLoader::Dependencies is done.
   def self.run
     require 'merb-core/dispatch/session'
@@ -396,7 +412,7 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
 
       # Load application file if it exists - for flat applications
       load_file Merb.dir_for(:application) if File.file?(Merb.dir_for(:application))
-      
+
       # Load classes and their requirements
       Merb.load_paths.each do |component, path|
         next if path.last.blank? || component == :application || component == :router
@@ -405,7 +421,7 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
 
       Merb::Controller.send :include, Merb::GlobalHelpers
     end
-    
+
     # Wait for any children to exit, remove the &quot;main&quot; PID, and
     # exit.
     def exit_gracefully
@@ -496,14 +512,14 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
     # @param status&lt;Integer&gt; The status code to exit with
     def kill_children(status = 0)
       Merb.exiting = true unless status == 128
-      
+
       begin
         @writer.puts(status.to_s) if @writer
       rescue SystemCallError
       end
-      
+
       threads = []
-      
+
       ($CHILDREN || []).each do |p|
         threads &lt;&lt; Thread.new do
           begin
@@ -516,7 +532,7 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
       threads.each {|t| t.join }
       exit(status)
     end
-    
+
     # ==== Parameters
     # file&lt;String&gt;:: The file to load.
     def load_file(file)
@@ -524,7 +540,7 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
       unless Merb::Config[:fork_for_class_load]
         klasses = ObjectSpace.classes.dup
       end
-      
+
       # Ignore the file for syntax errors. The next time
       # the file is changed, it'll be reloaded again
       begin
@@ -536,13 +552,13 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
           MTIMES[file] = File.mtime(file)
         end
       end
-      
+
       # Don't do this expensive operation unless we need to
       unless Merb::Config[:fork_for_class_load]
         LOADED_CLASSES[file] = ObjectSpace.classes - klasses
       end
     end
-    
+
     # Load classes from given paths - using path/glob pattern.
     #
     # *paths&lt;Array&gt;::
@@ -570,7 +586,7 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
         remove_classes_in_file(file) { |f| load_file(f) }
       end
     end
-    
+
     # ==== Parameters
     # file&lt;String&gt;:: The file to remove classes for.
     # &amp;block:: A block to call with the file that has been removed.
@@ -608,7 +624,7 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
         Merb.logger.debug(&quot;Failed to remove constant #{object} from #{base}&quot;)
       end
     end
-    
+
     private
 
     # &quot;Better loading&quot; of classes.  If a class fails to load due to a NameError
@@ -646,7 +662,7 @@ class Merb::BootLoader::LoadClasses &lt; Merb::BootLoader
         if klasses.size == size_at_start &amp;&amp; klasses.size != 0
           # Write all remaining failed classes and their exceptions to the log
           messages = error_map.only(*failed_classes).map do |klass, e|
-            [&quot;Could not load #{klass}:\n\n#{e.message} - (#{e.class})&quot;, 
+            [&quot;Could not load #{klass}:\n\n#{e.message} - (#{e.class})&quot;,
               &quot;#{(e.backtrace || []).join(&quot;\n&quot;)}&quot;]
           end
           messages.each { |msg, trace| Merb.logger.fatal!(&quot;#{msg}\n\n#{trace}&quot;) }
@@ -662,18 +678,18 @@ end
 
 class Merb::BootLoader::Router &lt; Merb::BootLoader
   class &lt;&lt; self
-    
+
     def run
       Merb::BootLoader::LoadClasses.load_file(router_file) if router_file
     end
-    
+
     def reload!
       if router_file
         Merb::Router.reset!
         Merb::BootLoader::LoadClasses.reload(router_file)
       end
     end
-    
+
     def router_file
       @router_file ||= begin
         if File.file?(router = Merb.dir_for(:router) / Merb.glob_for(:router))
@@ -681,7 +697,7 @@ class Merb::BootLoader::Router &lt; Merb::BootLoader
         end
       end
     end
-   
+
   end
 end
 
@@ -747,13 +763,13 @@ class Merb::BootLoader::MimeTypes &lt; Merb::BootLoader
 end
 
 class Merb::BootLoader::Cookies &lt; Merb::BootLoader
-  
+
   def self.run
     require 'merb-core/dispatch/cookies'
     Merb::Controller.send(:include, Merb::CookiesMixin)
     Merb::Request.send(:include, Merb::CookiesMixin::RequestMixin)
   end
-  
+
 end
 
 class Merb::BootLoader::SetupSession &lt; Merb::BootLoader
@@ -766,22 +782,22 @@ class Merb::BootLoader::SetupSession &lt; Merb::BootLoader
       base_name = File.basename(file, &quot;.rb&quot;)
       require file unless base_name == &quot;container&quot; || base_name == &quot;store_container&quot;
     end
-    
+
     # Set some defaults.
     Merb::Config[:session_id_key] ||= &quot;_session_id&quot;
-    
+
     # List of all session_stores from :session_stores and :session_store config options.
     config_stores = Merb::Config.session_stores
-    
+
     # Register all configured session stores - any loaded session container class
     # (subclassed from Merb::SessionContainer) will be available for registration.
     Merb::SessionContainer.subclasses.each do |class_name|
-      if(store = Object.full_const_get(class_name)) &amp;&amp; 
+      if(store = Object.full_const_get(class_name)) &amp;&amp;
         config_stores.include?(store.session_store_type)
           Merb::Request.register_session_type(store.session_store_type, class_name)
       end
     end
-    
+
     # Mixin the Merb::Session module to add app-level functionality to sessions
     Merb::SessionContainer.send(:include, Merb::Session)
   end
@@ -854,7 +870,7 @@ class Merb::BootLoader::RackUpApplication &lt; Merb::BootLoader
          run Merb::Rack::Application.new
        }.to_app
     end
-    
+
   end
 end
 
@@ -883,7 +899,7 @@ class Merb::BootLoader::ReloadClasses &lt; Merb::BootLoader
       next unless glob
       paths &lt;&lt; Dir[path / glob]
     end
-  
+
     if Merb.dir_for(:application) &amp;&amp; File.file?(Merb.dir_for(:application))
       paths &lt;&lt; Merb.dir_for(:application)
     end
@@ -894,15 +910,15 @@ class Merb::BootLoader::ReloadClasses &lt; Merb::BootLoader
       GC.start
       reload(paths)
     end
-    
+
   end
 
   # Reloads all files.
   def self.reload(paths)
     paths.each do |file|
-      next if LoadClasses::MTIMES[file] &amp;&amp;  
+      next if LoadClasses::MTIMES[file] &amp;&amp;
         LoadClasses::MTIMES[file] == File.mtime(file)
-          
+
       LoadClasses.reload(file)
     end
   end</diff>
      <filename>lib/merb-core/bootloader.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,6 +21,7 @@ module Merb
           :log_delimiter          =&gt; &quot; ~ &quot;,
           :log_auto_flush         =&gt; false,
           :log_level              =&gt; :info,
+          :log_stream             =&gt; STDOUT,
           :disabled_components    =&gt; [],
           :deferred_actions       =&gt; [],
           :verbose                =&gt; false,
@@ -36,6 +37,7 @@ module Merb
       # ==== Examples
       #   Merb::Config.use do |config|
       #     config[:exception_details] = false
+      #     config[:log_stream]        = STDOUT
       #   end
       def use
         @configuration ||= {}
@@ -348,6 +350,7 @@ module Merb
       #   Merb::Config.configure do
       #     environment &quot;development&quot;
       #     log_level   &quot;debug&quot;
+      #     log_file    Merb.root / &quot;log&quot; / &quot;special.log&quot;
       #   end
       def configure(&amp;block)
         ConfigBlock.new(self, &amp;block) if block_given?</diff>
      <filename>lib/merb-core/config.rb</filename>
    </modified>
    <modified>
      <diff>@@ -66,6 +66,6 @@ task :stats do
   code_loc = [:controllers, :helpers, :models].inject(0) { |sum, e| sum += @all[e][:loc] }
   test_loc = @all[:spec][:loc]
  
-  puts &quot;   Code LOC: #{cb}#{code_loc}#{ce}     Test LOC: #{cb}#{test_loc}#{ce}     Test to code radio:  #{cb}1:%0.2f#{ce}&quot; % (test_loc.to_f / code_loc.to_f)
+  puts &quot;   Code LOC: #{cb}#{code_loc}#{ce}     Test LOC: #{cb}#{test_loc}#{ce}     Code to test radio:  #{cb}1:%0.2f#{ce}&quot; % (test_loc.to_f / code_loc.to_f)
   puts
 end</diff>
      <filename>lib/merb-core/tasks/stats.rake</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>4c4f24ad393999037e34e5f0791674217c6862dd</id>
    </parent>
  </parents>
  <author>
    <name>Michael S. Klishin</name>
    <email>michael@novemberain.com</email>
  </author>
  <url>http://github.com/wycats/merb-core/commit/5a10f1840c3af5e1ddfc5895b85512d649541ffa</url>
  <id>5a10f1840c3af5e1ddfc5895b85512d649541ffa</id>
  <committed-date>2008-10-07T05:06:24-07:00</committed-date>
  <authored-date>2008-10-07T04:26:07-07:00</authored-date>
  <message>Use new logger options log_stream/log_file the same way everywhere.</message>
  <tree>dbdbd644d6a3826d599cbb0554f4c0f54bcfeb55</tree>
  <committer>
    <name>Michael S. Klishin</name>
    <email>michael@novemberain.com</email>
  </committer>
</commit>
