class TP2::Logger

def call(level, o)

Parameters:
  • o (Hash) -- hash
  • level (Symbol) -- log level
def call(level, o)
  emit(make_entry(level, o))
rescue StandardError => e
  puts 'Uncaught error while emitting log entry:'
  p e: e
  p e.backtrace
  exit
end

def emit(entry)

def emit(entry)
  @machine.write_async(@fd, "#{entry.to_json}\n")
end

def error(o)

def error(o)
  call(:ERROR, o)
end

def full_uri(headers)

def full_uri(headers)
  format(
    '%<scheme>s://%<host>s%<path>s',
    scheme: headers['x_forwarded_proto'] || 'http',
    host:   headers['host'],
    path:   headers[':path']
  )
end

def info(o)

def info(o)
  call(:INFO, o)
end

def initialize(machine, fd = $stdout.fileno, **opts)

def initialize(machine, fd = $stdout.fileno, **opts)
  @machine = machine
  @fd = fd
  @opts = opts
end

def make_entry(level, o)

def make_entry(level, o)
  if o[:request]
    make_request_entry(level, o)
  elsif o[:error]
    make_error_entry(level, o)
  else
    make_hash_entry(level, o)
  end
end

def make_error_entry(level, o)

def make_error_entry(level, o)
  err = o[:error]
  {
    level: level.to_s,
    ts: (t = Time.now; t.to_i),
    ts_s: t.iso8601
  }
  .merge(o)
  .merge(
    error: "#{err.class}: #{err.message}",
    backtrace: err.backtrace
  )
end

def make_hash_entry(level, hash)

def make_hash_entry(level, hash)
  {
    level: level.to_s,
    ts: (t = Time.now; t.to_i),
    ts_s: t.iso8601
  }
  .merge(hash)
end

def make_request_entry(level, o)

def make_request_entry(level, o)
  request = o[:request]
  request_headers = request.headers
  response_headers = o[:response_headers]
  elapsed = request.adapter.monotonic_clock - request.start_stamp
  {
    level: level.to_s,
    ts: (t = Time.now; t.to_i),
    ts_s: t.iso8601,
    message: o[:message] || 'HTTP request done',
    client_ip: request.forwarded_for || '?',
    http_method: request_headers[':method'].upcase,
    user_agent: request_headers['user-agent'],
    uri: full_uri(request_headers),
    status: response_headers[':status'] || '200',
    elapsed: elapsed
  }
end

def warn(o)

def warn(o)
  call(:WARN, o)
end