Ruby on Rails

Packrat monitors your Ruby on Rails application deploys, creating a verification plan and validating that it performs as intended in production. This guide walks through the Packrat setup for a Rails application.

The packrat-rails gem sets up OpenTelemetry in your app and sends its exceptions, traces and logs to Packrat. It supports Rails 7.1 and newer.

Already running Datadog's tracer? Dual-ship from the Datadog Agent.

Prerequisites

  1. Sign up for Packrat. It's free.

  2. Copy your ingest key from the setup page. It starts with packrat_ingest_.

  3. Install the Packrat CLI and sign in, so you can check what Packrat receives:

    curl -fsSL https://packrat.sh/cli | sh
    packrat login
    

Install the gem

1. Add packrat-rails

bundle add packrat-rails

2. Run the generator

bin/rails generate packrat --ingest-key=packrat_ingest_…

The generator creates config/initializers/packrat.rb:

Packrat.configure do |config|
  config.ingest_key = ENV.fetch("PACKRAT_INGEST_KEY", "packrat_ingest_…")
  # :strict sends no log text, query strings or exception messages: https://packrat.sh/docs/ruby-on-rails#privacy
  # config.privacy = :strict
end

An ingest key can only send data, so you can commit the file. To keep the key out of the repository, run the generator without --ingest-key and set a PACKRAT_INGEST_KEY environment variable where the app runs.

The generator also adds the Packrat plugin for Claude Code to your repository's .claude/settings.json. Commit the file, and anyone who opens Claude Code in the repository gets the plugin. To skip this, pass --no-claude-code.

To start with strict privacy, pass --strict.

3. Restart the app

When the app boots, the gem writes one line to the Rails log. It names the service and environment your data arrives under:

Packrat: sending traces and logs for shop/production to https://ingest.packrat.sh (rack, action_pack, active_job, active_record, net_http, pg, logger); redacting email and ip

The gem sends nothing from the test environment.

Check it works

Load a page. The first request reaches your setup screen within about a minute.

Run packrat status with your app's name, as <service>/<environment>:

packrat status --app shop/production

The output lists each signal (exceptions, traces, logs, metrics and replays), the sources that send it, when each source last sent, and whether Packrat keeps it. A signal with no source hasn't arrived yet. To see the names your apps report under, run packrat apps.

If nothing arrives, the quickstart lists what usually causes it.

Configuration

Packrat.configure sets the ingest key, the privacy level and your own redaction. Everything else is an environment variable:

Variable Default Note
PACKRAT_INGEST_KEY config.ingest_key Wins over the initializer. With neither, the gem sends nothing
PACKRAT_DISABLED unset 1 turns the gem off. The app boots as if the gem were not installed
PACKRAT_OTEL_INSTRUMENTATIONS the list below Comma-separated names to add. A leading - removes one
PACKRAT_PRIVACY config.privacy, else standard standard or strict. Wins over the initializer. Any other value is strict
PACKRAT_REDACT email,ip Patterns redacted from values. -ip stops masking IP addresses
PACKRAT_DEBUG_EXPORT config.debug_export, else off 1 prints everything the gem sends to stdout. See what is sent

The gem installs these instrumentations: rack, action_pack, action_view, active_job, active_record, net_http, pg, mysql2, sidekiq, redis, aws_sdk, concurrent_ruby, rake and logger. One for a library your app doesn't use installs nothing. For example, PACKRAT_OTEL_INSTRUMENTATIONS=faraday,-action_view adds Faraday (add opentelemetry-instrumentation-faraday to your bundle too) and removes Action View.

Your app's name in Packrat is <service>/<environment>:

  • Service: OTEL_SERVICE_NAME, else service.name in OTEL_RESOURCE_ATTRIBUTES, else the application's module name (Shop::Application is shop).
  • Environment: Rails.env, unless OTEL_RESOURCE_ATTRIBUTES names one.
  • Version: BUILD_COMMIT, HEROKU_SLUG_COMMIT or SOURCE_VERSION. Packrat matches it to your deploys.

A standard OTEL_* variable that you set always wins over the gem's value.

Privacy

By default, packrat-rails scrubs sensitive data before it reaches our servers. It has two privacy levels: standard (the default) and strict.

Standard

Standard sends requests, queries, log lines and errors, with personal data redacted. SQL and Redis commands are sent with every value replaced by ?. Request and response headers, job arguments and the client IP on spans are never sent.

Strict

Strict sends everything standard does, except:

  • The text of each log line, which becomes [REDACTED]. The severity and the request are kept.
  • Exception messages, which become [REDACTED], in the stack as well. The class and the stack frames are kept.
  • Query strings.
  • User agents.
  • Rails.error context.

Strict keeps what a deploy check needs: routes, durations, status codes, errors by class and the shape of each query. Without log text, Packrat can't group your log lines or read the GC time Rails writes to the log.

What is redacted

In standard, the gem changes these before export:

  • Email addresses become a token such as [email:4f2a91c0], the first eight hex digits of an HMAC-SHA256 keyed by your ingest key. The same address gives the same token everywhere, so you can still count per person. A new ingest key gives new tokens.
  • IP addresses keep their network: 203.0.113.77 becomes 203.0.113.0, and an IPv6 address becomes its /48. The addresses of servers your app calls, such as net.peer.ip, are kept.
  • Parameters in filter_parameters, the list Rails uses to filter your own logs, are replaced with [REDACTED] in query strings and in Rails.error context. To keep a parameter out of both, add it in config/initializers/filter_parameter_logging.rb.
  • Credentials: the value of any parameter or name=value pair named like a key, token, password, secret, signature or credential, and any Bearer or Basic value.

To stop one pattern, remove it with PACKRAT_REDACT: PACKRAT_REDACT=-ip keeps IP addresses.

Patterns find emails, IP addresses and credentials. They can't recognize other personal data, such as a name or an account number, that your app writes into a log line. To remove that, add your own redaction. If your logs can hold text you can't describe, such as the body of a support ticket, use strict.

Redact your own data

Add your own keys, patterns or a block to config/initializers/packrat.rb. They run after the gem's own redaction, in standard and in strict:

Packrat.configure do |config|
  config.ingest_key = ENV.fetch("PACKRAT_INGEST_KEY", "packrat_ingest_…")

  # Replace the whole value of these attributes and parameters
  config.redact_keys = %w[ssn account_number]

  # Replace each match, in every value and log line
  config.redact_patterns = [/acct \d{4}-\d{2}/]

  # Change any string before it is sent
  config.redact { |value, name| value.gsub(Customer::NAME_PATTERN, "[name]") }
end
  • redact_keys replaces the value with [REDACTED] wherever the name appears: as a span attribute, a query parameter, a Rails.error context key or a key in a structured log line. An attribute matches on its whole name or its last segment, so ssn also matches enduser.ssn. Unlike filter_parameters, a key matches only the whole name: ssn doesn't match ssn_last4.
  • redact_patterns replaces each match with [REDACTED]. A string is matched literally.
  • The redact block receives each string value and its attribute name, which is nil for a log line, and returns the string to send. If the block raises an error or returns something other than a string, the gem sends [REDACTED] in place of the value and logs one warning.

The boot line names what you added: …; redacting email and ip and the app's own keys, patterns, block.

These settings need packrat-rails 0.3.0 or newer. To upgrade, run bundle update packrat-rails.

Turn on strict

Do one of the following:

  • Pass --strict to the generator.
  • Set config.privacy = :strict in config/initializers/packrat.rb.
  • Set PACKRAT_PRIVACY=strict where the app runs. The variable wins over the initializer, so you can try strict in staging without a commit.

The boot line says which level is on: …; strict privacy, redacting email and ip.

See what is sent

To check the redaction yourself, set PACKRAT_DEBUG_EXPORT=1 and start the app. The gem prints each span and log line to stdout as it is sent, after redaction, one JSON object a line:

Packrat export: {"span":"GET /orders/:id","kind":"server","attributes":{"http.route":"/orders/:id","url.query":"token=[REDACTED]&page=2",…},"events":[]}
Packrat export: {"log":"Refund issued to [email:4f2a91c0]","severity":"INFO","attributes":{}}

The gem still sends everything to Packrat as usual. You can also set config.debug_export = true in the initializer; PACKRAT_DEBUG_EXPORT=0 turns it off again.

How long data is kept

Packrat keeps the most recent 13 months of your data. As data turns 13 months old, it is deleted.

Beside other tools

Packrat can run alongside your existing monitoring libraries.

  • Sentry: both run, and the gem doesn't change Sentry. If Sentry also dual-ships to Packrat, Packrat keeps exceptions and traces from whichever source sent them first. packrat status shows which.
  • Your own OpenTelemetry setup: the gem leaves it as it is and adds a second exporter, to Packrat. If your exporter already sends to Packrat, the gem adds nothing.

To configure OpenTelemetry yourself instead of using the gem, follow the Rails tab of the OpenTelemetry guide.