Class UnionStationHooks::RequestReporter
In: src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb
src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/controllers.rb
src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/view_rendering.rb
src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/misc.rb
src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter/basics.rb
Parent: Object

A RequestReporter object is used for logging request-specific information to Union Station. "Information" may include (and are not limited to):

 * Web framework controller and action name.
 * Exceptions raised during the request.
 * Cache hits and misses.
 * Database actions.

A unique RequestReporter is created by Passenger at the beginning of every request (by calling {UnionStationHooks.begin_rack_request}). This object is closed at the end of the same request (after the Rack body object is closed).

As an application developer, the RequestReporter is the main class that you will be interfacing with. See the {UnionStationHooks} module description for an example of how you can use RequestReporter.

## Obtaining a RequestReporter

You are not supposed to create a RequestReporter object directly. You are supposed to obtain the RequestReporter object that Passenger creates for you. This is done through the `union_station_hooks` key in the Rack environment hash, as well as through the `:union_station_hooks` key in the current thread‘s object:

    env['union_station_hooks']
    # => RequestReporter object or nil

    Thread.current[:union_station_hooks]
    # => RequestReporter object or nil

Note that Passenger may not have created such an object because of an error. At present, there are two error conditions that would cause a RequestReporter object not to be created. However, your code should take into account that in the future more error conditions may trigger this.

 1. There is no transaction ID associated with the current request.
    When Union Station support is enabled in Passenger, Passenger always
    assigns a transaction ID. However, administrators can also
    {https://www.phusionpassenger.com/library/admin/nginx/request_individual_processes.html
    access Ruby processes directly} through process-private HTTP sockets,
    bypassing Passenger's load balancing mechanism. In that case, no
    transaction ID will be assigned.
 2. An error occurred recently while sending data to the UstRouter, either
    because the UstRouter crashed or because of some other kind of
    communication error occurred. This error condition isn't cleared until
    certain a timeout has passed.

    The UstRouter is a Passenger process which runs locally and is
    responsible for aggregating Union Station log data from multiple
    processes, with the goal of sending the aggregate data over the network
    to the Union Station service.

    This kind of error is automatically recovered from after a certain
    period of time.

## Null mode

The error condition 2 described above may also cause an existing RequestReporter object to enter the "null mode". When this mode is entered, any further actions on the RequestReporter object will become no-ops. You can check whether the null mode is active by calling {null?}.

Closing a RequestReporter also causes it to enter the null mode.

## Thread-safety

RequestReporter is not thread-safe. If you access it concurrently, be sure to wrap its operations in a mutex.

Methods

Constants

GC_MUTEX = Mutex.new   A mutex for synchronizing GC stats reporting. We do this because in multithreaded situations we don‘t want to interleave GC stats access with calls to `GC.clear_stats`. Not that GC stats are very helpful in multithreaded situations, but this is better than nothing.

@private

OBJECT_SPACE_SUPPORTS_LIVE_OBJECTS = ObjectSpace.respond_to?(:live_objects)   @private
OBJECT_SPACE_SUPPORTS_ALLOCATED_OBJECTS = ObjectSpace.respond_to?(:allocated_objects)   @private
OBJECT_SPACE_SUPPORTS_COUNT_OBJECTS = ObjectSpace.respond_to?(:count_objects)   @private
GC_SUPPORTS_TIME = GC.respond_to?(:time)   @private
GC_SUPPORTS_CLEAR_STATS = GC.respond_to?(:clear_stats)   @private

Public Class methods

Returns a new RequestReporter object. You should not call `RequestReporter.new` directly. See "Obtaining a RequestReporter" in the {RequestReporter class description}.

@api private

Public Instance methods

Indicates that no further information will be logged for this request.

@api private

Returns whether {log_controller_action_block} or {log_controller_action} has been called during this request.

@return [Boolean]

Logs a benchmarking activity, for display in the activity timeline.

An activity is a block in the activity timeline in the Union Station user interace. It has a name, a begin time and an end time.

The primary use case of this method is to integrate with Rails‘s benchmarking API (`ActiveSupport::Benchmarkable`). The Rails benchmarking API allows you to run a block and to log how long that block has taken. But you can also use it to integrate with the Ruby standard library‘s `Benchmark` class.

You can wrap a benchmark call in a `UnionStationHooks.log_benchmark_block` call, so that an entry for it is displayed in the acitivity timeline. This method measures the time before and after the block runs.

The difference between this method and {log_user_activity_block} is that this method generates timeline blocks of a different color, as to differentiate user-defined activities from benchmark activities.

If your app is a Rails app, then the `union_station_hooks_rails` gem automatically calls this for you every time `ActiveSupport::Benchmarkable#benchmark` is called. This includes `benchmark` calls from controllers and from views.

@param title A title for this benchmark. It can be any arbitrary name but

  may not contain newlines.

@return The return value of the block. @yield The block is expected to perform the benchmarking activity. @example Rails example

  # This example shows what to put inside a Rails controller action
  # method. Note that the `log_benchmark_block` call is automatically done
  # for you if you use the union_station_hooks_rails gem.
  UnionStationHooks.log_benchmark_block('Process data files') do
    benchmark('Process data files') do
      expensive_files_operation
    end
  end

Logs that something was successfully retrieved from a cache. This can be any cache, be it an in-memory Hash, Redis, Memcached, a flat file or whatever.

There is just one exception. You should not use this method to log cache hits in the ActiveRecord SQL cache or similar mechanisms. Database-related timing should be logged with {log_database_query}.

If your app is a Rails app, then the `union_station_hooks_rails` gem automatically calls this for you every time an `ActiveSupport::Cache` `fetch` or `read` call success. This includes calls to `Rails.cache.fetch` or `Rails.cache.read`, because `Rails.cache` is an instance of `ActiveSupport::Cache`.

@param [String] name A unique name for this cache hit event. The cache

  key is a good value to use.

@note At present (30 September 2015), logged cache hit/miss information

  isn't shown in the Union Station interface. We may implement this
  feature in the near future.

Logs the failure to retrieve something from a cache. This can be any cache, be it an in-memory Hash, Redis, Memcached, a flat file or whatever.

There is just one exception. You should not use this method to log cache misses in the ActiveRecord SQL cache or similar mechanisms. Database-related timing should be logged with {log_database_query}.

If your app is a Rails app, then the `union_station_hooks_rails` gem automatically calls this for you every time an `ActiveSupport::Cache` `fetch` or `read` call success. This includes calls to `Rails.cache.fetch` or `Rails.cache.read`, because `Rails.cache` is an instance of `ActiveSupport::Cache`.

@param [String] name A unique name for this cache miss event. The cache

  key is a good value to use.

@param [Numeric] miss_cost_duration The amount of time that was spent in

  calculating or processing something, as a result of this cache miss.
  This time is in **microseconds**.

@note At present (30 September 2015), logged cache hit/miss information

  isn't shown in the Union Station interface. We may implement this
  feature in the near future.

Logs that the application server is about to call `close` on the Rack body object.

This call must be followed by a call to {log_closing_rack_body_end} some time later.

This is automatically called by Passenger‘s Rack handler.

@private @return An ID to be passed later to {log_closing_rack_body_end}, or nil

  on error.

Logs that the application server is done calling `close` on the Rack body object.

This is automatically called by Passenger‘s Rack handler.

@private

Logs that you are calling a web framework controller action. Of course, you should only call this if your web framework has the concept of controller actions. For example Rails does, but Sinatra and Grape don‘t.

You can pass additional information about the web framework controller action, which will be logged.

Unlike {log_controller_action_block}, this form does not expect a block. However, you are expected to pass timing information to the options hash.

The `union_station_hooks_rails` gem automatically calls {log_controller_action_block} for you if your application is a Rails app.

@param [Hash] options Information about the controller action. @option options [String] :controller_name (optional)

  The controller's name, e.g. `PostsController`.

@option options [String] :action_name (optional if :controller_name

  isn't set) The controller action's name, e.g. `create`.

@option options [String] :method (optional)

  The HTTP method that the web framework thinks this request should have,
  e.g. `GET` and `PUT`. The main use case for this option is to support
  Rails's HTTP verb emulation. Rails uses a parameter named
  [`_method`](http://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-patch-put-or-delete-methods-work-questionmark)
  to emulate HTTP verbs besides GET and POST. Other web frameworks may
  have a similar mechanism.

@option options [TimePoint or Time] :begin_time The time at which the

  controller action begun. See {UnionStationHooks.now} to learn more.

@option options [TimePoint or Time] :end_time The time at which the

  controller action ended. See {UnionStationHooks.now} to learn more.

@option options [Boolean] :has_error (optional) Whether an uncaught

  exception occurred during the request. Default: false.

@example

  # This example shows what to put inside a Rails controller action
  # method. Note that all of this is automatically done for you if you
  # use the union_station_hooks_rails gem.
  options = {
    :controller_name => self.class.name,
    :action_name => action_name,
    :method => request.request_method,
    :begin_time => UnionStationHooks.now
  }
  begin
    do_some_request_processing_here
  rescue Exception
    options[:has_error] = true
    raise
  ensure
    options[:end_time] = UnionStationHooks.now
    reporter.log_controller_action(options)
  end

Logs that you are calling a web framework controller action. Of course, you should only call this if your web framework has the concept of controller actions. For example Rails does, but Sinatra and Grape don‘t.

This form takes an options hash as well as a block. You can pass additional information about the web framework controller action, which will be logged. The block is expected to perform the actual request handling. When the block returns, timing information about the block is automatically logged.

See also {log_controller_action} for a form that doesn‘t expect a block.

The `union_station_hooks_rails` gem automatically calls this for you if your application is a Rails app.

@yield The given block is expected to perform request handling. @param [Hash] options Information about the controller action.

  All options are optional.

@option options [String] :controller_name

  The controller's name, e.g. `PostsController`.

@option options [String] :action_name

  The controller action's name, e.g. `create`.

@option options [String] :method

  The HTTP method that the web framework thinks this request should have,
  e.g. `GET` and `PUT`. The main use case for this option is to support
  Rails's HTTP verb emulation. Rails uses a parameter named
  [`_method`](http://guides.rubyonrails.org/form_helpers.html#how-do-forms-with-patch-put-or-delete-methods-work-questionmark)
  to emulate HTTP verbs besides GET and POST. Other web frameworks may
  have a similar mechanism.

@return The return value of the block.

@example Rails example

  # This example shows what to put inside a Rails controller action
  # method. Note that all of this is automatically done for you if you
  # use the union_station_hooks_rails gem.
  options = {
    :controller_name => self.class.name,
    :action_name => action_name,
    :method => request.request_method
  }
  reporter.log_controller_action_block(options) do
    do_some_request_processing_here
  end

Logs a database query that was performed during the request.

@option options [String] :name (optional) A name for this database

  query activity. Default: "SQL"

@option options [TimePoint or Time] :begin_time The time at which this

  database query begun. See {UnionStationHooks.now} to learn more.

@option options [TimePoint or Time] :end_time The time at which this

  database query ended. See {UnionStationHooks.now} to learn more.

@option options [String] :query The database query string.

Logs an exception that occurred during a request.

If you want to use an exception that occurred outside the request/response cycle, e.g. an exception that occurred in a thread, use {UnionStationHooks.log_exception} instead.

If {log_controller_action_block} or {log_controller_action} was called during the same request, then the information passed to those methods will be included in the exception report.

@param [Exception] exception

Logs the beginning of a Rack request. This is automatically called from {UnionStationHooks.begin_rack_request} (and thus automatically from Passenger).

@private

Logs the end of a Rack request. This means that the Rack response body has been written out, and that the `close` has been called on the Rack response body.

This does not necessarily indicate that any buffering mechanism in between the app and the client (e.g. Nginx, or the Passenger core) is done flushing the response to the client.

This is automatically called from {UnionStationHooks.begin_rack_request} (and thus automatically from Passenger).

@private

Logs a user-defined activity, for display in the activity timeline.

An activity is a block in the activity timeline in the Union Station user interace. It has a name, a begin time and an end time.

Unlike {log_user_activity_block}, this form does not expect a block. However, you are expected to pass timing information.

@param name The name that should show up in the activity timeline.

  It can be any arbitrary name but may not contain newlines.

@param [TimePoint or Time] begin_time The time at which this activity

  begun. See {UnionStationHooks.now} to learn more.

@param [TimePoint or Time] end_time The time at which this activity

  ended. See {UnionStationHooks.now} to learn more.

@param [Boolean] has_error Whether an uncaught

  exception occurred during the activity.

Logs the begin of a user-defined activity, for display in the activity timeline.

An activity is a block in the activity timeline in the Union Station user interace. It has a name, a begin time and an end time.

This form logs only the name and the begin time. You must also call {log_user_activity_end} later with the same name to log the end time.

@param name The name that should show up in the activity timeline.

  It can be any arbitrary name but may not contain newlines.

@return id An ID which you must pass to {log_user_activity_end} later.

Logs a user-defined activity, for display in the activity timeline.

An activity is a block in the activity timeline in the Union Station user interace. It has a name, a begin time and an end time.

This form takes a block. Before and after the block runs, the time is measured.

@param name The name that should show up in the activity timeline.

  It can be any arbitrary name but may not contain newlines.

@return The return value of the block. @yield The block is expected to perform the activity. @example

  reporter.log_user_activity_block('Preheat cache') do
    calculate_preheat_values.each_pair do |key, value|
      Rails.cache.write(key, value)
    end
  end

Logs the end of a user-defined activity, for display in the activity timeline.

An activity is a block in the activity timeline in the Union Station user interace. It has a name, a begin time and an end time.

This form logs only the name and the end time. You must also have called {log_user_activity_begin} earlier with the same name to log the begin time.

@param id The ID which you obtained from {log_user_activity_begin}

  earlier.

@param [Boolean] has_error Whether an uncaught

  exception occurred during the activity.

Logs timing information about the rendering of a single view, template or partial.

Unlike {log_view_rendering_block}, this form does not expect a block. However, you are expected to pass timing information to the options hash.

The `union_station_hooks_rails` gem automatically calls {log_view_rendering_block} for you if your application is a Rails app. It will call this on every view or partial rendering.

@option options [String] :name Name of the view, template or partial

  that is being rendered.

@option options [TimePoint or Time] :begin_time The time at which this

  view rendering begun. See {UnionStationHooks.now} to learn more.

@option options [TimePoint or Time] :end_time The time at which this view

  rendering ended. See {UnionStationHooks.now} to learn more.

@option options [Boolean] :has_error (optional) Whether an uncaught

  exception occurred during the view rendering. Default: false.

Logs timing information about the rendering of a single view, template or partial. This form expects a block, which is to perform the view/template/partial rendering. Timing information is collected before and after the block returns.

The `union_station_hooks_rails` gem automatically calls this for you if your application is a Rails app. It will call this on every view or partial rendering.

@param [String] name Name of the view, template or partial that is being

  rendered.

@yield The given block is expected to perform the actual view rendering. @return The return value of the block.

Logs that the application server is about to write out the Rack response body.

This call must be followed by a call to {log_writing_rack_body_end} some time later.

This is automatically called by Passenger‘s Rack handler.

@private @return An ID to be passed later to {log_writing_rack_body_end}, or nil

  on error.

Logs that the application server is done writing out the Rack response body. This does not necessarily indicate that any buffering mechanism in between the app and the client (e.g. Nginx, or the Passenger core) is done flushing the response to the client.

This is automatically called by Passenger‘s Rack handler.

@private

Returns whether is this RequestReporter object is in null mode. See the {RequestReporter class description} for more information.

[Validate]