lib/semantic_logger/base.rb in semantic_logger-4.1.1 vs lib/semantic_logger/base.rb in semantic_logger-4.2.0
- old
+ new
@@ -122,12 +122,20 @@
# Backward compatibility
alias_method :benchmark, :measure
# Log a thread backtrace
- def backtrace(thread: Thread.current, level: :warn, message: 'Backtrace:', payload: nil, metric: nil, metric_amount: 1)
- log = Log.new(name, level)
+ def backtrace(thread: Thread.current,
+ level: :warn,
+ message: 'Backtrace:',
+ payload: nil,
+ metric: nil,
+ metric_amount: nil)
+
+ log = Log.new(name, level)
+ return false unless meets_log_level?(log)
+
backtrace =
if thread == Thread.current
Log.cleanse_backtrace
else
log.thread_name = thread.name
@@ -140,12 +148,14 @@
if backtrace
message += "\n"
message << backtrace.join("\n")
end
- if log.assign(message: message, backtrace: backtrace, payload: payload, metric: metric, metric_amount: metric_amount) && should_log?(log)
+ if log.assign(message: message, backtrace: backtrace, payload: payload, metric: metric, metric_amount: metric_amount) && !filtered?(log)
self.log(log)
+ else
+ false
end
end
# Add the tags or named tags to the list of tags to log for this thread whilst the supplied block is active.
#
@@ -230,17 +240,20 @@
def payload
warn '#payload is deprecated, use SemanticLogger.named_tags'
SemanticLogger.named_tags
end
- protected
-
# Write log data to underlying data storage
def log(log_)
raise NotImplementedError.new('Logging Appender must implement #log(log)')
end
+ # Whether this log entry meets the criteria to be logged by this appender.
+ def should_log?(log)
+ meets_log_level?(log) && !filtered?(log)
+ end
+
private
# Initializer for Abstract Class SemanticLogger::Base
#
# Parameters
@@ -279,37 +292,44 @@
def level_index
@level_index || SemanticLogger.default_level_index
end
# Whether to log the supplied message based on the current filter if any
- def include_message?(log)
- return true if @filter.nil?
+ def filtered?(log)
+ return false if @filter.nil?
if @filter.is_a?(Regexp)
- (@filter =~ log.name) != nil
+ (@filter =~ log.name) == nil
elsif @filter.is_a?(Proc)
- @filter.call(log) == true
+ @filter.call(log) != true
+ else
+ raise(ArgumentError, "Unrecognized semantic logger filter: #{@filter.inspect}, must be a Regexp or a Proc")
end
end
- # Whether the log message should be logged for the current logger or appender
- def should_log?(log)
- # Ensure minimum log level is met, and check filter
- (level_index <= (log.level_index || 0)) && include_message?(log)
+ # Ensure minimum log level is met
+ def meets_log_level?(log)
+ (level_index <= (log.level_index || 0))
end
# Log message at the specified level
def log_internal(level, index, message = nil, payload = nil, exception = nil, &block)
log = Log.new(name, level, index)
should_log =
if payload.nil? && exception.nil? && message.is_a?(Hash)
- log.assign(message)
+ # Check if someone just logged a hash payload instead of meaning to call semantic logger
+ if message.has_key?(:message) || message.has_key?(:payload) || message.has_key?(:exception) || message.has_key?(:metric)
+ log.assign(message)
+ else
+ log.assign_positional(nil, message, nil, &block)
+ end
else
log.assign_positional(message, payload, exception, &block)
end
- self.log(log) if should_log && include_message?(log)
+ # Log level may change during assign due to :on_exception_level
+ self.log(log) if should_log && should_log?(log)
end
# Measure the supplied block and log the message
def measure_internal(level, index, message, params)
exception = nil
@@ -344,27 +364,64 @@
else
params[:duration] || raise('Mandatory block missing when :duration option is not supplied')
end
# Extract options after block completes so that block can modify any of the options
- payload = params[:payload]
+ payload = params[:payload]
+ # May return false due to elastic logging
should_log = log.assign(
message: message,
payload: payload,
min_duration: params[:min_duration] || 0.0,
exception: exception,
metric: params[:metric],
- metric_amount: 1,
+ metric_amount: params[:metric_amount],
duration: duration,
- backtrace: nil,
log_exception: params[:log_exception] || :partial,
on_exception_level: params[:on_exception_level]
)
- self.log(log) if should_log && include_message?(log)
+ # Log level may change during assign due to :on_exception_level
+ self.log(log) if should_log && should_log?(log)
raise exception if exception
result
+ end
+ end
+
+ # For measuring methods and logging their duration.
+ def measure_method(index:,
+ level:,
+ message:,
+ min_duration:,
+ metric:,
+ log_exception:,
+ on_exception_level:,
+ &block)
+
+ # Ignores filter, silence, payload
+ exception = nil
+ start = Time.now
+ begin
+ yield
+ rescue Exception => exc
+ exception = exc
+ ensure
+ log = Log.new(name, level, index)
+ # May return false due to elastic logging
+ should_log = log.assign(
+ message: message,
+ min_duration: min_duration,
+ exception: exception,
+ metric: metric,
+ duration: 1000.0 * (Time.now - start),
+ log_exception: log_exception,
+ on_exception_level: on_exception_level
+ )
+
+ # Log level may change during assign due to :on_exception_level
+ log(log) if should_log && should_log?(log)
+ raise exception if exception
end
end
end
end