Merge pull request #2444 from createdbypete/configurable-logger
This commit is contained in:
commit
83fb1fd0f6
|
@ -21,6 +21,7 @@ require 'time'
|
|||
require 'safe_yaml/load'
|
||||
require 'English'
|
||||
require 'pathname'
|
||||
require 'logger'
|
||||
|
||||
# 3rd party
|
||||
require 'liquid'
|
||||
|
@ -31,6 +32,7 @@ require 'toml'
|
|||
# internal requires
|
||||
require 'jekyll/version'
|
||||
require 'jekyll/utils'
|
||||
require 'jekyll/log_adapter'
|
||||
require 'jekyll/stevenson'
|
||||
require 'jekyll/deprecator'
|
||||
require 'jekyll/configuration'
|
||||
|
@ -116,7 +118,11 @@ module Jekyll
|
|||
end
|
||||
|
||||
def self.logger
|
||||
@logger ||= Stevenson.new
|
||||
@logger ||= LogAdapter.new(Stevenson.new)
|
||||
end
|
||||
|
||||
def self.logger=(writer)
|
||||
@logger = LogAdapter.new(writer)
|
||||
end
|
||||
|
||||
# Public: File system root
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
module Jekyll
|
||||
class LogAdapter
|
||||
attr_reader :writer
|
||||
|
||||
LOG_LEVELS = {
|
||||
:debug => ::Logger::DEBUG,
|
||||
:info => ::Logger::INFO,
|
||||
:warn => ::Logger::WARN,
|
||||
:error => ::Logger::ERROR
|
||||
}
|
||||
|
||||
# Public: Create a new instance of Jekyll's log writer
|
||||
#
|
||||
# writer - Logger compatible instance
|
||||
# log_level - (optional, symbol) the log level
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(writer, level = :info)
|
||||
@writer = writer
|
||||
self.log_level = level
|
||||
end
|
||||
|
||||
# Public: Set the log level on the writer
|
||||
#
|
||||
# level - (symbol) the log level
|
||||
#
|
||||
# Returns nothing
|
||||
def log_level=(level)
|
||||
writer.level = LOG_LEVELS.fetch(level)
|
||||
end
|
||||
|
||||
# Public: Print a jekyll debug message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def debug(topic, message = nil)
|
||||
writer.debug(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def info(topic, message = nil)
|
||||
writer.info(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def warn(topic, message = nil)
|
||||
writer.warn(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a jekyll error message
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def error(topic, message = nil)
|
||||
writer.error(message(topic, message))
|
||||
end
|
||||
|
||||
# Public: Print a Jekyll error message and immediately abort the process
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail (can be omitted)
|
||||
#
|
||||
# Returns nothing
|
||||
def abort_with(topic, message = nil)
|
||||
error(topic, message)
|
||||
abort
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Internal: Build a Jekyll topic method
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns the formatted message
|
||||
def message(topic, message)
|
||||
formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ')
|
||||
end
|
||||
|
||||
# Internal: Format the topic
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
#
|
||||
# Returns the formatted topic statement
|
||||
def formatted_topic(topic)
|
||||
"#{topic} ".rjust(20)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,102 +1,58 @@
|
|||
module Jekyll
|
||||
class Stevenson
|
||||
attr_accessor :log_level
|
||||
|
||||
LOG_LEVELS = {
|
||||
debug: 0,
|
||||
info: 1,
|
||||
warn: 2,
|
||||
error: 3
|
||||
}
|
||||
|
||||
# Public: Create a new instance of Stevenson, Jekyll's logger
|
||||
#
|
||||
# level - (optional, symbol) the log level
|
||||
#
|
||||
# Returns nothing
|
||||
def initialize(level = :info)
|
||||
@log_level = level
|
||||
class Stevenson < ::Logger
|
||||
def initialize
|
||||
@progname = nil
|
||||
@level = DEBUG
|
||||
@default_formatter = Formatter.new
|
||||
@logdev = $stdout
|
||||
@formatter = proc do |severity, datetime, progname, msg|
|
||||
"#{msg}"
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Print a jekyll debug message to stdout
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def debug(topic, message = nil)
|
||||
$stdout.puts(message(topic, message)) if should_log(:debug)
|
||||
def add(severity, message = nil, progname = nil, &block)
|
||||
severity ||= UNKNOWN
|
||||
@logdev = set_logdevice(severity)
|
||||
|
||||
if @logdev.nil? or severity < @level
|
||||
return true
|
||||
end
|
||||
progname ||= @progname
|
||||
if message.nil?
|
||||
if block_given?
|
||||
message = yield
|
||||
else
|
||||
message = progname
|
||||
progname = @progname
|
||||
end
|
||||
end
|
||||
@logdev.puts(
|
||||
format_message(format_severity(severity), Time.now, progname, message))
|
||||
true
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message to stdout
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def info(topic, message = nil)
|
||||
$stdout.puts(message(topic, message)) if should_log(:info)
|
||||
# Log a +WARN+ message
|
||||
def warn(progname = nil, &block)
|
||||
add(WARN, nil, progname.yellow, &block)
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message to stderr
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def warn(topic, message = nil)
|
||||
$stderr.puts(message(topic, message).yellow) if should_log(:warn)
|
||||
# Log an +ERROR+ message
|
||||
def error(progname = nil, &block)
|
||||
add(ERROR, nil, progname.red, &block)
|
||||
end
|
||||
|
||||
# Public: Print a jekyll error message to stderr
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def error(topic, message = nil)
|
||||
$stderr.puts(message(topic, message).red) if should_log(:error)
|
||||
def close
|
||||
# No LogDevice in use
|
||||
end
|
||||
|
||||
# Public: Print a Jekyll error message to stderr and immediately abort the process
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail (can be omitted)
|
||||
#
|
||||
# Returns nothing
|
||||
def abort_with(topic, message = nil)
|
||||
error(topic, message)
|
||||
abort
|
||||
end
|
||||
private
|
||||
|
||||
# Public: Build a Jekyll topic method
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns the formatted message
|
||||
def message(topic, message)
|
||||
formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ')
|
||||
end
|
||||
|
||||
# Public: Format the topic
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
#
|
||||
# Returns the formatted topic statement
|
||||
def formatted_topic(topic)
|
||||
"#{topic} ".rjust(20)
|
||||
end
|
||||
|
||||
# Public: Determine whether the current log level warrants logging at the
|
||||
# proposed level.
|
||||
#
|
||||
# level_of_message - the log level of the message (symbol)
|
||||
#
|
||||
# Returns true if the log level of the message is greater than or equal to
|
||||
# this logger's log level.
|
||||
def should_log(level_of_message)
|
||||
LOG_LEVELS.fetch(log_level) <= LOG_LEVELS.fetch(level_of_message)
|
||||
def set_logdevice(severity)
|
||||
if severity > INFO
|
||||
$stderr
|
||||
else
|
||||
$stdout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
require 'helper'
|
||||
|
||||
class TestLogAdapter < Test::Unit::TestCase
|
||||
class LoggerDouble
|
||||
attr_accessor :level
|
||||
end
|
||||
|
||||
context "#log_level=" do
|
||||
should "set the writers logging level" do
|
||||
subject = Jekyll::LogAdapter.new(LoggerDouble.new)
|
||||
subject.log_level = :error
|
||||
assert_equal Jekyll::LogAdapter::LOG_LEVELS[:error], subject.writer.level
|
||||
end
|
||||
end
|
||||
|
||||
context "#debug" do
|
||||
should "call #debug on writer return true" do
|
||||
writer = LoggerDouble.new
|
||||
logger = Jekyll::LogAdapter.new(writer)
|
||||
stub(writer).debug('topic '.rjust(20) + 'log message') { true }
|
||||
assert logger.debug('topic', 'log message')
|
||||
end
|
||||
end
|
||||
|
||||
context "#info" do
|
||||
should "call #info on writer return true" do
|
||||
writer = LoggerDouble.new
|
||||
logger = Jekyll::LogAdapter.new(writer)
|
||||
stub(writer).info('topic '.rjust(20) + 'log message') { true }
|
||||
assert logger.info('topic', 'log message')
|
||||
end
|
||||
end
|
||||
|
||||
context "#warn" do
|
||||
should "call #warn on writer return true" do
|
||||
writer = LoggerDouble.new
|
||||
logger = Jekyll::LogAdapter.new(writer)
|
||||
stub(writer).warn('topic '.rjust(20) + 'log message') { true }
|
||||
assert logger.warn('topic', 'log message')
|
||||
end
|
||||
end
|
||||
|
||||
context "#error" do
|
||||
should "call #error on writer return true" do
|
||||
writer = LoggerDouble.new
|
||||
logger = Jekyll::LogAdapter.new(writer)
|
||||
stub(writer).error('topic '.rjust(20) + 'log message') { true }
|
||||
assert logger.error('topic', 'log message')
|
||||
end
|
||||
end
|
||||
|
||||
context "#abort_with" do
|
||||
should "call #error and abort" do
|
||||
logger = Jekyll::LogAdapter.new(LoggerDouble.new)
|
||||
stub(logger).error('topic', 'log message') { true }
|
||||
assert_raise(SystemExit) { logger.abort_with('topic', 'log message') }
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue