Module: UnionStationHooks
- Defined in:
- lib/union_station_hooks_core.rb,
lib/union_station_hooks_core/api.rb,
lib/union_station_hooks_core/log.rb,
lib/union_station_hooks_core/lock.rb,
lib/union_station_hooks_core/utils.rb,
lib/union_station_hooks_core/context.rb,
lib/union_station_hooks_core/version.rb,
lib/union_station_hooks_core/connection.rb,
lib/union_station_hooks_core/time_point.rb,
lib/union_station_hooks_core/simple_json.rb,
lib/union_station_hooks_core/spec_helper.rb,
lib/union_station_hooks_core/transaction.rb,
lib/union_station_hooks_core/message_channel.rb,
lib/union_station_hooks_core/request_reporter.rb,
lib/union_station_hooks_core/request_reporter/misc.rb,
lib/union_station_hooks_core/request_reporter/basics.rb,
lib/union_station_hooks_core/request_reporter/controllers.rb,
lib/union_station_hooks_core/request_reporter/view_rendering.rb
Overview
The UnionStationHooks module is the entry point to the ‘union_station_hooks_core` gem’s public API. Note that this API is only available since Passenger 5.0.20!
**_Not familiar with ‘union_station_hooks_core`? Please read the [README](github.com/phusion/union_station_hooks_core) for an introduction._**
## Places of interest
You will probably be most interested in these:
* {UnionStationHooks.initialize!}
* {UnionStationHooks.begin_rack_request} and
{UnionStationHooks.end_rack_request}
* {UnionStationHooks::RequestReporter}
* {UnionStationHooks.log_exception}
## Rack example
Here is a small example showing to use ‘union_station_hooks_core` with a bare Rack application. There are three main things you see in this example:
1. The `union_station_hooks_*` gems are initialized.
2. Obtaining a RequestReporter object, which is the main object that you
will be using as an application developer to log information to Union
Station.
3. Using the RequestReporter object by calling methods on it.
Example code follows:
# (1) Initialize all `union_station_hooks_*` gems.
UnionStationHooks.initialize!
# Define application object.
app = lambda do |env|
body, rendering_time = process_this_request(env)
# (2) You can obtain a RequestReporter object as follows. With that
# object, you can log to Union Station information about the current
# request.
reporter = env['union_station_hooks']
# -OR- (if you don't have access to the Rack env):
reporter = Thread.current[:union_station_hooks]
# The reporter object may be nil because of various error conditions,
# so you must check for it.
if reporter
# (3) For example you can log the amount of time it took to render
# the view.
reporter.log_total_view_rendering_time(rendering_time)
end
[200, { "Content-Type" => "text/plain" }, body]
end
# Tell the application server to run this application object.
run app
Defined Under Namespace
Modules: Log, SimpleJSON, SpecHelper, Utils Classes: ConfigurationError, Connection, Context, Lock, MessageChannel, RequestReporter, TimePoint, Transaction
Constant Summary collapse
- LIBROOT =
The path to the ‘union_station_hooks_core` Ruby library directory.
File.(File.dirname(__FILE__))
- ROOT =
The path to the ‘union_station_hooks_core` gem root directory.
File.dirname(LIBROOT)
- MAJOR_VERSION =
version_data[:major]
- MINOR_VERSION =
version_data[:minor]
- TINY_VERSION =
version_data[:tiny]
- VERSION_STRING =
version_data[:string]
- @@config =
{}
- @@context =
nil
- @@initializers =
[]
- @@initialized =
false
- @@app_group_name =
nil
- @@key =
nil
- @@vendored =
false
Class Method Summary collapse
- .app_group_name ⇒ Object
-
.begin_rack_request(rack_env) ⇒ RequestReporter?
Indicates that a Rack request has begun.
- .call_event_pre_hook(_event) ⇒ Object
-
.check_initialized ⇒ Object
Called by Passenger after loading the application, to check whether or not the application developer forgot to call UnionStationHooks.initialize!.
-
.config ⇒ Hash
Returns the configuration hash.
-
.context ⇒ Object
The singleton Context object, created during initialization.
-
.end_rack_request(rack_env, uncaught_exception_raised_during_request = false) ⇒ Object
Indicates that a Rack request, on which UnionStationHooks.begin_rack_request was called, has ended.
-
.get_delta_monotonic ⇒ Object
Returns a best-estimate delta (usec) between the wallclock and the monotonic clock (updated every request), such that: time_monotic_usec = time_wallclock_usec - delta.
-
.initialize! ⇒ Boolean
Initializes the Union Station hooks.
-
.initialized? ⇒ Boolean
Returns whether the Union Station hooks are initialized.
-
.initializers ⇒ Object
An array of objects on which ‘#initialize!` will be called when UnionStationHooks.initialize! is called.
-
.key ⇒ Object
The currently active Union Station key.
-
.log_exception(exception) ⇒ Object
Logs an exception that did NOT occur during a request.
-
.now ⇒ TimePoint
Returns an opaque object (a TimePoint) that represents a collection of metrics about the current time.
- .require_lib(name) ⇒ Object
-
.should_initialize? ⇒ Boolean
Returns whether the Union Station hooks should be initialized.
- .vendored=(val) ⇒ Object
-
.vendored? ⇒ Boolean
Returns whether this ‘union_station_hooks_core` gem is bundled with Passenger (as opposed to a standalone gem added to the Gemfile).
Class Method Details
.app_group_name ⇒ Object
257 258 259 |
# File 'lib/union_station_hooks_core.rb', line 257 def app_group_name @@app_group_name end |
.begin_rack_request(rack_env) ⇒ RequestReporter?
You do not have to call this! Passenger automatically calls this for you! Just obtain the RequestReporter object that has been made available for you.
Indicates that a Rack request has begun. Given a Rack environment hash, this method returns RequestReporter object, which you can use for logging Union Station information about this request. This method should be called as early as possible during a request, before any processing has begun. Only after calling this method will it be possible to log request-specific information to Union Station.
The RequestReporter object that this method creates is also made available through the ‘union_station_hooks` key in the Rack environment hash, as well as 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
If this method was already called on this Rack request, then this method does nothing and merely returns the previously created RequestReporter.
See RequestReporter to learn what kind of information you can log to Union Station about Rack requests.
61 62 63 64 65 |
# File 'lib/union_station_hooks_core/api.rb', line 61 def begin_rack_request(_rack_env) # When `initialize!` is called, the definition in # `api.rb` will override this implementation. nil end |
.call_event_pre_hook(_event) ⇒ Object
270 271 272 273 |
# File 'lib/union_station_hooks_core.rb', line 270 def call_event_pre_hook(_event) raise 'This method may only be called after ' \ 'UnionStationHooks.initialize! is called' end |
.check_initialized ⇒ Object
Called by Passenger after loading the application, to check whether or not the application developer forgot to call initialize!. If so, it logs the problem and initializes now.
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
# File 'lib/union_station_hooks_core.rb', line 281 def check_initialized return if !should_initialize? || initialized? return if !config.fetch(:check_initialized, true) if defined?(::Rails) = 'The Union Station hooks are not initialized. Please ensure ' \ 'that you have an initializer file ' \ '`config/initializers/union_station.rb` in which you call ' \ "this:\n\n" \ " if defined?(UnionStationHooks)\n" \ " UnionStationHooks.initialize!\n" \ " end" else = 'The Union Station hooks are not initialized. Please ensure ' \ 'that the following code is called during application ' \ "startup:\n\n" \ " if defined?(UnionStationHooks)\n" \ " UnionStationHooks.initialize!\n" \ " end" end STDERR.puts(" *** WARNING: #{}") @@config[:initialize_from_check] = true initialize! report_internal_information('HOOKS_NOT_INITIALIZED', ) end |
.config ⇒ Hash
Returns the configuration hash. This configuration is used by all ‘union_station_hooks_*` gems. You are supposed to set this hash before calling initialize!.
At present, none of the ‘union_station_hooks_*` gems require additional configuration. All necessary configuration is pulled from Passenger. This may change if and when Union Station in the future supports application servers besides Passenger.
This hash is supposed to only contain symbol keys, not string keys. When initialize! is called, that method will convert all string keys to symbol keys before doing anything else with the config hash, so assigning string keys works even though we don’t recommend it. Furthermore, the config hash is frozen after initialization.
233 234 235 |
# File 'lib/union_station_hooks_core.rb', line 233 def config @@config end |
.context ⇒ Object
The singleton Context object, created during initialization. All the ‘union_station_hooks_*` gem internals make use of this context object.
242 243 244 |
# File 'lib/union_station_hooks_core.rb', line 242 def context @@context end |
.end_rack_request(rack_env, uncaught_exception_raised_during_request = false) ⇒ Object
You do not have to call this! Passenger automatically calls this for you!
Indicates that a Rack request, on which begin_rack_request was called, has ended. You should call this method as late as possible during a request, after all processing have ended. Preferably after the Rack response body has closed.
The RequestReporter object associated with this Rack request and with the current, will be closed (by calling UnionStationHooks::RequestReporter#close), which finalizes the Union Station logs for this request.
This method MUST be called in the same thread that called begin_rack_request.
It is undefined what will happen if you call this method a Rack request on which begin_rack_request was not called, so don’t do that.
This method does nothing if it was already called on this Rack request.
105 106 107 108 109 110 |
# File 'lib/union_station_hooks_core/api.rb', line 105 def end_rack_request(_rack_env, _uncaught_exception_raised_during_request = false) # When `initialize!` is called, the definition in # `api.rb` will override this implementation. nil end |
.get_delta_monotonic ⇒ Object
Returns a best-estimate delta (usec) between the wallclock and the monotonic clock (updated every request), such that: time_monotic_usec = time_wallclock_usec - delta
177 178 179 180 181 |
# File 'lib/union_station_hooks_core/api.rb', line 177 def get_delta_monotonic # When `initialize!` is called, the definition in # `api.rb` will override this implementation. nil end |
.initialize! ⇒ Boolean
Initializes the Union Station hooks. If there are any other ‘union_station_hooks_*` gems loaded, then they are initialized too.
Applications must call this during startup. Hooks aren’t actually installed until this method is called, so until you call this you cannot use the public APIs of any ‘union_station_hooks_*` gems (besides trivial things such as initialized?).
A good place to call this is in the Rackup file ‘config.ru`. Or, if your application is a Rails app, then you should create an initializer file `config/initializers/union_station.rb` in which you call this.
If this method successfully initializes, then it returns true.
Calling this method may or may not actually initialize the hooks. If this gem determines that initialization is not desired, then this method won’t do anything and will return ‘false`. See should_initialize?.
Initialization takes place according to parameters set in the configuration hash. If a required configuration option is missing, then this method will raise a ConfigurationError.
Initializing twice is a no-op. It only causes this method to return true.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/union_station_hooks_core.rb', line 161 def initialize! return false if !should_initialize? return true if initialized? finalize_and_validate_config require_lib('api') create_context install_postfork_hook install_event_pre_hook initialize_other_union_station_hooks_gems finalize_install true end |
.initialized? ⇒ Boolean
Returns whether the Union Station hooks are initialized.
177 178 179 |
# File 'lib/union_station_hooks_core.rb', line 177 def initialized? @@initialized end |
.initializers ⇒ Object
An array of objects on which ‘#initialize!` will be called when initialize! is called. Other `union_station_hooks_*` gems register themselves in this list when they are loaded, so that a call to initialize! will initialize them too.
252 253 254 |
# File 'lib/union_station_hooks_core.rb', line 252 def initializers @@initializers end |
.key ⇒ Object
The currently active Union Station key. This is pulled from the configuration.
265 266 267 |
# File 'lib/union_station_hooks_core.rb', line 265 def key @@key end |
.log_exception(exception) ⇒ Object
Logs an exception that did NOT occur during a request.
This method should be used for logging exceptions outside the request-response cycle, e.g. exceptions in threads. If you want to log an exception that occurred during a request, use UnionStationHooks::RequestReporter#log_exception instead. That method will also log any related request-specific information, while this method does not.
129 130 131 132 133 |
# File 'lib/union_station_hooks_core/api.rb', line 129 def log_exception(_exception) # When `initialize!` is called, the definition in # `api.rb` will override this implementation. nil end |
.now ⇒ TimePoint
Returns an opaque object (a TimePoint) that represents a collection of metrics about the current time.
This TimePoint samples monotonic time (with a fallback to wall clock time) as well as CPU time, time spent in userspace and kernel space, time spent context switching, etc. The exact information contained in the object is operating system specific, hence the object is opaque.
You should use it for the various API methods that require timing information. Those methods also accept standard Ruby ‘Time` objects, but we strongly recommended against doing this, because wall clock time can jump forwards and backwards, which may create issues.
See UnionStationHooks::RequestReporter#log_controller_action for an example of an API method which expects timing information. ‘RequestReporter#log_controller_action` expects you to provide timing information about a controller action. That timing information is supposed to be obtained by calling `UnionStationHooks.now`.
168 169 170 171 172 |
# File 'lib/union_station_hooks_core/api.rb', line 168 def now # When `initialize!` is called, the definition in # `api.rb` will override this implementation. nil end |
.require_lib(name) ⇒ Object
212 213 214 |
# File 'lib/union_station_hooks_core.rb', line 212 def require_lib(name) require("#{LIBROOT}/union_station_hooks_core/#{name}") end |
.should_initialize? ⇒ Boolean
Returns whether the Union Station hooks should be initialized. If this method returns false, then initialize! doesn’t do anything.
At present, this method only returns true when the app is running inside Passenger. This may change if and when in the future Union Station supports application servers besides Passenger.
188 189 190 191 192 193 194 |
# File 'lib/union_station_hooks_core.rb', line 188 def should_initialize? if defined?(PhusionPassenger) PhusionPassenger::App.['analytics'] else false end end |
.vendored=(val) ⇒ Object
207 208 209 |
# File 'lib/union_station_hooks_core.rb', line 207 def vendored=(val) @@vendored = val end |
.vendored? ⇒ Boolean
Returns whether this ‘union_station_hooks_core` gem is bundled with Passenger (as opposed to a standalone gem added to the Gemfile). See the README and the file `hacking/Vendoring.md` for information about how Passenger bundles `union_station_hooks_*` gems.
202 203 204 |
# File 'lib/union_station_hooks_core.rb', line 202 def vendored? @@vendored end |