123456789_123456789_123456789_123456789_123456789_

Class: Puma::ErrorLogger

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Instance Chain:
self, Const
Inherits: Object
Defined in: lib/puma/error_logger.rb

Overview

The implementation of a detailed error logging.

Version:

  • 5.0.0

Constant Summary

Const - Included

BANNED_HEADER_KEY, CGI_VER, CHUNKED, CHUNK_SIZE, CLOSE, CLOSE_CHUNKED, CODE_NAME, COLON, CONNECTION_CLOSE, CONNECTION_KEEP_ALIVE, CONTENT_LENGTH, CONTENT_LENGTH2, CONTENT_LENGTH_S, CONTINUE, DQUOTE, EARLY_HINTS, ERROR_RESPONSE, FAST_TRACK_KA_TIMEOUT, GATEWAY_INTERFACE, HALT_COMMAND, HEAD, HIJACK, HIJACK_IO, HIJACK_P, HTTP, HTTPS, HTTPS_KEY, HTTP_10_200, HTTP_11, HTTP_11_100, HTTP_11_200, HTTP_CONNECTION, HTTP_EXPECT, HTTP_HEADER_DELIMITER, HTTP_HOST, HTTP_VERSION, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED_PROTO, HTTP_X_FORWARDED_SCHEME, HTTP_X_FORWARDED_SSL, IANA_HTTP_METHODS, ILLEGAL_HEADER_KEY_REGEX, ILLEGAL_HEADER_VALUE_REGEX, KEEP_ALIVE, LINE_END, LOCALHOST, LOCALHOST_IPV4, LOCALHOST_IPV6, MAX_BODY, MAX_HEADER, NEWLINE, PATH_INFO, PORT_443, PORT_80, PROXY_PROTOCOL_V1_REGEX, PUMA_CONFIG, PUMA_PEERCERT, PUMA_SERVER_STRING, PUMA_SOCKET, PUMA_TMP_BASE, PUMA_VERSION, QUERY_STRING, RACK_AFTER_REPLY, RACK_INPUT, RACK_URL_SCHEME, REMOTE_ADDR, REQUEST_METHOD, REQUEST_PATH, REQUEST_URI, RESTART_COMMAND, SERVER_NAME, SERVER_PORT, SERVER_PROTOCOL, SERVER_SOFTWARE, STOP_COMMAND, SUPPORTED_HTTP_METHODS, TRANSFER_ENCODING, TRANSFER_ENCODING2, TRANSFER_ENCODING_CHUNKED, UNMASKABLE_HEADERS, UNSPECIFIED_IPV4, UNSPECIFIED_IPV6, WRITE_TIMEOUT

Class Method Summary

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(ioerr) ⇒ ErrorLogger

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 18

def initialize(ioerr)
  @ioerr = ioerr

  @debug = ENV.key? 'PUMA_DEBUG'
end

Class Method Details

.stdio

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 24

def self.stdio
  new $stderr
end

Instance Attribute Details

#ioerr (readonly)

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 12

attr_reader :ioerr

Instance Method Details

#debug(options = {})

Print occurred error details only if environment variable PUMA_DEBUG is defined. options hash with additional options:

  • error is an exception object

  • req the http request

  • text (default nil) custom string to print in title and before all remaining info.

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 47

def debug(options={})
  return unless @debug

  error = options[:error]
  req = options[:req]

  string_block = []
  string_block << title(options)
  string_block << request_dump(req) if request_parsed?(req)
  string_block << error.backtrace if error

  internal_write string_block.join("\n")
end

#info(options = {})

Print occurred error details. options hash with additional options:

  • error is an exception object

  • req the http request

  • text (default nil) custom string to print in title and before all remaining info.

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 35

def info(options={})
  internal_write title(options)
end

#internal_write(str) (private)

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 98

def internal_write(str)
  LOG_QUEUE << str
  while (w_str = LOG_QUEUE.pop(true)) do
    begin
      @ioerr.is_a?(IO) and @ioerr.wait_writable(1)
      @ioerr.write "#{w_str}\n"
      @ioerr.flush unless @ioerr.sync
    rescue Errno::EPIPE, Errno::EBADF, IOError, Errno::EINVAL
    # 'Invalid argument' (Errno::EINVAL) may be raised by flush
    end
  end
rescue ThreadError
end

#request_dump(req)

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 73

def request_dump(req)
  "Headers: #{request_headers(req)}\n" \
  "Body: #{req.body}"
end

#request_headers(req)

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 89

def request_headers(req)
  headers = req.env.select { |key, _| key.start_with?('HTTP_') }
  headers.map { |key, value| [key[5..-1], value] }.to_h.inspect
end

#request_parsed?(req) ⇒ Boolean

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 94

def request_parsed?(req)
  req && req.env[REQUEST_METHOD]
end

#request_title(req)

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 78

def request_title(req)
  env = req.env

  REQUEST_FORMAT % [
    env[REQUEST_METHOD],
    env[REQUEST_PATH] || env[PATH_INFO],
    env[QUERY_STRING] || "",
    env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-"
  ]
end

#title(options = {})

[ GitHub ]

  
# File 'lib/puma/error_logger.rb', line 61

def title(options={})
  text = options[:text]
  req = options[:req]
  error = options[:error]

  string_block = ["#{Time.now}"]
  string_block << " #{text}" if text
  string_block << " (#{request_title(req)})" if request_parsed?(req)
  string_block << ": #{error.inspect}" if error
  string_block.join('')
end