Rack

To instrument Rack applications, AppSignal provides a Rack instrumentation middleware. If you use any of the supported Rack frameworks like Rails, Sinatra, Hanami, Grape, or Padrino, we recommend using those instrumentations instead.

Add the instrumentation middleware

AppSignal for RubyThis feature requires version 3.10.0 or higher.

To integrate AppSignal in a Rack application, we first need to load, configure, and start AppSignal.

Then, instrument the Rack app by adding our Rack EventHandler and InstrumentationMiddleware middleware to the middleware stack.

This documentation explains how to do this in your application's config.ru file.

ruby
# config.ru require "appsignal" # Load AppSignal Appsignal.config = Appsignal::Config.new( Dir.pwd, # Application root path ENV["RACK_ENV"], # Application environment ) Appsignal.start # Start the AppSignal integration Appsignal.start_logger # Start logger # Add the Rack EventHandler middleware first use ::Rack::Events, [Appsignal::Rack::EventHandler.new] # Add the Rack InstrumentationMiddleware middleware use Appsignal::Rack::InstrumentationMiddleware # Load your app with a require statement here, like require_relative "app" # Add other middleware here if needed # Finally, run the app use MyApp.run

Ensure the EventHandler and Instrumentation middleware are registered in the application middleware stack as early as possible. The earlier these middleware are registered, the more request runtime the middleware will instrument. If other middleware are registered beforehand, our middleware will not instrument these other middleware.

After adding the EventHandler and InstrumentationMiddleware to your app's middleware stack, the action needs to be set for each route in your app in AppSignal. Without an action name to group requests, the EventHandler will not report request information.

For more insights into the operation of your Rack application, we recommend adding additional instrumentation to the application's endpoints.

The Rack EventHandler middleware

We recommend adding our Rack EventHandler middleware to all Rack applications. This middleware will ensure we track The AppSignal Rack EventHandler middleware has the following features:

  • Instrumentation of the request and recording a process_request.rack event.
  • Reporting Exceptions that occur in the app and middleware.
  • Tracking the response status code as the response_status tag on the sample.
  • Tracking the response status code as the response_status metric, with the namespace and status tags.

The Rack instrumentation middleware

We recommend that in addition to the Appsignal::Rack::EventHandler, the AppSignal::Rack::InstrumentationMiddleware is added to the app. This middleware supplements the EventHandler's instrumentation by adding tags for the request path and request method, as well as tracking response body handling and response body closing operations.

The instrumentation middleware has the following features:

  • Instrumentation of the request and recording a process_request.rack event.
  • Reporting Exceptions that occur in the app.
  • Tracking the request path and request method as tags on the sample.
  • Instrumentation of the response body handling and recording a process_response_body.rack event for this operation.
  • Instrumentation of the response body closing and recording a close_response_body.rack event for this operation.

Using the legacy instrumentation middleware

AppSignal for RubyThis feature requires version v1.1.6 or higher.

The GenericInstrumentation middleware was deprecated in Ruby gem 3.10.0. Please use the new guide instead.

To integrate AppSignal in a Rack application, we first need to load, configure, and start AppSignal.

Then, instrument the Rack app by adding our Rack GenericInstrumentation middleware to the middleware stack.

This documentation explains how to do this in your application's config.ru file.

ruby
# config.ru # Load and configure AppSignal require "appsignal" # Load AppSignal Appsignal.config = Appsignal::Config.new( File.expand_path("../", __FILE__), # Application root path ENV["RACK_ENV"], # Application environment ) Appsignal.start # Start the AppSignal integration Appsignal.start_logger # Start logger # Load your app with a require statement here, like require_relative "app" # Add the GenericInstrumentation middleware use Appsignal::Rack::GenericInstrumentation # Add other middleware here if needed # Finally, run the app use MyApp.run

Ensure the EventHandler and Instrumentation middleware are registered in the application middleware stack as early as possible. The earlier these middleware are registered, the more request runtime the middleware will instrument. If other middleware are registered beforehand, our middleware will not instrument these other middleware.

After adding the EventHandler and InstrumentationMiddleware to your app's middleware stack, the action needs to be set for each route in your app in AppSignal. Without an action name to group requests, the EventHandler will not report request information.

For more insights into the operation of your Rack application, we recommend adding additional instrumentation to the application's endpoints.

Setting the action name

Set an action name on the AppSignal transaction for a request so we can group endpoints in our issues and metrics. We recommend using a static action name per endpoint, like GET /blog, POST /users, PUT /users/:id, etc.

To set an action name for a request, call the Appsignal.set_action helper from the app.

Do not use the request path of the route as the action name if the path has dynamic segments. Using real request paths for action names breaks our request grouping by creating unique issues for each possible request path.

ruby
# app.rb require "rack" # Example pure-Rack app class MyApp def call(env) case [env["REQUEST_METHOD"], env["PATH_INFO"]] when ["GET", "/"] Appsignal.set_action("GET /") # Action name set here body = <<~BODY <h1>Rack example app</h1> <ul> <li><a href="/slow">Slow request</a></li> <li><a href="/error">Error request</a></li> </ul> BODY [200, {"Content-Type" => "text/html"}, [body]] when ["GET", "/slow"] Appsignal.set_action("GET /slow") # Action name set here sleep 1 [200, {"Content-Type" => "text/plain"}, ["Slow response"]] when ["GET", "/error"] Appsignal.set_action("GET /error") # Action name set here raise "uh oh" else Appsignal.set_action("NotFound") # Action name set here [404, {"Content-Type" => "text/plain"}, ["Page not found"]] end end end