Class: Appydays::Loggable::RequestLogger

Inherits:
Object
  • Object
show all
Includes:
Appydays::Loggable
Defined in:
lib/appydays/loggable/request_logger.rb

Overview

Rack middleware for request logging, to replace Rack::CommonLogger.

To get additional log fields, you can subclass this and override request_tags.

Or you can use Appydays::Loggable::RequestLogger.set_request_tags (or call it on your logger subclass) with fields that will accumulate over the request and log out in the “request_finished” message.

If you want authenticated user info, make sure you install the middleware after your auth middleware.

Params:

error_code: If an unhandled exception reaches the request logger.

or happens in the request logger, this status code will be used for easay identification.
Generally unhandled exceptions in an application should be handled further downstream,
and already be returning the right error code.

slow_request_seconds: Normally request_finished is logged at info.

Requests that take >= this many seconds are logged at warn.

reraise: Reraise unhandled errors (after logging them).

In some cases you may want this to be true, but in some it may bring down the whole process.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Appydays::Loggable

[], configure_12factor, default_level=, ensure_stderr_appender, included, set_default_level, with_log_tags

Constructor Details

#initialize(app, error_code: 599, slow_request_seconds: 10, reraise: true) ⇒ RequestLogger

Returns a new instance of RequestLogger.



33
34
35
36
37
38
# File 'lib/appydays/loggable/request_logger.rb', line 33

def initialize(app, error_code: 599, slow_request_seconds: 10, reraise: true)
  @app = app
  @error_code = error_code
  @slow_request_seconds = slow_request_seconds
  @reraise = reraise
end

Class Method Details

.request_tagsObject



125
# File 'lib/appydays/loggable/request_logger.rb', line 125

def self.request_tags = Thread.current[:appydays_request_logger_request_tags] || {}

.set_request_tags(tags) ⇒ Object

Set request tags that get logged out in the “request_finished” message. This allows you to add useful context to the request without needing a dedicated log message. See README for more info.



120
121
122
123
# File 'lib/appydays/loggable/request_logger.rb', line 120

def self.set_request_tags(tags)
  Thread.current[:appydays_request_logger_request_tags] ||= {}
  Thread.current[:appydays_request_logger_request_tags].merge!(tags)
end

Instance Method Details

#call(env) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/appydays/loggable/request_logger.rb', line 40

def call(env)
  # We need to clear request tags in log_finished, but it's possible it didn't run on the last request
  # so clear the request tags first thing.
  self.class.request_tags.clear
  began_at = Time.now
  request_id = self._ensure_request_id(env)
  # Only use the request_id as the context/correllation id for log messages,
  # otherwise we end up with a lot of log spam.
  status, header, body = SemanticLogger.named_tagged(request_id:) do
    @app.call(env)
  end
  header = Rack::Utils::HeaderHash.new(header)
  body = Rack::BodyProxy.new(body) { self.log_finished(env, began_at, status, header) }
  [status, header, body]
rescue StandardError => e
  began_at ||= nil
  self.log_finished(env, began_at, 599, {}, e)
  raise if @reraise
end

#request_tags(_env) ⇒ Object



80
81
82
# File 'lib/appydays/loggable/request_logger.rb', line 80

def request_tags(_env)
  return {}
end