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.
Install
bundle add naijacloud-argusSet up
Rails
Set the DSN where the app runs. There is no initializer to write:
ARGUS_DSN=https://<public key>@argus-in.naijacloud.com/<project id> bin/rails serverThe gem's Railtie starts Argus after your initializers. To change options, add an initializer; it runs first, so it wins:
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
endRack, Sinatra and plain Ruby
require "naijacloud/argus"
NaijaCloud::Argus.init # reads ARGUS_DSN
use NaijaCloud::Argus::Rack
run AppIn 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
bin/rails runner 'NaijaCloud::Argus.capture_message("Argus test event")'Outside Rails:
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 atraceparentheader 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_onanddiscard_onbehave as before. Rails.error(Rails 7.0 and later):Rails.error.reportandRails.error.handlereach Argus too.- Outgoing
Net::HTTPcalls (and Faraday, HTTParty and anything built on it), traced, with atraceparentheader 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
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
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
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
NaijaCloud::Argus.trace("charge card", provider: "paystack") do |span|
span.set_attribute("amount", order.total)
paystack.charge(order)
endA 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:
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 codemonitor reports the start, then success or failure, and re-raises your
job's exception.
Feature flags
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,bvnandcardbecome[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:
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
endAlready on Sentry
Keep sentry-ruby. In your Sentry.init block, change the dsn line:
config.dsn = 'https://<public key>@argus-in.naijacloud.com/<project id>'