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
-
Sign up for Packrat. It's free.
-
Copy your ingest key from the setup page. It starts with
packrat_ingest_. -
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, elseservice.nameinOTEL_RESOURCE_ATTRIBUTES, else the application's module name (Shop::Applicationisshop). - Environment:
Rails.env, unlessOTEL_RESOURCE_ATTRIBUTESnames one. - Version:
BUILD_COMMIT,HEROKU_SLUG_COMMITorSOURCE_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.errorcontext.
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.77becomes203.0.113.0, and an IPv6 address becomes its/48. The addresses of servers your app calls, such asnet.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 inRails.errorcontext. To keep a parameter out of both, add it inconfig/initializers/filter_parameter_logging.rb. - Credentials: the value of any parameter or
name=valuepair named like a key, token, password, secret, signature or credential, and anyBearerorBasicvalue.
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_keysreplaces the value with[REDACTED]wherever the name appears: as a span attribute, a query parameter, aRails.errorcontext key or a key in a structured log line. An attribute matches on its whole name or its last segment, sossnalso matchesenduser.ssn. Unlikefilter_parameters, a key matches only the whole name:ssndoesn't matchssn_last4.redact_patternsreplaces each match with[REDACTED]. A string is matched literally.- The
redactblock receives each string value and its attribute name, which isnilfor 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
--strictto the generator. - Set
config.privacy = :strictinconfig/initializers/packrat.rb. - Set
PACKRAT_PRIVACY=strictwhere 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 statusshows 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.