lib/semantic_logger/log.rb in semantic_logger-2.21.0 vs lib/semantic_logger/log.rb in semantic_logger-3.0.0
- old
+ new
@@ -62,10 +62,23 @@
ex.original_exception
end
end
end
+ # Returns [String] the exception backtrace including all of the child / caused by exceptions
+ def backtrace_to_s
+ trace = ''
+ each_exception do |exception, i|
+ if i == 0
+ trace = (exception.backtrace || []).join("\n")
+ else
+ trace << "\nCause: #{exception.class.name}: #{exception.message}\n#{(exception.backtrace || []).join("\n")}"
+ end
+ end
+ trace
+ end
+
# Returns [String] duration of the log entry as a string
# Returns nil if their is no duration
# Java time precision does not include microseconds
if defined? JRuby
def duration_to_s
@@ -87,11 +100,11 @@
elsif seconds >= 3600.0 # 1 hour
Time.at(seconds).strftime('%-Hh %-Mm')
elsif seconds >= 60.0 # 1 minute
Time.at(seconds).strftime('%-Mm %-Ss')
elsif seconds >= 1.0 # 1 second
- Time.at(seconds).strftime('%-Ss %Lms')
+ "#{'%.3f' % seconds}s"
else
duration_to_s
end
end
@@ -102,22 +115,30 @@
# Returns [String] the available process info
# Example:
# 18934:thread 23 test_logging.rb:51
def process_info(thread_name_length = 30)
- file, line = file_name_and_line
+ file, line = file_name_and_line(true)
file_name = " #{file}:#{line}" if file
"#{$$}:#{"%.#{thread_name_length}s" % thread_name}#{file_name}"
end
+ CALLER_REGEXP = /^(.*):(\d+).*/
+
+ # Extract the filename and line number from the last entry in the supplied backtrace
+ def extract_file_and_line(stack, short_name = false)
+ match = CALLER_REGEXP.match(stack.first)
+ [short_name ? File.basename(match[1]) : match[1], match[2].to_i]
+ end
+
# Returns [String, String] the file_name and line_number from the backtrace supplied
# in either the backtrace or exception
- def file_name_and_line
+ def file_name_and_line(short_name = false)
if backtrace || (exception && exception.backtrace)
- stacktrace = backtrace || exception.backtrace
- stacktrace[0].split('/').last.split(':')[0..1] if stacktrace && stacktrace.size > 0
+ stack = backtrace || exception.backtrace
+ extract_file_and_line(stack, short_name) if stack && stack.size > 0
end
end
# Strip the standard Rails colorizing from the logged message
def cleansed_message
@@ -144,9 +165,68 @@
# Return the Time as a formatted string
# Ruby MRI supports micro seconds
def formatted_time
"#{time.strftime('%Y-%m-%d %H:%M:%S')}.#{'%06d' % (time.usec)}"
end
+ end
+
+ # Returns [Hash] representation of this log entry
+ def to_h
+ # Header
+ h = {
+ host: SemanticLogger.host,
+ application: SemanticLogger.application,
+ name: name,
+ pid: $$,
+ thread: thread_name,
+ time: time,
+ level: level,
+ level_index: level_index,
+ }
+ file, line = file_name_and_line
+ if file
+ h[:file] = file
+ h[:line] = line.to_i
+ end
+
+ # Tags
+ h[:tags] = tags if tags && (tags.size > 0)
+
+ # Duration
+ if duration
+ h[:duration_ms] = duration
+ h[:duration] = duration_human
+ end
+
+ # Log message
+ h[:message] = cleansed_message if message
+
+ # Payload
+ if payload
+ if payload.is_a?(Hash)
+ h.merge!(payload)
+ else
+ h[:payload] = payload
+ end
+ end
+
+ # Exceptions
+ if exception
+ root = h
+ each_exception do |exception, i|
+ name = i == 0 ? :exception : :cause
+ root[name] = {
+ name: exception.class.name,
+ message: exception.message,
+ stack_trace: exception.backtrace
+ }
+ root = root[name]
+ end
+ end
+
+ # Metric
+ h[:metric] = metric if metric
+ h
end
end
end