class

Logrb

Defined in logrb.rb
Show More
Hide internal members
Hide private members
Hide attributes
Show inherited members
Show extended members
Show included members
Logrb provides a facility for working with logs in text and json formats. All instances share a single mutex to ensure logging consistency. The following attributes are available:

Arguments

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
, and
:debug
format
The format to output logs. Supports
:text
and
:json
.
Each instance exposes the following methods, which accepts an arbitrary number of key-value pairs to be included in the logged message:
#error(msg, error=nil, **fields)
: Outputs an error entry. When error is present, attempts to obtain backtrace information and also includes it to the emitted entry.
#fatal(msg, **fields)
: Outputs a fatal entry. Calling fatal causes the current process to exit with a status 1.
#warn(msg, **fields)
: Outputs a warning entry.
#info(msg, **fields)
: Outputs a informational entry.
#debug(msg, **fields)
: Outputs a debug entry.
#dump(msg, data=nil)
: Outputs a given String or Array of bytes using the same format as hexdump -C.
Attributes
fieldsread/write
(No documentation available)
levelread/write
(No documentation available)
formatread/write
(No documentation available)
Class Methods
mutexinternal
A mutex instance used for synchronizing the usage of the output IO.
Show Source
  def self.mutex
    @mutex ||= Mutex.new
  end
Instance Methods
backtracefromprivate
Attempts to obtain a backtrace from a provided object. In case the object does not include backtrace metadata, uses
#stack_trace
as a fallback.
Show Source
  def backtrace(from)
    if from.respond_to?(:backtrace_locations) && !from.backtrace_locations.nil?
      stack_trace(from.backtrace_locations)
    else
      stack_trace
    end
  end
clean_caller_locationsprivate
Removes all backtrace frames pointing to the logging facility itself.
Show Source
  def clean_caller_locations
    caller_locations.reject { |t| t.absolute_path&.end_with?("logrb.rb") }
  end
colorcolortextprivate
Formats a given text using the ANSI escape sequences. Notice that this method does not attempt to determine whether the current output supports escape sequences.
Show Source
  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
compose_linelevelcaller_metamsgfieldsprivate
Composes a log line with given information.

Arguments

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
Show Source
  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
determine_callerprivate
Returns the caller of a function, returning a pair containing its path and base method name.
Show Source
  def determine_caller
    c = clean_caller_locations.first
    [normalize_location(c), c.base_label]
  end
dumplogdatanilfields
Dumps a given String or Array in the same format as hexdump -C.
Show Source
  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
errormsgerrornilfields
Emits an error to the log output. When error is provided, this method attempts to gather a stacktrace to include in the emitted entry.
Show Source
  def error(msg, error = nil, **fields)
    return if LEVELS[@level] > LEVELS[:error]

    wrap(:error, msg, error, fields)
    nil
  end
fatalmsgerrornilfields
Emits a fatal message to the log output, and invokes
Kernel#exit
with a non-zero status code. When error is provided, this method attempts to gather a stacktrace to include in the emitted entry. This log entry cannot be filtered, and is always emitted.
Show Source
  def fatal(msg, error = nil, **fields)
    wrap(:fatal, msg, error, fields)
    exit 1
  end
initializeoutputformattrueleveltruefields
Initializes a new Logger instance that outputs logs to a provided output.

Arguments

output
an IO-like object that implements a
#write
method.
format
Optional. Indicates the format used to output log entries. Supports
:text
(default) and
:json
.
level
Level to filter this logger instance
fields
Fields to include in emitted entries
Show Source
  def initialize(output, format: :text, level: :debug, **fields)
    @output = output
    @format = format
    @fields = fields
    @level = level
  end
jsonlevelmsgerrorfieldscaller_metaprivate
Logs a JSON entry to the current output.

Arguments

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.
Show Source
  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
normalize_locationtraceinclude_function_namefalseprivate
Performs a cleanup for a given backtrace frame.

Arguments

trace
Trace to be clean.
include_function_name
Optional. When true, includes the function name on the normalized string. Defaults to false.
Show Source
  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
stack_tracetraceclean_caller_locationsprivate
Returns a string containing a stacktrace of the current invocation.
Show Source
  def stack_trace(trace = clean_caller_locations)
    trace.map { |s| normalize_location(s, include_function_name: true) }.join("\n")
  end
textlevelmsgerrorfieldscaller_metaprivate
Logs a text entry to the current output.

Arguments

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.
Show Source
  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
with_fieldsfields
Returns a new logger instance using the same output of its parent's, with an optional set of fields to be merged against the parent's fields.

Arguments

fields
A Hash containing metadata to be included in all output entries emitted from the returned instance.
Show Source
  def with_fields(**fields)
    inst = Logrb.new(@output, format: @format, level: @level)
    inst.fields = @fields.merge(fields)
    inst
  end
wraplevelmsgerrorfieldsprivate
Dynamically invokes the current log formatter for the provided arguments. For further information, see
#text
and
#json
Show Source
  def wrap(level, msg, error, fields)
    msg = msg.to_s
    send(@format, level, msg, error, fields, determine_caller)
    exit 1 if level == :fatal
  end
write_outputtextprivate
Writes a given value to the current's output IO. Calls to this method are thread-safe.
Show Source
  def write_output(text)
    Logrb.mutex.synchronize do
      @output.write(text)
    end
  end