allstak

AllStak SDK for Ruby, Rails, Rack, and Sidekiq. Captures exceptions, logs, inbound and outbound HTTP requests, ActiveRecord queries, Sidekiq job failures, spans, and cron heartbeats. Rails apps are auto-instrumented via a Railtie; Sidekiq via a server middleware.

Install

gem install allstak

Or add it to your Gemfile:

gem "allstak"

Setup

require "allstak"

AllStak.configure do |config|
  config.api_key = ENV["ALLSTAK_API_KEY"]
  config.environment = ENV.fetch("APP_ENV", "production")
  config.release = ENV["ALLSTAK_RELEASE"]
  config.service_name = "checkout-api"
end

AllStak.capture_exception(StandardError.new("checkout failed"))
AllStak.log.info("payment retry", metadata: { order_id: "ord_123" })

Rails

For Rails apps there is no manual wiring. Requiring the gem loads a Railtie that auto-inserts the AllStak Rack middleware into your application's middleware stack during boot. Just configure the SDK during app initialization (e.g. in config/initializers/allstak.rb):

require "allstak"

AllStak.configure do |config|
  config.api_key = ENV["ALLSTAK_API_KEY"]
  config.environment = Rails.env
  config.service_name = "checkout-api"
end

You then get inbound request telemetry, trace propagation, unhandled-exception capture, ActiveRecord query instrumentation, and outbound Net::HTTP capture automatically. The middleware insertion is idempotent.

Rack (non-Rails)

For plain Rack apps (Sinatra, Roda, etc.), add the middleware yourself:

use AllStak::Integrations::Rack::Middleware

Sidekiq

When Sidekiq is present, AllStak.configure registers a Sidekiq server middleware automatically — no manual setup. It wraps each job in a span and breadcrumb, and captures job failures with worker class, jid, queue, and (PII-sanitized) args as context, then re-raises so Sidekiq's retry machinery still runs. Jobs that exhaust their retries are also captured via a death handler. When Sidekiq is not installed, this is a graceful no-op.

Spans

AllStak.tracing.in_span("checkout.authorize") do
  authorize_payment
end

Breadcrumbs are collected automatically — no per-call code. After AllStak.configure, the SDK records a trail of recent events on a 50-entry per-thread ring buffer and attaches it to the next captured exception on that thread. Auto breadcrumbs come from:

  • inbound Rack requests (method, path, status, duration),
  • outbound Net::HTTP calls (method, host, path, status, duration),
  • ActiveRecord queries (truncated SQL, duration, status),
  • Sidekiq job processing,
  • and every AllStak.log.* call.

Because the buffer is per-thread, one request's trail never bleeds into a concurrent request's exception. You can also add your own:

AllStak.add_breadcrumb(type: "auth", message: "password reset requested",
                       data: { "userId" => current_user.id })

Disable automatic collection (manual add_breadcrumb still works) with enable_auto_breadcrumbs = false or ALLSTAK_AUTO_BREADCRUMBS=0.

Structured logs (optional)

Ship your application logs to AllStak by composing the optional log adapter with your existing logger — existing log destinations are preserved:

# Rails 7.1+ (broadcast alongside the current logger):
AllStak::Integrations::Logger.attach_to_rails!

# Any Ruby logger:
logger = AllStak::Integrations::Logger.broadcast(logger)

Once attached, logger.info / .warn / .error ship to /ingest/v1/logs automatically. Records at ERROR/FATAL are additionally promoted to error entries so they surface in the Errors list. Disable promotion with AllStak::Integrations::Logger.new(error_promotion: false), or change the threshold with error_promotion_level:. The adapter is opt-in and fail-open — it never raises into your logging path.

Configuration

Option Description
api_key Project API key.
environment Deployment environment.
release App version or commit SHA.
service_name Logical service name.
flush_interval_ms Background flush interval.
buffer_size Max buffered events.
enable_auto_breadcrumbs Collect breadcrumbs automatically from the Rack/Net::HTTP/ActiveRecord/Sidekiq instrumentation and the AllStak.log.* bridge (default true; env ALLSTAK_AUTO_BREADCRUMBS=0 to disable). Manual AllStak.add_breadcrumb is unaffected.
install_at_exit_handler Install a process-wide at_exit hook that captures the exception terminating the process as an unhandled event (default true).
before_send Callable invoked with the event hash just before transport. Return a modified hash, or nil to drop the event. Fails open (sends the original) if it raises.
sample_rate Float in [0.0, 1.0] head-sampling rate for error/message events (default 1.0 = keep all).
traces_sample_rate Float in [0.0, 1.0] span sampling rate. nil (default) keeps every span and the traceparent sampled flag; when set, span creation is sampled and the propagated traceparent flag reflects the decision.

For top-level uncaught exceptions outside Rack (workers, threads, rake tasks), the at_exit handler catches genuine unhandled terminations automatically. You can also report manually at a boundary:

begin
  run_worker
rescue => e
  AllStak.capture_unhandled(e) # mechanism=at_exit, handled=false
  raise
end

Privacy

The SDK redacts common sensitive headers and fields. Avoid putting secrets in custom metadata.

Troubleshooting

  • No events: confirm ALLSTAK_API_KEY is available before configuration.
  • Missing request telemetry (Rails): confirm require "allstak" runs at boot so the Railtie can auto-insert the middleware.
  • Missing request telemetry (plain Rack): confirm use AllStak::Integrations::Rack::Middleware is in your Rack stack.
  • Short-lived job: call AllStak.flush before exit when possible.

Contributing and Support

License

MIT