module Pliny::Log

Public Instance Methods

context(data, &block) click to toggle source
# File lib/pliny/log.rb, line 42
def context(data, &block)
  old = local_context
  self.local_context = old.merge(data)
  res = block.call
ensure
  self.local_context = old
  res
end
default_context() click to toggle source
# File lib/pliny/log.rb, line 55
def default_context
  @default_context || {}
end
default_context=(default_context) click to toggle source
# File lib/pliny/log.rb, line 51
def default_context=(default_context)
  @default_context = default_context
end
log(data, &block) click to toggle source
# File lib/pliny/log.rb, line 3
def log(data, &block)
  log_to_stream(stdout || $stdout, merge_log_contexts(data), &block)
end
log_exception(e, data = {}) click to toggle source
# File lib/pliny/log.rb, line 15
def log_exception(e, data = {})
  exception_id = e.object_id

  # Log backtrace in reverse order for easier digestion.
  if e.backtrace
    e.backtrace.reverse.each do |backtrace|
      log_to_stream(stderr || $stderr, merge_log_contexts(
        exception_id: exception_id,
        backtrace:    backtrace
      ))
    end
  end

  # then log the exception message last so that it's as close to the end of
  # a log trace as possible
  data.merge!(
    exception:    true,
    class:        e.class.name,
    message:      e.message,
    exception_id: exception_id
  )

  data[:status] = e.status if e.respond_to?(:status)

  log_to_stream(stderr || $stderr, merge_log_contexts(data))
end
log_scrubber() click to toggle source
# File lib/pliny/log.rb, line 82
def log_scrubber
  @scrubber
end
log_scrubber=(scrubber) click to toggle source
# File lib/pliny/log.rb, line 75
def log_scrubber=(scrubber)
  if scrubber && !scrubber.respond_to?(:call)
    raise(ArgumentError, "Must respond to 'call'")
  end
  @scrubber = scrubber
end
log_with_default_context(data, &block) click to toggle source
# File lib/pliny/log.rb, line 7
def log_with_default_context(data, &block)
  log_to_stream(stdout || $stdout, default_context.merge(data), &block)
end
log_without_context(data, &block) click to toggle source
# File lib/pliny/log.rb, line 11
def log_without_context(data, &block)
  log_to_stream(stdout || $stdout, data, &block)
end
stderr() click to toggle source
# File lib/pliny/log.rb, line 71
def stderr
  @stderr
end
stderr=(stream) click to toggle source
# File lib/pliny/log.rb, line 67
def stderr=(stream)
  @stderr = stream
end
stdout() click to toggle source
# File lib/pliny/log.rb, line 63
def stdout
  @stdout
end
stdout=(stream) click to toggle source
# File lib/pliny/log.rb, line 59
def stdout=(stream)
  @stdout = stream
end

Private Instance Methods

local_context() click to toggle source
# File lib/pliny/log.rb, line 92
def local_context
  RequestStore.store[:local_context] ||= {}
end
local_context=(h) click to toggle source
# File lib/pliny/log.rb, line 96
def local_context=(h)
  RequestStore.store[:local_context] = h
end
log_context() click to toggle source
# File lib/pliny/log.rb, line 100
def log_context
  RequestStore.store[:log_context] || {}
end
log_to_stream(stream, data) { || ... } click to toggle source
# File lib/pliny/log.rb, line 104
def log_to_stream(stream, data, &block)
  unless block
    data = log_scrubber.call(data) if log_scrubber
    str = unparse(data)
    stream.print(str + "\n")
  else
    data = data.dup
    start = Time.now
    log_to_stream(stream, data.merge(at: "start"))
    begin
      res = yield
      log_to_stream(stream, data.merge(
        at: "finish", elapsed: (Time.now - start).to_f))
      res
    rescue
      log_to_stream(stream, data.merge(
        at: "exception", elapsed: (Time.now - start).to_f))
      raise $!
    end
  end
end
merge_log_contexts(data) click to toggle source
# File lib/pliny/log.rb, line 88
def merge_log_contexts(data)
  default_context.merge(log_context.merge(local_context.merge(data)))
end
quote_string(v) click to toggle source
# File lib/pliny/log.rb, line 130
def quote_string(v)
  if !v.include?('"')
    %{"#{v}"}
  elsif !v.include?("'")
    %{'#{v}'}
  else
    %{"#{v.gsub(/"/, '\\"')}"}
  end
end
replace_newlines(v) click to toggle source
# File lib/pliny/log.rb, line 126
def replace_newlines(v)
  v.gsub("\n", "\\n")
end
unparse(attrs) click to toggle source
# File lib/pliny/log.rb, line 140
def unparse(attrs)
  attrs.map { |k, v| unparse_pair(k, v) }.compact.join(" ")
end
unparse_pair(k, v) click to toggle source
# File lib/pliny/log.rb, line 144
def unparse_pair(k, v)
  v = v.call if v.is_a?(Proc)

  if v == nil
    nil
  elsif v == true
    k
  elsif v.is_a?(Float)
    "#{k}=#{format("%.3f", v)}"
  elsif v.is_a?(Time)
    "#{k}=#{v.iso8601}"
  else
    v = "#{v}"
    v = replace_newlines(v)
    v = quote_string(v) if v =~ /\s/

    "#{k}=#{v}"
  end
end