lib/semantic_logger/appender/base.rb in semantic_logger-3.0.1 vs lib/semantic_logger/appender/base.rb in semantic_logger-3.1.0
- old
+ new
@@ -1,12 +1,5 @@
-require 'json'
-# Load AwesomePrint if available
-begin
- require 'awesome_print'
-rescue LoadError
-end
-
# Base appender
#
# Abstract base class for appenders
#
# Implements common behavior such as default text formatter etc
@@ -14,151 +7,79 @@
# Note: Do not create instances of this class directly
#
module SemanticLogger
module Appender
- # Formatting & colors used by optional colorized_formatter
- module AnsiColors
- CLEAR = "\e[0m"
- BOLD = "\e[1m"
- BLACK = "\e[30m"
- RED = "\e[31m"
- GREEN = "\e[32m"
- YELLOW = "\e[33m"
- BLUE = "\e[34m"
- MAGENTA = "\e[35m"
- CYAN = "\e[36m"
- WHITE = "\e[37m"
+ # DEPRECATED, use SemanticLogger::AnsiColors
+ AnsiColors = SemanticLogger::AnsiColors
- # Maps the log level to a color for colorized formatters
- # Since this map is not frozen, it can be modified as needed
- LEVEL_MAP = {
- trace: MAGENTA,
- debug: GREEN,
- info: CYAN,
- warn: BOLD,
- error: RED,
- fatal: RED
- }
- end
-
class Base < SemanticLogger::Base
+ # Every logger has its own formatter
attr_accessor :formatter
- # Default log formatter
- # Replace this formatter by supplying a Block to the initializer
- # Generates logs of the form:
- # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
- def default_formatter
- Proc.new do |log, logger|
- # Header with date, time, log level and process info
- entry = "#{log.formatted_time} #{log.level_to_s} [#{log.process_info}]"
+ # Returns the current log level if set, otherwise it logs everything it receives
+ def level
+ @level || :trace
+ end
- # Tags
- entry << ' ' << log.tags.collect { |tag| "[#{tag}]" }.join(' ') if log.tags && (log.tags.size > 0)
+ # An appender can implement a flush method if it is able to.
+ def flush
+ # NOOP
+ end
- # Duration
- entry << " (#{log.duration_human})" if log.duration
-
- # Class / app name
- entry << " #{log.name}"
-
- # Log message
- entry << " -- #{log.message}" if log.message
-
- # Payload
- if payload = log.payload_to_s(false)
- entry << ' -- ' << payload
- end
-
- # Exceptions
- if log.exception
- entry << " -- Exception: #{log.exception.class}: #{log.exception.message}\n"
- entry << log.backtrace_to_s
- end
- entry
- end
+ # DEPRECATED: use SemanticLogger::Formatters::Default.new
+ def default_formatter
+ warn '[DEPRECATION] SemanticLogger::Appender::Base.default_level is deprecated. Please use SemanticLogger::Formatters::Default.new instead.'
+ formatter = SemanticLogger::Formatters::Default.new
+ Proc.new { |log, logger| formatter.call(log, logger) }
end
- # Optional log formatter to colorize log output
- # To use this formatter
- # SemanticLogger.add_appender($stdout, &SemanticLogger::Appender::Base.colorized_formatter)
- #
- # 2011-07-19 14:36:15.660 D [1149:ScriptThreadProcess] Rails -- Hello World
+ # DEPRECATED: use SemanticLogger::Formatters::Color.new
def self.colorized_formatter
- Proc.new do |log, logger|
- colors = SemanticLogger::Appender::AnsiColors
- level_color = colors::LEVEL_MAP[log.level]
-
- # Header with date, time, log level and process info
- entry = "#{log.formatted_time} #{level_color}#{log.level_to_s}#{colors::CLEAR} [#{log.process_info}]"
-
- # Tags
- entry << ' ' << log.tags.collect { |tag| "[#{level_color}#{tag}#{colors::CLEAR}]" }.join(' ') if log.tags && (log.tags.size > 0)
-
- # Duration
- entry << " (#{colors::BOLD}#{log.duration_human}#{colors::CLEAR})" if log.duration
-
- # Class / app name
- entry << " #{level_color}#{log.name}#{colors::CLEAR}"
-
- # Log message
- entry << " -- #{log.message}" if log.message
-
- # Payload
- if payload = log.payload_to_s(true)
- entry << ' -- ' << payload
- end
-
- # Exceptions
- if log.exception
- entry << " -- Exception: #{colors::BOLD}#{log.exception.class}: #{log.exception.message}#{colors::CLEAR}\n"
- entry << log.backtrace_to_s
- end
- entry
- end
+ warn '[DEPRECATION] SemanticLogger::Appender::Base.colorized_formatter is deprecated. Please use SemanticLogger::Formatters::Color.new instead.'
+ formatter = SemanticLogger::Formatters::Color.new
+ Proc.new { |log, logger| formatter.call(log, logger) }
end
- # Optional log formatter to output data in a hash format
- # To use this formatter
- # SemanticLogger.add_appender($stdout, &SemanticLogger::Appender::Base.json_formatter)
+ # DEPRECATED: use SemanticLogger::Formatters::Json.new
def self.json_formatter
- Proc.new do |log, logger|
- h = log.to_h
- h.delete(:time)
- h[:timestamp] = log.time.utc.iso8601(defined?(JRuby) ? 3 : 6)
- h.to_json
- end
+ warn '[DEPRECATION] SemanticLogger::Appender::Base.json_formatter is deprecated. Please use SemanticLogger::Formatters::Json.new instead.'
+ formatter = SemanticLogger::Formatters::Json.new
+ Proc.new { |log, logger| formatter.call(log, logger) }
end
- def flush
- # An appender can implement a flush method if it supports it.
- end
-
- # Returns the current log level if set, otherwise it returns the global
- # default log level
- def level
- @level || :trace
- end
-
private
# Initializer for Abstract Class SemanticLogger::Appender
#
# Parameters
- # level [Symbol]
- # Only allow log entries of this level or higher to be written to this appender
- # For example if set to :warn, this appender would only log :warn and :fatal
- # log messages when other appenders could be logging :info and lower
+ # level: [:trace | :debug | :info | :warn | :error | :fatal]
+ # Override the log level for this appender.
+ # Default: :error
#
- # filter [RegExp|Proc]
- # Optional regular expression to filter log entries based on the class name
- # When filter is a proc, it is passed the entire log struct and must return
- # true or false indicating whether to log the message
- def initialize(level=nil, filter=nil, &block)
- # Set the formatter to the supplied block
- @formatter = block || default_formatter
+ # formatter: [Object|Proc]
+ # An instance of a class that implements #call, or a Proc to be used to format
+ # the output from this appender
+ # Default: Use the built-in formatter (See: #call)
+ #
+ # filter: [Regexp|Proc]
+ # RegExp: Only include log messages where the class name matches the supplied.
+ # regular expression. All other messages will be ignored.
+ # Proc: Only include log messages where the supplied Proc returns true
+ # The Proc must return true or false.
+ def initialize(options={}, &block)
+ # Backward compatibility
+ options = {level: options} unless options.is_a?(Hash)
+ options = options.dup
+ level = options.delete(:level)
+ filter = options.delete(:filter)
+ @formatter = options.delete(:formatter)
+ @formatter = self.class.extract_formatter(@formatter) if @formatter.is_a?(Symbol)
+ @formatter ||= block
+ # Default to #call method for formatting if defined for an appender
+ @formatter ||= (respond_to?(:call) ? self : SemanticLogger::Formatters::Default.new)
+ raise(ArgumentError, "Unknown options: #{options.inspect}") if options.size > 0
# Appenders don't take a class name, so use this class name if an appender
# is logged to directly
super(self.class, level, filter)
end
@@ -166,9 +87,14 @@
# Return the level index for fast comparisons
# Returns the lowest level index if the level has not been explicitly
# set for this instance
def level_index
@level_index || 0
+ end
+
+ # Return formatter for supplied Symbol
+ def self.extract_formatter(formatter)
+ SemanticLogger.send(:named_formatter, formatter).new
end
end
end
end