112 lines
3.1 KiB
Ruby
112 lines
3.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Log
|
|
class Log
|
|
class LogFormatter < Logger::Formatter
|
|
attr_reader :options
|
|
|
|
def initialize(options = {})
|
|
@options = options
|
|
super() # superclass does not take parameters
|
|
end
|
|
|
|
def call(severity, timestamp, progname, msg)
|
|
super(severity, timestamp, progname, "#{log_tags}#{msg}")
|
|
end
|
|
|
|
def log_tags
|
|
tags = formatted_tags.join ' '
|
|
tags.blank? ? '' : "[#{tags}] "
|
|
end
|
|
|
|
private
|
|
def formatted_tags
|
|
elems = [Thread.current[:name].to_s]
|
|
elems += (options[:tags] || []).map { |e| e.is_a?(Proc) ? e.call : e }
|
|
elems.reject(&:blank?)
|
|
end
|
|
end
|
|
|
|
attr_reader :options # default = {}
|
|
|
|
# Options may include:
|
|
# tags: an array of static elements and/or callable Procs to include in log output
|
|
# filename: specifies filename for log in Rails log directory
|
|
# stream: specifies stream for log output (included for test support)
|
|
def initialize(options = {})
|
|
@options = options
|
|
end
|
|
|
|
def logger
|
|
@logger ||= begin
|
|
new_logger = Logger.new log_destination
|
|
new_logger.level = numeric_log_level
|
|
new_logger.formatter = LogFormatter.new options
|
|
new_logger
|
|
end
|
|
end
|
|
|
|
def numeric_log_level
|
|
AppConfig.numeric_log_level
|
|
end
|
|
|
|
# Returns filename for log or stream object if specified in options.
|
|
def log_destination
|
|
options[:stream].present? ? options[:stream] : log_filepath
|
|
end
|
|
|
|
def log_filepath
|
|
@log_filepath ||= log_dir.join log_filename
|
|
end
|
|
|
|
def log_filename
|
|
options[:filename].present? ? options[:filename].to_s : "#{Rails.env.to_s}.log"
|
|
end
|
|
|
|
def log_dir
|
|
@log_dir ||= begin
|
|
dir = Rails.root.join 'log'
|
|
FileUtils.mkdir_p dir
|
|
dir
|
|
end
|
|
end
|
|
|
|
# Same semantics as Log.error except uses current instance of logger.
|
|
def error(msg, exception = nil, options = {})
|
|
Log.log_error logger, msg, exception, options
|
|
end
|
|
|
|
# Same semantics as Log.raise_error except uses current instance of logger.
|
|
def raise_error(msg, exception, options = {})
|
|
error msg, exception, options
|
|
raise exception
|
|
end
|
|
|
|
class << self
|
|
# Logs and re-raises exception.
|
|
def raise_error (msg, exception, options = {})
|
|
error msg, exception, options
|
|
raise exception
|
|
end
|
|
|
|
# Logs error with exception backtrace detail if available. Always uses Rails.logger.
|
|
#
|
|
# Options may include:
|
|
# no_backtrace: true suppresses backtrace
|
|
#
|
|
# Returns formatted msg.
|
|
def error(msg, exception = nil, options = {})
|
|
log_error Rails.logger, msg, exception, options
|
|
end
|
|
|
|
# Same semantics as Log.error except uses specified logger.
|
|
def log_error(logger, msg, exception = nil, options = {})
|
|
message = exception.nil? ? msg : "Exception #{exception.class.name}: #{exception.inspect} #{msg}"
|
|
logger.error message
|
|
logger.error exception.backtrace if exception.try(:backtrace) && !options[:no_backtrace]
|
|
message
|
|
end
|
|
end
|
|
end
|
|
end
|