Naijacloud
Docs

Ruby and Rails

On Rails, the gem and an ARGUS_DSN are the whole setup. Rack apps, Sinatra and scripts call init once. The gem uses only the standard library and needs Ruby 3.0 or newer.

5 min read

Install

Install
bash
bundle add naijacloud-argus

Set up

Rails

Set the DSN where the app runs. There is no initializer to write:

Start
bash
ARGUS_DSN=https://<public key>@argus-in.naijacloud.com/<project id> bin/rails server

The gem's Railtie starts Argus after your initializers. To change options, add an initializer; it runs first, so it wins:

config/initializers/argus.rb
ruby
NaijaCloud::Argus.init do |c| c.release = ENV["GIT_SHA"] c.traces_sample_rate = 0.2 c.rails_logs = true # also send Rails.logger lines to Argus Logs end

Rack, Sinatra and plain Ruby

config.ru
ruby
require "naijacloud/argus" NaijaCloud::Argus.init # reads ARGUS_DSN use NaijaCloud::Argus::Rack run App

In a script or a worker, call NaijaCloud::Argus.init at the top. An exception that ends the process is reported, and what's queued is sent before it exits.

init with no dsn reads ARGUS_DSN, then SENTRY_DSN. A Naijacloud service gets the DSN from its Send errors to Argus switch. Without a DSN the gem does nothing, so development and test need no changes.

Send a test event

Send a test event
bash
bin/rails runner 'NaijaCloud::Argus.capture_message("Argus test event")'

Outside Rails:

Send a test event
bash
ruby -e 'require "naijacloud/argus"; NaijaCloud::Argus.init; NaijaCloud::Argus.capture_message("Argus test event")'

The exit hook sends the event, and it shows under Argus → Errors. Add ARGUS_DEBUG=1 to print what the gem does.

What it captures

On Rails, with only the DSN:

  • Every request, traced, named by its route (GET /orders/:id), continuing a traceparent header from the caller.
  • Unhandled exceptions, with the request they came from. A 404 or a bad CSRF token is not reported.
  • ActiveJob failures, with the job's class, id and queue, and a trace of each job. retry_on and discard_on behave as before.
  • Rails.error (Rails 7.0 and later): Rails.error.report and Rails.error.handle reach Argus too.
  • Outgoing Net::HTTP calls (and Faraday, HTTParty and anything built on it), traced, with a traceparent header added.

The Rack middleware gives Sinatra, Hanami, Roda, Grape and plain Rack the same request spans and error reports. ActiveRecord queries are not traced yet.

Report errors yourself

Errors
ruby
begin charge_card(order) rescue Paystack::Error => e NaijaCloud::Argus.capture_exception(e, tags: { provider: "paystack" }, extra: { order_id: order.id }) raise end NaijaCloud::Argus.capture_message("Webhook signature mismatch", level: :warning) NaijaCloud::Argus.set_user(id: current_user.id) NaijaCloud::Argus.set_tag("region", "af-west")

A user, tags and breadcrumbs set during a request or job stay with it. The same exception object is sent once, however many layers see it.

Logs

Logs
ruby
NaijaCloud::Argus.log.info("order placed", order_id: "ord_81", total: 18_500) NaijaCloud::Argus.log.error("paystack timed out", attempt: 3)

Logs are sent in batches every 5 seconds, and a line written inside a request carries its trace id. For a library that takes a ::Logger, pass NaijaCloud::Argus::Logger.new(level: :info).

Metrics

Metrics
ruby
NaijaCloud::Argus.metrics.count("orders.placed", 1, method: "card") NaijaCloud::Argus.metrics.gauge("queue.depth", jobs.size) NaijaCloud::Argus.metrics.distribution("checkout.ms", elapsed_ms, nil, "ms")

Metrics are added up in the process and sent every 10 seconds.

Traces

Traces
ruby
NaijaCloud::Argus.trace("charge card", provider: "paystack") do |span| span.set_attribute("amount", order.total) paystack.charge(order) end

A span joins the request or job it runs in, and an exception marks it failed and is re-raised. NaijaCloud::Argus.start_span("upload") gives you one to end yourself with span.finish.

Cron check-ins

Create a cron monitor in Argus first, then report runs by its slug:

Cron check-ins
ruby
NaijaCloud::Argus.monitor("nightly-invoices") do InvoiceRun.call end # or by hand: NaijaCloud::Argus.cron.check_in("nightly-invoices", :start) NaijaCloud::Argus.cron.check_in("nightly-invoices", :ok) # or :error, or an exit code

monitor reports the start, then success or failure, and re-raises your job's exception.

Feature flags

Feature flags
ruby
if NaijaCloud::Argus.flags.on?("new-checkout", current_user.id) # … end theme = NaijaCloud::Argus.flags.variant("theme", current_user.id, "light")

Answers are cached for 30 seconds per user. If Argus can't be reached within 2 seconds, or the flag doesn't exist, you get the fallback you passed.

Release and environment

init reads ARGUS_RELEASE and ARGUS_ENVIRONMENT, then SENTRY_RELEASE and SENTRY_ENVIRONMENT. Without them the environment is Rails.env on Rails and production elsewhere. Or set them in the initializer: c.release = ENV["GIT_SHA"], c.environment = "staging".

Privacy

On by default:

  • Values of keys such as password, token, secret, authorization, cookie, bvn and card become [Filtered], at any depth.
  • Card numbers, bearer tokens, JWTs and password=… pairs are filtered inside strings, including exception messages and log lines.
  • Query strings are removed from URLs in requests, breadcrumbs and spans.
  • Request bodies and cookies are never sent.
  • The user's IP address is not sent unless you set send_default_pii: true.

before_send changes an event (a Hash), or drops it when it returns nil:

config/initializers/argus.rb
ruby
NaijaCloud::Argus.init do |c| c.before_send = lambda do |event| next nil if event.dig(:exception, :values)&.last&.dig(:type) == "Rack::Timeout::RequestTimeoutException" event end end

Already on Sentry

Keep sentry-ruby. In your Sentry.init block, change the dsn line:

Sentry.init
ruby
config.dsn = 'https://<public key>@argus-in.naijacloud.com/<project id>'