Monitoring
Ruby SDK
Part of the `sillydev` gem on RubyGems. `require "sillydev"` does not load it: require `sillydev/monitoring` when you want it. No dependencies outside Ruby's standard library.
← Monitoring docsUpdated
Browse the docs
init
Call it once, as early as you can. Every option is optional. Without a key (as an argument or in SILLYDEV_MONITORING_KEY) it does nothing. Calling it again replaces the previous setup. Forked workers, such as Puma's and Unicorn's, start sending on their own.
runtime_metrics sends CPU, memory, garbage collection and thread counts, and the heartbeat. capture_unhandled records the exception that ends the program, without changing what Ruby does with it. sample_rate is the share of errors and events sent, from 0 to 1. before_send is called with the kind ("error", "event" or "slow") and the item, and returns the item, changed or not, or nil to drop it. debug logs every payload.
Ruby
require "sillydev/monitoring"
SillyDev::Monitoring.init(
service: "orders-bot", # default: SILLYDEV_MONITORING_SERVICE, then "default"
environment: "production", # default: SILLYDEV_MONITORING_ENVIRONMENT, then "production"
release: "1.4.2", # default: SILLYDEV_MONITORING_RELEASE
runtime_metrics: true,
capture_unhandled: true,
sample_rate: 1.0,
before_send: ->(kind, item) { kind == "event" && item["name"] == "debug" ? nil : item },
debug: false,
)Metrics
increment(name, value = 1, tags: nil) adds to a counter, gauge(name, value, tags: nil) records the latest value, and timing(name, ms, tags: nil) records a duration in milliseconds. time(name) { ... } times a block and returns its value; a block slower than a second is also kept as a slow operation.
Names are lowercase letters, digits, dots and underscores, starting with a letter. Tags are up to 8 pairs, and each name and set of tags is one series, so tag by things with few values.
Ruby
SillyDev::Monitoring.increment("orders.created", tags: { plan: "free" })
SillyDev::Monitoring.gauge("queue.length", queue.size)
SillyDev::Monitoring.timing("payment.duration", 182.5, tags: { provider: "stripe" })
report = SillyDev::Monitoring.time("reports.build") { build_report }Errors and events
capture_exception(error, tags: nil, context: nil) reports an exception; with no argument, the one being rescued. capture_message(message) reports something that is not an exception as an error. Context is shown on the issue page; values whose names look like passwords, tokens or cookies are replaced with [redacted].
event(name, attributes) records something that happened. A deploy event is marked on the Overview charts.
Ruby
begin
charge(order)
rescue PaymentError => e
SillyDev::Monitoring.capture_exception(e, tags: { provider: "stripe" }, context: { order: order.id })
end
SillyDev::Monitoring.event("deploy", { version: "1.4.2" })Heartbeats, flushing and shutting down
With runtime metrics on, every send is a heartbeat; with them off, call heartbeat yourself. The SDK sends from a background thread every ten seconds, and at exit.
flush sends everything now and returns whether it all went; shutdown flushes and stops. A short script that ends straight after its work is covered by the exit hook, but a process that ends with exit! should call flush first.
Read next