Table of contents

Loading...

Basic usage and installation

Registering a web app and setting it up to send data to Union Station

Every web app that wish you to track with Union Station must be registered.

Click on the '+' button on the lower left corner of the screen. You will be asked a name for this web app. This name doesn't have to correspond to your web app's actual name - it's just an identifier for Union Station and can be changed later. When you're done, click OK.

After the web app is registered, you must set it up to send data to Union Station, otherwise nothing will be displayed in Union Station. Please follow the installation instructions that are shown after registering a web app.

Adding a node (server)

You don't need to manually add a node in Union Station. Whenever your web app sends its data to Union Station, it will include its node host name. Union Station automatically registers the node if it hasn't already been registered.

Nodes are identified through its machine host name so you must make sure that each node in your web app's cluster has a unique host name! You can see the host name by running the hostname command on the terminal.

My node doesn't show up!

Phusion Passenger buffers Union Station data in memory for at most 1 minute before sending it to Union Station. Please wait a little if 1 minute hasn't passed yet.

If 1 minute has passed and your node still doesn't show up, then these are the most common reasons why that happens:

  1. Your firewall is preventing your web app from sending data to Union Station. Please make sure that it allows outbound connections to gateway.unionstationapp.com port 443.
  2. Your node has the same host name as another node in your cluster. This prevents Union Station from uniquely identifying that node. Please give it a unique host name.
  3. There were issues in Phusion Passenger in combination with older Curl versions. Affected systems include RHEL 5 and derived systems like CentOS 5. These issues have been fixed as of March 4, 2011 and the fixes will be included in Phusion Passenger 3.0.5. Please upgrade.
  4. File permission problems. Phusion Passenger sends data to Union Station through HTTPS. It verifies the connection using the certificate file resources/union_station_gateway.crt in its source or gem directory. This file must be readable by the process named PassengerLoggingAgent, which is typically running as the user nobody. Please ensure that the file permissions allow this.

    Please also note that on Unix, the readability of a file depends not only on the permissions of the file itself, but also on the permissions of all parent directories. For example suppose that Phusion Passenger is installed to /home/deploy/.rvm/gems/ruby-1.8.7-p334/gems/passenger-3.0.4 and that PassengerLoggingAgent is running as nobody. Just ensuring that /home/deploy/.rvm/gems/ruby-1.8.7-p334/gems/passenger-3.0.4/resources/union_station_gateway.crt is world-readable is not enough. All the parent directories must be executable by nobody:

    • /home/deploy/.rvm/gems/ruby-1.8.7-p334/gems/passenger-3.0.4/resources must be executable by nobody.
    • /home/deploy/.rvm/gems/ruby-1.8.7-p334/gems/passenger-3.0.4 must be executable by nobody.
    • /home/deploy/.rvm/gems/ruby-1.8.7-p334/gems must be executable by nobody.
    • ...etc...
    • /home/deploy must be executable by nobody.
    • /home must be executable by nobody.

If it still doesn't work after trying these, then you can find more about the error by setting PassengerLogLevel (Apache) or passenger_log_level (Nginx) to 2. Any problems related to contacting Union Station will be printed to the web server error log file.

My node does show up, but not my data!

Your system clock or your time zone might not be set correctly, causing the data to be indexed at different times than you would expect. Please use the history navigation controls in Union Station to look for your data and please fix your clock.

Filtering request data sent to Union Station

By default Phusion Passenger logs every dynamic request and sends it to Union Station. Everything; not just slow requests. However sometimes there may be some requests you don't want to log, e.g. because you are only interested in slow requests or only interested in requests to a certain controller.

Phusion Passenger >= 3.0.5 allows client-side filtering of data. One writes filters in the Union Station filter language and specifies them in the web server config file. The result of a filter is either true (allow the given data to be sent to Union Station) or false (don't allow the given data to be sent). After logging a request, Phusion Passenger runs all defined filters to determine whether to send the request's data to Union Station.

Filters are defined with the UnionStationFilter directive (Apache) or the union_station_filter directive (Nginx).

The Union Station filter language somewhat resembles expressions in many popular languages such as C, Javascript and Ruby. Every filter is a combination of expressions, each of which evaluate to a boolean. An expression is either a matching expression or a function call.

Quick examples

Example 1: URI must be exactly equal to /foo/bar:
uri == "/foo/bar"
Example 2: Response time must be larger than 150 miliseconds (150000 microseconds):
response_time > 150000
Example 3: URI must match the regular expression /animals/(dog|cat) and the response time must be larger than 60 miliseconds (60000 microseconds):
uri =~ /\/animals\/(dog|cat)/ && response_time > 60000
Example 4: The response time - not taking garbage collection into consideration - must be larger than 50 miliseconds, and the response status must be unsuccesful (in the 4xx or 5xx range).
response_time_without_gc > 50000 && status_code >= 400

Values

The filter language supports literal values and identifier values. Values always have a type. The following types are supported:

Integers
Integer literals must be written in decimal format. Hexadecimal and octal forms are not supported. Examples of integer literals: 1, 1234.
Booleans
Two boolean literals exist: true and false.
Strings
String literals begin and with either a single quote or a double quote character. \ can be used as escape character. The following special escaped characters are supported:
  • \n - newline (byte 10)
  • \r - carriage return (byte 13)
  • \t - tab (byte 9)
  • \\ - backslash
Examples:
"foo"
"hello world"
"Joe \"Trigger-Happy\" Dalton"
"string\nliteral"
'single-quote string'
Please note that, unlike most programming languages, escape characters work the same way in single-quote strings and double-quote strings. In the Union Station filter language the following string literals are equivalent:
"string\nliteral"
'string\nliteral'
Regular expressions
There are two regular expression literal syntaxes. The first one begins and ends with a slash:
/regexp definition here/optional modifiers here
The second one begins with %r{ and ends with }:
%r{regexp definition here}optional modifiers here

Regular expressions are case-sensitive by default. You can use the i modifier to make it case-insensitive. At this time this is the only supported modifier.

Just like with strings, \ can be used as escape character, and all special escaped characters supported by strings are also supported by regular expressions. Examples:

/foo/       matches "foo", "foobar", etc. but NOT "Foo", "FooBar", etc.
%r{foo}     same as above

/foo/i      matches "foo", "foobar", etc. and also "Foo", "FooBar", etc.
%r{foo}i    same as above
/foo( bar)+/
%r{foo( bar)+}
/newline\n/
%r{newline\n}
/\/users\/1/
%r{/users/1}

Identifier values

Identifier values are identifiers that evaluate to a value. The following identifiers are available:

  • uri - the URL, not including the scheme, host name and port, but including the query string. Examples: /foo/bar, /users/1/edit?return_to=overview.
  • response_time - the response time in microseconds.
  • response_time_without_gc - the response time in microseconds, without taking into account the time spent on garbage collection. Logically equivalent to response_time - gc_time.

    Your Ruby interpreter must support GC statistics APIs, otherwise this identifier is always equal to response_time. Please read gc_time for details and notes.

    Supported since Phusion Passenger 3.0.8.

  • gc_time - the amount of time spent on garbage collection, in microseconds. In order for Phusion Passenger to be able to collect garbage collection statistics, it must be using Ruby Enterprise Edition or some other Ruby interpreter which supports the GC statistics API. On Ruby interpreters where such an API is not available, gc_time is always 0.

    Supported since Phusion Passenger 3.0.8.

  • controller - the controller name, including the suffix "Controller". Only available when the app is a Rails app; for all other apps, this identifier evaluates to the empty string. Examples: CustomersController, UsersController.
  • status_code - the HTTP response status code as an integer.

    Supported since Phusion Passenger 3.0.8.

Matching expressions

Matching expressions have the form of:
subject operator object
and always evaluate to boolean values. subject and object are values, while operator is one of these:
==
Equality. Subject and object must be both strings or both integers.
!=
Inequality. Subject and object must be both strings or both integers.
=~
Test whether regular expression matches. Subject must be a string, object must be a regular expression.
!~
Test whether regular expression doesn't match. Subject must be a string, object must be a regular expression.
<
Less than. Subject and object must be both integers.
<=
Less than or equal to. Subject and object must be both integers.
>
Greater than. Subject and object must be both integers.
>=
Greather than or equal to. Subject and object must be both integers.

Function calls

Only one function call is available at the moment:
starts_with(haystack, needle)
Returns whether the string haystack starts with the string needle. The following example returns whether the URI starts with /foo/bar:
starts_with(uri, "/foo/bar")

Combining expressions with logical operators

One can combine expressions with boolean operators:
&&
Logical AND.
||
Logical OR.
!
Negation.
Examples:
uri == "/foo" || !starts_with(uri, "/bar")
response_time < 10000 && uri == "/should_be_slow"
To avoid ambiguity, one can group expressions together with brackets:
(uri == "/foo") || (uri == "bar" && response_time > 10000)
Please note that the language does not currently support operator precedence! That is, && and || have the same operator priority. So something like
response_time > 100000 || uri == "/foo" && response_time > 1000
is currently being interpreted as
(response_time > 100000 || uri == "foo") && response_time > 1000

Defining filters in Phusion Passenger for Apache

Use the UnionStationFilter directive. Its syntax is:
UnionStationFilter "(your filter source code here)"
This directive may appear in:
  • The global context.
  • Inside a VirtualHost block.
  • Inside a location block.
  • Inside .htaccess.

In each place, it may be specified multiple times, allowing one to define multiple filters. All defined filters are combined together with logical AND.

Please note that when specifying a configuration value in the Apache config file, if the value contains spaces then it needs to be surrounded by double quote characters. Otherwise Apache will think you're trying to pass multiple values to a config option that only supports a single value. Because of this, one must escape any special characters in the filter source.

Example:

<VirtualHost *:80>
ServerName www.example.com
DocumentRoot /webapps/example/public
UnionStationSupport on
UnionStationKey ...

# The filter must be surrounded by double quote characters,
# and any double quote characters that appear in the filter
# source must be escaped.
UnionStationFilter "starts_with(uri, \"/users\")"

# Alternatively you can use the single quote string syntax
# so you don't have to escape double quote characters in
# the filter source:
UnionStationFilter "starts_with(uri, '/users')"

# !!!! Don't do this! !!! Apache will report a syntax error!
UnionStationFilter starts_with(uri, "/users")
</VirtualHost>
Another example:
<VirtualHost *:80>
ServerName www.example.com
DocumentRoot /webapps/example/public
UnionStationSupport on
UnionStationKey ...

UnionStationFilter "starts_with(uri, '/users')"
UnionStationFilter "response_time > 100000"

# The above two directives together have the same effect
# as specifying this single directive:
UnionStationFilter "starts_with(uri, '/users') && response_time > 100000"
</VirtualHost>

Defining filters in Phusion Passenger for Nginx

Use the union_station_filter directive. Its syntax is:
union_station_filter "(your filter source code here)"
This directive may appear in:
  • The global 'http' block.
  • Inside a 'server' block.
  • Inside a 'location' block.

In each place, it may be specified multiple times, allowing one to define multiple filters. All defined filters are combined together with logical AND.

Please note that when specifying a configuration value in the Nginx config file, if the value contains spaces then it needs to be surrounded by double quote characters. Otherwise Nginx will think you're trying to pass multiple values to a config option that only supports a single value. Because of this, one must escape any special characters in the filter source.

Example:

server {
listen 80;
server_name www.example.com;
root /webapps/example/public;
passenger_enabled on;
union_station_support on;
union_station_key ...;

# The filter must be surrounded by double quote characters,
# and any double quote characters that appear in the filter
# source must be escaped.
union_station_filter "starts_with(uri, \"/users\")";

# Alternatively you can use the single quote string syntax
# so you don't have to escape double quote characters in
# the filter source:
union_station_filter "starts_with(uri, '/users')";

# !!!! Don't do this! !!! Nginx will report a syntax error!
union_station_filter starts_with(uri, "/users");
}
Another example:
server {
listen *:80;
server_name www.example.com;
root /webapps/example/public;
union_station_support on;
union_station_key ...;

union_station_filter "starts_with(uri, '/users')";
union_station_filter "response_time > 100000";

# The above two directives together have the same effect
# as specifying this single directive:
union_station_filter "starts_with(uri, '/users') && response_time > 100000";
}

Defining filters in Phusion Passenger Standalone

It is currently not possible to define filters in Phusion Passenger Standalone. Please request this feature at the Phusion Passenger issue tracker if you want it.

Notes on gathering memory usage

Phusion Passenger gathers application process-level memory usage statistics using the ps command, so this always works.

However in order to gather application-level memory usage statistics, such as the number of Ruby objects on the Ruby, Phusion Passenger requires certain APIs that are only available in Ruby Enterprise Edition or in Ruby 1.9. If you're using neither of those then you will only see process-level memory usage statistics in Union Station, not application-level memory usage statistics.

It should also be noted that application-level memory usage statistics are only reliable if the application is not multithreaded. Because of the nature of multithreading there is no way to gather useful memory usage statistics in their presence.

Notes on the request timeline

The request timeline shows how much time the server spends executing various actions on a single request.

The first block is always Selecting application process. When the server spends a significant amount of time in this block it means that a process is being spawned for this request or that the server is waiting for another request that is spawning a process.

After this Phusion Passenger sends the request header and then the request body to the application. When the application uses the Rails framework it first prepares and routes the request and then goes into the controller. The controller executes all the before filters, the action, then the after filters and finally renders the view.

APIs

Please consult the API page.

Contact

Union Station is written by Phusion. Please email info@phusion.nl for questions, support and feedback.