Documentation / Ruby

Integrate a Ruby app or Rails service with Logister.

The best path for Ruby projects is the published RubyGems package logister-ruby. It is the Ruby-specific install path for sending errors, logs, metrics, transactions, spans, and check-ins into Logister.

Before you start

Create the project with the Ruby integration type.

What you needWhy it matters
Project API tokenAuthenticates your app when sending events
Logister instance base URLUsed to build the ingest and deployment endpoints
Ruby app with BundlerLets you install and configure logister-ruby
Optional GitHub App installationLets Logister use repository, commit_sha, branch, and deployment records for source excerpts and deploy links

What you get

Use the Ruby integration to start with errors, then add performance and deploy signals.

NeedWhat appears in Logister
See Ruby and Rails failures in one placeError groups in Issues with stacktrace details, request context, occurrence history, and triage actions.
Find repeated problemsGrouped issues based on fingerprints or consistent messages, with first-seen and last-seen history.
Capture useful manual errorsManual Logister.report_error calls include runtime, deployment, source, breadcrumb, dependency, user, and nested exception cause context.
Understand request loadOptional Rails request spans that feed request load waterfall charts on the performance page.
Understand database pressuredb.query metric events that power database load cards on the performance page when database metrics are enabled.
Resolve source and deploy historyrepository, commit_sha, branch, release, and deployment records that let Logister show source excerpts, GitHub links, and "started after deploy" context when a GitHub repository is connected to the project.
Keep sensitive values out of eventsClient-side redaction of sensitive keys, credential-shaped strings, and sensitive URL query values, plus an allowlist for captured request headers. See Redaction.
Watch custom operationsLogs, metrics with value/unit context, transactions, spans, and check-ins in activity, performance, and monitor views.

Setup flow

Recommended installation path

  1. Create the project. Logister opens its setup path at the API key step; create the key there.
  2. Add logister-ruby to the application.
  3. Configure the API key, Logister ingest endpoint, environment, release, and source context.
  4. Optionally enable DB metrics for performance visibility.
  5. From CI/CD, call Logister.record_deployment after a successful deploy so releases map to exact commits.

Tip

If you only want error capture at first, ship the base config first and add source context, deployment records, and database metrics next.

Install

Install logister-ruby from RubyGems.

Use the published package when you want a Ruby app or Rails service to send errors, logs, metrics, transactions, spans, check-ins, and deployment records into Logister through Bundler or RubyGems. The RubyGems listing is the canonical package page for install commands, version history, and package metadata.

ruby
gem "logister-ruby", "~> 0.6.0"
shell
bundle install
gem install logister-ruby

Package links: RubyGems and GitHub.

Upgrading

Upgrading to 0.6.0: review the changed defaults.

Version 0.6.0 changes what the gem captures and how it delivers events. Review each row before you update the gem in an application, then use the linked section for the exact option.

AreaCurrent behaviorWhat to review
Request headersCaptured from an allowlist. Headers outside it are not sent.Add any other header you rely on to config.capture_headers. See Request headers.
SQL breadcrumbsChanged default: capture_sql_breadcrumbs is false. When enabled, string and numeric literals are replaced with ?.Set config.capture_sql_breadcrumbs = true if you want SQL breadcrumbs. See SQL breadcrumbs.
db.query metricsWith capture_db_metrics, string and numeric literals in the captured sql are replaced with ?.Expect ? placeholders in the sql context field.
RedactionSensitive keys, credential-shaped strings, and sensitive URL query values in the message and the whole context become [REDACTED]. URL fragments are dropped.Add project-specific keys with config.redact_keys. See Redaction.
anonymize_ipAlso truncates every address in X-Forwarded-For and X-Real-Ip.No change needed if you already set config.anonymize_ip = true.
User contextLogister.set_user stores the user in the request scope, which is reset when each request or job ends.Call Logister.clear_user at the end of work in other long-lived threads. See User context.
Event sizeEach event is bounded. An event over config.max_event_bytes (default 256 KB) after a compact second pass is dropped with reason event_too_large.Check unconfirmed_events in Logister.delivery_stats. See Event limits.
Synchronous deliveryWith config.async = false, and for deployment records, retries use config.sync_max_retries (default 1) with waits capped at one second.Set sync_max_retries if you need a different budget, up to max_retries.
RetriesOnly transport failures and HTTP 408, 425, 429, and 5xx responses are retried.Other errors fail the attempt once.
ReconfiguringCalling Logister.configure again shuts down the previous client after it drains what it already queued. One at_exit hook flushes the current reporter.No change needed.

Verify it

After upgrading, trigger one test error from a request in a non-production environment. Open the event and confirm the headers and context fields you rely on are present and sensitive values show [REDACTED]. Then check Logister.delivery_stats for unexpected unconfirmed_events.

The full list of changes is in the changelog.

Configure

Point the gem at your Logister project.

shell
mkdir -p config/initializers
ruby
Logister.configure do |config|
  config.api_key = ENV.fetch("LOGISTER_API_KEY")
  config.endpoint = ENV.fetch("LOGISTER_ENDPOINT")
  config.environment = Rails.env
  config.release = ENV["LOGISTER_RELEASE"]
  config.repository = ENV["LOGISTER_REPOSITORY"] || ENV["GITHUB_REPOSITORY"]
  config.commit_sha = ENV["LOGISTER_COMMIT_SHA"] || ENV["GITHUB_SHA"]
  config.branch = ENV["LOGISTER_BRANCH"] || ENV["GITHUB_REF_NAME"]
  config.capture_request_spans = true
end

The endpoint should be your Logister instance base URL plus /api/v1/ingest_events. Use HTTPS: the client logs a warning when an endpoint uses http:// on a host other than localhost or a loopback address. Calling Logister.configure again replaces the reporter; the previous client drains what it already queued and stops.

The ingest endpoint accepts 1,200 requests per minute per API token by default and returns 429 Too Many Requests with retry headers when that limit is exceeded.

Important

The API token is only shown once, when you create it. Store it in your environment or secret manager before you navigate away.

Inspect delivery outcomes.

The Ruby SDK provides Logister.delivery_stats and config.delivery_observer. Counters distinguish queued, acknowledged, unconfirmed, queue-full and retry outcomes. Observer callbacks contain counts and safe reason codes, never event payloads. Send them to an independent log sink to avoid feedback loops. A successful flush only means pending work drained; it does not prove delivery. Async shutdown waits at most one second and returns false if the worker is still active.

See the SDK README for the complete contract.

Event limits

Bound event size and synchronous retries.

Each event is sanitized and serialized on its own before it is batched, so an event that is too large or cannot be serialized is dropped alone and the rest of its batch is still sent.

LimitValue
String lengthTruncated at 16 KB
Collection size100 items
Nesting depth10 levels
Keys per event400
Whole eventconfig.max_event_bytes, default 262_144 (256 KB)

Invalid UTF-8 is replaced and NaN/Infinity become strings. When anything is cut, logister_truncated: true is added to the context. An event still larger than max_event_bytes after a second, tighter pass is dropped and counted as unconfirmed with reason event_too_large. An event that cannot be serialized is dropped with reason serialization_error.

ruby
Logister.configure do |config|
  config.max_event_bytes = 262_144
  config.max_retries = 3
  config.sync_max_retries = 1
end

Synchronous delivery retries

With config.async = false, delivery runs on the caller's thread, so it uses sync_max_retries (default 1, never more than max_retries) and caps each wait at one second. Deployment records are always sent this way. Asynchronous delivery keeps the max_retries budget.

Only transport failures are retried: timeouts, IOError, SocketError, OpenSSL::SSL::SSLError, Errno::*, and HTTP 408, 425, 429, or 5xx responses. Any other error fails the attempt once.

Verify it

If events you expect are missing, check unconfirmed_events in Logister.delivery_stats. Look for a logister_truncated context field on events that arrived but look shorter than expected.

Privacy defaults

Know what the gem redacts before an event is sent.

Every event is redacted in the client before it is serialized, using the default redaction rules shared by all Logister SDKs. Matching values are replaced with [REDACTED].

RuleWhat it matchesResult
Sensitive keysA key that, lowercased with every non-alphanumeric character removed, equals a listed name such as password, secret, token, apikey, authorization, cookie, setcookie, accesstoken, signature, ssn, creditcard, or cvv, or contains token, secret, password, passwd, apikey, authorization, credential, or cookie.The whole value becomes [REDACTED].
Credential-shaped stringsBearer <x> and Basic <x> values, JWT-shaped strings, lgst_ keys, and name=value pairs with a sensitive name.Bearer [REDACTED] / Basic [REDACTED]. JWTs and lgst_ keys become [REDACTED]. A name=value pair keeps its name.
Request URL and refererSensitive query parameter values and userinfo passwords.Scheme, host, and path are kept; those values become [REDACTED] and the fragment is dropped.

Redaction covers the message and the whole context: request URL, referer, headers, params, user context, tags, breadcrumbs, dependency calls, job arguments (after Rails filter_parameters), span attributes, log fields, and exception data. Envelope fields such as uuid, event_type, trace_id, span_id, parent_span_id, request_id, and session_id are never redacted. The full list of sensitive key names is in the SDK README.

Add project-specific keys

Add keys with config.redact_keys. Entries are normalized the same way and must match a key exactly.

ruby
Logister.configure do |config|
  config.redact_keys = ["tenant_ref", "X-Internal-Signature"]
end

Request headers

Request headers are captured from an allowlist: Accept, Accept-Encoding, Accept-Language, Cache-Control, Content-Length, Content-Type, Dnt, Host, Origin, Referer, User-Agent, Via, W3C, B3, Datadog, and AWS trace headers, X-Request-Id, X-Forwarded-For/Host/Proto/Port, X-Real-Ip, and Sec-Fetch-*/Sec-Ch-Ua* hints. Other headers are not sent.

Add headers with config.capture_headers. The sensitive-key rule still applies, so an added header such as X-Auth-Token is captured as [REDACTED].

ruby
Logister.configure do |config|
  config.capture_headers = ["X-Tenant"]
  config.anonymize_ip = true
end

With config.anonymize_ip = true, the client IP and every address in X-Forwarded-For and X-Real-Ip are truncated (/24 for IPv4, /64 for IPv6).

ruby
Logister.report_error(
  RuntimeError.new("Redaction test error"),
  context: { password: "example", tenant_ref: "example" },
  fingerprint: "redaction-test-error"
)
Logister.flush

Verify it

Run the snippet above from bin/rails console, then open Redaction test error in the project inbox. password should show [REDACTED], and so should tenant_ref once it is listed in config.redact_keys. To check headers, trigger a test error from a request and confirm the headers you added appear in the event's request context.

User context

Attach the signed-in user to the current request or job.

Errors reported during the current request or job include the user you set with Logister.set_user. User context is redacted with the same rules as the rest of the event.

ruby
Logister.set_user(id: current_user.id, email: current_user.email, name: current_user.name)
Logister.clear_user

The user is stored in the request scope. The Rack middleware and the Active Job integration reset that scope when each request or job ends, so identity does not carry over to the next request on a reused Puma or Sidekiq thread. In other long-lived threads, call Logister.clear_user when the unit of work ends.

Source and deployments

Record the deployed commit when CI/CD knows it.

If the project is connected to the GitHub App, Logister can use source context to resolve Ruby and Rails stack frames to repository files. Deployment records tell Logister which commit was deployed for a release and environment.

ruby
Logister.record_deployment(
  release: ENV.fetch("LOGISTER_RELEASE"),
  environment: ENV.fetch("LOGISTER_ENVIRONMENT", Rails.env),
  repository: ENV.fetch("LOGISTER_REPOSITORY", "acme/checkout"),
  commit_sha: ENV.fetch("LOGISTER_COMMIT_SHA", ENV["GITHUB_SHA"]),
  branch: ENV["LOGISTER_BRANCH"] || ENV["GITHUB_REF_NAME"],
  deployed_at: Time.now.utc.iso8601,
  release_tag: ENV["GITHUB_REF_NAME"],
  workflow_run_url: ENV["GITHUB_RUN_ID"] && "https://github.com/#{ENV["GITHUB_REPOSITORY"]}/actions/runs/#{ENV["GITHUB_RUN_ID"]}"
)
FieldSet it fromUsed for
repositoryLOGISTER_REPOSITORY or GITHUB_REPOSITORYFinds the GitHub repository connected to the project.
commit_shaLOGISTER_COMMIT_SHA or GITHUB_SHAResolves stack frames and deployment context to the exact commit.
branchLOGISTER_BRANCH or GITHUB_REF_NAMEFalls back when an event has no commit or deployment record yet.
releaseYour app version, build ID, tag, or package versionConnects event filters, release health, and deployments.

config.deployment_endpoint defaults to the configured ingest endpoint with /ingest_events replaced by /deployments. Set LOGISTER_DEPLOYMENT_ENDPOINT only when that endpoint cannot be derived from LOGISTER_ENDPOINT.

Verify it

After a deploy, send one test exception with the same release. Open the event detail and check for source lookup status, deployment context, and GitHub links. If source is missing, confirm the GitHub App is installed, linked to the project, and the repository is connected; then check that the event has repository plus either commit_sha or a matching deployment record.

Metrics

Enable DB timing metrics when needed.

ruby
Logister.configure do |config|
  config.capture_db_metrics = true
  config.db_metric_min_duration_ms = 10.0
  config.db_metric_sample_rate = 1.0
end
SettingPurpose
capture_db_metricsTurns database timing capture on
db_metric_min_duration_msFilters out very fast queries
db_metric_sample_rateControls how much query traffic is reported

Each sample is a metric event with message: "db.query" and context fields such as duration_ms, name, sql, and binds_count. String and numeric literals are replaced with ? in the captured sql; bind placeholders like $1 and quoted identifiers are kept.

Manual metrics and check-ins

ruby
Logister.report_metric(
  message: "queue.depth",
  value: 12,
  unit: "jobs",
  context: { queue: "emails" }
)

Logister.report_check_in(
  slug: "nightly-reconcile",
  status: "ok",
  expected_interval_seconds: 900,
  duration_ms: 248.3,
  release: ENV["LOGISTER_RELEASE"],
  trace_id: "trace-123",
  request_id: "req-123"
)
Verification
Performance page checklist
transactions visible
db.query samples flowing
request spans visible
source context visible on events when configured
deployment context visible after Logister.record_deployment runs
no missing API token errors

Useful examples

Add the context that makes Ruby events easier to triage.

Attach breadcrumbs and dependency calls before an error

ruby
Logister.add_breadcrumb(
  category: "checkout",
  message: "Starting payment authorization",
  data: { order_id: 123 }
)

Logister.add_dependency(
  name: "stripe.charge",
  host: "api.stripe.com",
  method: "POST",
  status: 200,
  duration_ms: 184.7,
  kind: "http"
)

SQL breadcrumbs

Rails request breadcrumbs are captured automatically. SQL breadcrumbs are off by default (capture_sql_breadcrumbs = false) because adapters without prepared statements inline literal values. Turn them on to record queries slower than sql_breadcrumb_min_duration_ms; string and numeric literals are replaced with ?.

ruby
Logister.configure do |config|
  config.capture_sql_breadcrumbs = true
  config.sql_breadcrumb_min_duration_ms = 25.0
end

Report worker spans and a transaction

ruby
trace_id = SecureRandom.hex(16)
root_span_id = SecureRandom.hex(8)

Logister.report_transaction(
  name: "billing.reconcile",
  duration_ms: 1840.7,
  context: { trace_id: trace_id, queue: "billing", service: "billing-worker" }
)

Logister.report_span(
  name: "billing.reconcile",
  duration_ms: 1840.7,
  trace_id: trace_id,
  span_id: root_span_id,
  kind: "server",
  status: "ok",
  context: { queue: "billing" }
)

Logister.report_span(
  name: "load invoices",
  duration_ms: 430.2,
  trace_id: trace_id,
  parent_span_id: root_span_id,
  kind: "db",
  status: "ok",
  context: { queue: "billing" }
)

Use breadcrumbs for the steps leading to an exception, dependency calls for outbound services, transactions for total work duration, and spans for the pieces of that work that should appear in request load waterfall charts.

Follow requests between projects

Logister 3.7 adds explicit project connections and request-identifier evidence. See request correlation setup for the required SDK versions, origin allowlists, permissions, and verification.