fields |
A hash containing metadata to be included in logs emitted by this instance.
|
level |
The level filter for the instance. Valid values are
:error
:fatal
:info
:warn
:debug
|
format |
The format to output logs. Supports
:text
:json
|
error
is present, attempts to obtain backtrace information and also includes it to the emitted entry.
#warn(msg, **fields)
#info(msg, **fields)
#debug(msg, **fields)
hexdump -C
.
def self.mutex
@mutex ||= Mutex.new
end
output |
an IO-like object that implements a
#write
|
format |
Optional. Indicates the format used to output log entries. Supports
:text
:json
|
level |
Level to filter this logger instance
|
fields |
Fields to include in emitted entries
|
def initialize(output, format: :text, level: :debug, **fields)
@output = output
@format = format
@fields = fields
@level = level
end
fields |
A Hash containing metadata to be included in all output entries emitted from the returned instance.
|
def with_fields(**fields)
inst = Logrb.new(@output, format: @format, level: @level)
inst.fields = @fields.merge(fields)
inst
end
def error(msg, error = nil, **fields)
return if LEVELS[@level] > LEVELS[:error]
wrap(:error, msg, error, fields)
nil
end
Kernel#exit
def fatal(msg, error = nil, **fields)
wrap(:fatal, msg, error, fields)
exit 1
end
hexdump -C
.
def dump(log, data = nil, **fields)
return if LEVELS[@level] > LEVELS[:debug]
if data.nil?
data = log
log = nil
end
data = data.pack("C*") if data.is_a? Array
dump = []
padding = @format == :json ? "" : " "
Hexdump.dump(data, output: dump)
dump.map! { |line| "#{padding}#{line.chomp}" }
dump = dump.join("\n")
if @format == :json
fields[:dump] = dump
dump = nil
end
wrap(:dump, log || "", nil, fields)
write_output("#{dump}\n\n") unless dump.nil?
end
def color(color, text)
bg = BACKGROUNDS[color]
reset_bg = ""
if bg
bg = "\e[#{bg}m"
reset_bg = "\e[49m"
end
"#{bg}\e[#{COLORS[color]}m#{text}\e[#{COLORS[:reset]}m#{reset_bg}"
end
def clean_caller_locations
caller_locations.reject { |t| t.absolute_path&.end_with?("logrb.rb") }
end
def determine_caller
c = clean_caller_locations.first
[normalize_location(c), c.base_label]
end
trace |
Trace to be clean.
|
include_function_name |
Optional. When true, includes the function name on the normalized string. Defaults to false.
|
def normalize_location(trace, include_function_name: false)
path = trace.absolute_path
return trace.to_s if path.nil?
if (root = Gem.path.find { |p| path.start_with?(p) })
path = "$GEM_PATH#{path[root.length..]}"
end
"#{path}:#{trace.lineno}#{include_function_name ? " in `#{trace.label}'" : ""}"
end
def stack_trace(trace = clean_caller_locations)
trace.map { |s| normalize_location(s, include_function_name: true) }.join("\n")
end
level |
The severity of the log message
|
caller_meta |
An Array containing the caller's location and name
|
msg |
The message to be logged
|
fields |
A Hash of fields to be included in the entry
|
def compose_line(level, caller_meta, msg, fields)
ts = Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%z")
msg = " #{msg}" unless msg.empty?
fields_str = if fields.empty?
""
else
" #{fields}"
end
level_str = color(level, level.to_s.upcase)
"#{ts} #{level_str}: #{caller_meta.last}:#{msg}#{fields_str}"
end
level |
The severity of the message to be logged.
|
msg |
The message to be logged
|
error |
Either an Exception object or nil. This parameter is used to provide extra information on the logged entry.
|
fields |
A Hash containing metadata to be included in the logged entry.
|
caller_meta |
An Array containing the caller's location and name.
|
def text(level, msg, error, fields, caller_meta)
fields ||= {}
fields.merge! @fields
write_output(compose_line(level, caller_meta, msg, fields))
if (error_message = error&.message)
write_output(": #{error_message}")
end
write_output("\n")
return unless level == :error
backtrace_str = backtrace(error)
.split("\n")
.map { |s| " #{s}" }.join("\n")
write_output(backtrace_str)
write_output("\n")
end
def backtrace(from)
if from.respond_to?(:backtrace_locations) && !from.backtrace_locations.nil?
stack_trace(from.backtrace_locations)
else
stack_trace
end
end
def write_output(text)
Logrb.mutex.synchronize do
@output.write(text)
end
end
level |
The severity of the message to be logged.
|
msg |
The message to be logged
|
error |
Either an Exception object or nil. This parameter is used to provide extra information on the logged entry.
|
fields |
A Hash containing metadata to be included in the logged entry.
|
caller_meta |
An Array containing the caller's location and name.
|
def json(level, msg, error, fields, caller_meta)
fields ||= {}
fields.merge! @fields
data = {
level: level,
caller: caller_meta.first,
msg: msg,
ts: Time.now.utc.to_i
}
data[:stacktrace] = backtrace(error) if level == :error
data.merge!(fields)
write_output("#{data.to_json}\n")
end
def wrap(level, msg, error, fields)
msg = msg.to_s
send(@format, level, msg, error, fields, determine_caller)
exit 1 if level == :fatal
end