Skip to content

Commit

Permalink
Merge commit 'adelcambre/sprint' into sprint
Browse files Browse the repository at this point in the history
  • Loading branch information
wycats committed Oct 11, 2008
2 parents 5e4a862 + d425060 commit a7fb18c
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 122 deletions.
6 changes: 1 addition & 5 deletions lib/merb-core.rb
Expand Up @@ -278,11 +278,7 @@ def root_path(*path)

# Logger settings
def logger
Thread.current[:merb_logger] ||= Merb::Logger.new(
Merb::Config[:log_stream],
Merb::Config[:log_level],
Merb::Config[:log_delimiter],
Merb::Config[:log_auto_flush])
Thread.current[:merb_logger] ||= Merb::Logger.new
end

def reset_logger!
Expand Down
2 changes: 0 additions & 2 deletions lib/merb-core/controller/merb_controller.rb
Expand Up @@ -97,8 +97,6 @@ def self._filter_params(params)
params
end

private

# All methods that are callable as actions.
#
# ==== Returns
Expand Down
182 changes: 162 additions & 20 deletions lib/merb-core/logger.rb
@@ -1,5 +1,16 @@
# Merb::Logger = Extlib::Logger

class Merb::Logger < Extlib::Logger
def verbose!(message, level = :warn)
send("#{level}!", message) if Merb::Config[:verbose]
end

def verbose(message, level = :warn)
send(level, message) if Merb::Config[:verbose]
end
end

# require "time" # httpdate
# ==== Public Merb Logger API
#
# To replace an existing logger with a new one:
Expand Down Expand Up @@ -34,37 +45,168 @@
# Merb::Logger.new(log{String, IO},level{Symbol, String})
module Merb

class Logger < Extlib::Logger
class Logger

attr_accessor :level
attr_accessor :delimiter
attr_accessor :auto_flush
attr_reader :buffer
attr_reader :log
attr_reader :init_args

# ==== Notes
# Ruby (standard) logger levels:
# :fatal:: An unhandleable error that results in a program crash
# :error:: A handleable error condition
# :warn:: A warning
# :info:: generic (useful) information about system operation
# :debug:: low-level information for developers
Levels = Mash.new({
:fatal => 7,
:error => 6,
:warn => 4,
:info => 3,
:debug => 0
}) unless const_defined?(:Levels)

@@mutex = {}

# Appends a message to the log if the specified log level is at least as high as
# the log level of the logger if Merb::Config[:verbose]. Then flushes the log
# buffer to disk.
private

# Readies a log for writing.
#
# ==== Parameters
# message<String>:: The message to be logged.
# level<Symbol>:: The level at which to log. Default is :warn.
# log<IO, String>:: Either an IO object or a name of a logfile.
def initialize_log(log)
close if @log # be sure that we don't leave open files laying around.

if log.respond_to?(:write)
@log = log
elsif File.exist?(log)
@log = open(log, (File::WRONLY | File::APPEND))
@log.sync = true
else
FileUtils.mkdir_p(File.dirname(log)) unless File.directory?(File.dirname(log))
@log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
@log.sync = true
@log.write("#{Time.now.httpdate} #{delimiter} info #{delimiter} Logfile created\n")
end
end

public

# To initialize the logger you create a new object, proxies to set_log.
#
# ==== Returns
# self:: The logger object for chaining.
# ==== Parameters
# *args:: Arguments to create the log from. See set_logs for specifics.
def initialize(*args)
set_log(*args)
end

# Replaces an existing logger with a new one.
#
# @api plugin
def verbose!(message, level = :warn)
send("#{level}!", message) if Merb::Config[:verbose]
# ==== Parameters
# log<IO, String>:: Either an IO object or a name of a logfile.
# log_level<~to_sym>::
# The log level from, e.g. :fatal or :info. Defaults to :error in the
# production environment and :debug otherwise.
# delimiter<String>::
# Delimiter to use between message sections. Defaults to " ~ ".
# auto_flush<Boolean>::
# Whether the log should automatically flush after new messages are
# added. Defaults to false.
def set_log(stream = Merb::Config[:log_stream],
log_level = Merb::Config[:log_level],
delimiter = Merb::Config[:log_delimiter],
auto_flush = Merb::Config[:log_auto_flush])

@buffer = []
@delimiter = delimiter
@auto_flush = auto_flush

if Levels[log_level]
@level = Levels[log_level]
else
@level = log_level
end

@log = stream
@mutex = (@@mutex[@log] ||= Mutex.new)
end

# Flush the entire buffer to the log object.
def flush
return unless @buffer.size > 0
@mutex.synchronize do
@log.write(@buffer.slice!(0..-1).to_s)
end
end

# Close and remove the current log object.
def close
flush
@log.close if @log.respond_to?(:close) && !@log.tty?
@log = nil
end

# Appends a message to the log if the specified log level is at least as high as
# the log level of the logger if Merb::Config[:verbose].
# Appends a message to the log. The methods yield to an optional block and
# the output of this block will be appended to the message.
#
# ==== Parameters
# message<String>:: The message to be logged.
# level<Symbol>:: The level at which to log. Default is :warn.
# string<String>:: The message to be logged. Defaults to nil.
#
# ==== Returns
# self:: The logger object for chaining.
#
# @api plugin
def verbose(message, level = :warn)
send(level, message) if Merb::Config[:verbose]
# String:: The resulting message added to the log file.
def <<(string = nil)
message = ""
message << delimiter
message << string if string
message << "\n" unless message[-1] == ?\n
@buffer << message
flush if @auto_flush

message
end
alias :push :<<

# Generate the logging methods for Merb.logger for each log level.
Levels.each_pair do |name, number|
class_eval <<-LEVELMETHODS, __FILE__, __LINE__
# Appends a message to the log if the log level is at least as high as
# the log level of the logger.
#
# ==== Parameters
# string<String>:: The message to be logged. Defaults to nil.
#
# ==== Returns
# self:: The logger object for chaining.
def #{name}(message = nil)
self << message if #{number} >= level
self
end
# Appends a message to the log if the log level is at least as high as
# the log level of the logger. The bang! version of the method also auto
# flushes the log buffer to disk.
#
# ==== Parameters
# string<String>:: The message to be logged. Defaults to nil.
#
# ==== Returns
# self:: The logger object for chaining.
def #{name}!(message = nil)
self << message if #{number} >= level
flush if #{number} >= level
self
end
# ==== Returns
# Boolean:: True if this level will be logged by this logger.
def #{name}?
#{number} >= level
end
LEVELMETHODS
end

end
Expand Down
91 changes: 0 additions & 91 deletions spec/public/logger/logger_spec.rb
Expand Up @@ -21,14 +21,6 @@

describe Merb::Logger do

describe "Levels" do
it "should have the same entries as Extlib::Logger::Levels" do
Extlib::Logger::Levels.each do |level, value|
Merb::Logger::Levels[level].should == value
end
end
end

describe "#new" do
it "should call set_log with the arguments it was passed." do
logger = Merb::Logger.allocate # create an object sans initialization
Expand All @@ -49,12 +41,6 @@
Merb.logger.level.should == 4
end

it "should set the log level to a specific numeric value when that value is set into Mer" do
Merb::Config[:log_level] = 5
Merb.reset_logger!
Merb.logger.level.should == 5
end

it "should set the log level to :debug (0) when Merb.environment is development" do
Merb.environment = "development"
Merb::Config.delete(:log_level)
Expand Down Expand Up @@ -294,81 +280,4 @@ def set_level(level)
Merb.logger.should log_with_method(:fatal)
end
end # #fatal

describe "#verbose" do
before do
@stream = Merb::Config[:log_stream] = StringIO.new
Merb.reset_logger!
end

describe "when Merb::Config[:verbose] is false" do
it "should not log any messages" do
Merb::Config[:verbose] = false
Merb::Config[:log_level] = :debug
Merb.logger.verbose("message", :fatal)
Merb.logger.flush

Merb.logger.log.string.should_not include("message")
end
end

describe "when Merb::Config[:verbose] is true" do
before do
Merb::Config[:verbose] = true
Merb::Config[:log_level] = :debug
end

it "adds to the buffer with error level" do
set_level(:error)
Merb.logger.verbose("message", :error)
Merb.logger.flush
Merb.logger.log.string.should include("message")
end

it "adds to the buffer with fatal level" do
set_level(:fatal)
Merb.logger.verbose("message", :error)
Merb.logger.flush
Merb.logger.log.string.should_not include("message")
end

end
end

describe "#verbose!" do
before do
@stream = Merb::Config[:log_stream] = StringIO.new
Merb.reset_logger!
end

describe "when Merb::Config[:verbose] is false" do
it "should not log any messages" do
Merb::Config[:verbose] = false
Merb::Config[:log_level] = :debug
Merb.logger.verbose!("message", :fatal)
Merb.logger.log.string.should_not include("message")
end
end

describe "when Merb::Config[:verbose] is true" do
before do
Merb::Config[:verbose] = true
Merb::Config[:log_level] = :debug
end

it "adds to the buffer with error level" do
set_level(:error)
Merb.logger.verbose!("message", :error)
Merb.logger.log.string.should include("message")
end

it "adds to the buffer with fatal level" do
set_level(:fatal)
Merb.logger.verbose!("message", :error)
Merb.logger.log.string.should_not include("message")
end

end
end

end # Merb::Logger
8 changes: 4 additions & 4 deletions spec/public/router/recognition/deferred_spec.rb
Expand Up @@ -6,7 +6,7 @@
before :each do
Merb::Router.prepare do
match("/deferred/:zoo").defer_to do |request, params|
route params.merge(:controller => "w00t") if params[:zoo]
params.merge(:controller => "w00t") if params[:zoo]
end
end
end
Expand All @@ -22,7 +22,7 @@
it "should return the param hash returned by the block" do
Merb::Router.prepare do
match("/deferred").defer_to do |request, params|
route :hello => "world"
:hello => "world"
end
end

Expand All @@ -32,7 +32,7 @@
it "should accept params" do
Merb::Router.prepare do
match("/").defer_to(:controller => "accounts") do |request, params|
route params.update(:action => "hello")
params.update(:action => "hello")
end
end

Expand All @@ -42,7 +42,7 @@
it "should be able to define routes after the deferred route" do
Merb::Router.prepare do
match("/deferred").defer_to do
route :hello => "world"
:hello => "world"
end

match("/").to(:foo => "bar")
Expand Down

0 comments on commit a7fb18c

Please sign in to comment.