Backend Setup: Ruby
This guide walks you through instrumenting a Ruby application with the SF Veritas SDK. Ruby instrumentation captures logs, print statements, exceptions, HTTP request/response telemetry, and function execution spans.
Installation
Add the Gem Source
First, add the Sailfish gem repository:
gem sources -a https://ruby-gemrepo.sailfishqa.com/
Bundler (Recommended)
Add sf-veritas to your Gemfile:
# Gemfile
gem 'sf-veritas', group: :development
Then install:
bundle install
Direct Install
gem install sf-veritas
Basic Setup
Add the following to your application's entry point. Use an environment variable check so instrumentation only runs during local development:
You must set the SF_DEV=true environment variable when running your app locally. This is how SF Veritas knows to activate. Add it as a prefix to your run command:
SF_DEV=true rails server
SF_DEV=true bundle exec rackup
SF_DEV=true ruby app.rb
# At the top of your application entry point
if ENV['SF_DEV'] == 'true'
require 'sf_veritas'
SfVeritas.setup_interceptors(
api_key: 'sf-veritas-local',
api_graphql_endpoint: 'http://localhost:6776/graphql/',
service_identifier: 'my-ruby-service',
service_version: '1.0.0'
)
end
# Your application code continues below...
Using a .env File
Instead of prefixing every command, create a .env file in your project root:
# .env
SF_DEV=true
Then load it in your application using the dotenv gem:
gem install dotenv
require 'dotenv/load' # Loads .env file
if ENV['SF_DEV'] == 'true'
require 'sf_veritas'
SfVeritas.setup_interceptors(
api_key: 'sf-veritas-local',
api_graphql_endpoint: 'http://localhost:6776/graphql/',
service_identifier: 'my-ruby-service'
)
end
Add .env to your .gitignore to avoid committing development settings. Create a .env.example file for reference:
# .env.example
SF_DEV=true
Configuration Options
| Option | Type | Required | Description |
|---|---|---|---|
api_key | String | Yes | Use "sf-veritas-local" for local development |
api_graphql_endpoint | String | Yes | URL of the local collector (default port 6776) |
service_identifier | String | Yes | Unique name for your service |
service_version | String | No | Version of your service |
service_display_name | String | No | Display name in the UI |
git_sha | String | No | Git commit SHA (auto-detected) |
git_org | String | No | Git organization (auto-detected) |
git_repo | String | No | Git repository name (auto-detected) |
git_provider | String | No | Git provider (auto-detected) |
sf_debug | Boolean | No | Enable debug logging to stderr |
domains_to_not_propagate_headers_to | Array | No | Domains to skip header propagation |
routes_to_skip_network_hops | Array | No | Routes to skip inbound tracing |
What Gets Captured Automatically
Once setup_interceptors is called, these are captured with zero additional code:
- Structured logs — All Ruby
Loggeroutput - Print statements — All
$stdout/putsoutput - Exceptions — Unhandled exceptions with full stack traces
- Outbound HTTP requests — Via
Net::HTTP(automatic monkey-patch) - Inbound HTTP requests — Via Rack middleware (auto-installed in Rails, manual in Sinatra)
Framework Examples
Ruby on Rails
Rails integration is automatic via a Railtie. When the sf-veritas gem is loaded, the Rack middleware is auto-installed — no extra configuration needed.
Add to your config/environments/development.rb or config/initializers/sf_veritas.rb:
# config/initializers/sf_veritas.rb
if ENV['SF_DEV'] == 'true'
require 'sf_veritas'
SfVeritas.setup_interceptors(
api_key: 'sf-veritas-local',
api_graphql_endpoint: 'http://localhost:6776/graphql/',
service_identifier: 'rails-api',
service_version: '1.0.0'
)
end
Then start Rails with:
SF_DEV=true rails server
The Rack middleware for inbound request tracking is automatically inserted via a Rails Railtie. You don't need to add config.middleware.use manually.
Sinatra
For Sinatra, require the gem and add the middleware manually:
# app.rb
require 'sinatra'
if ENV['SF_DEV'] == 'true'
require 'sf_veritas'
SfVeritas.setup_interceptors(
api_key: 'sf-veritas-local',
api_graphql_endpoint: 'http://localhost:6776/graphql/',
service_identifier: 'sinatra-api',
service_version: '1.0.0'
)
use SfVeritas::Middleware
end
get '/api/users' do
puts 'Fetching users' # This will appear in SF Veritas Console
{ users: [] }.to_json
end
# Run with: SF_DEV=true ruby app.rb
Generic Rack
For any Rack-compatible application:
# config.ru
if ENV['SF_DEV'] == 'true'
require 'sf_veritas'
SfVeritas.setup_interceptors(
api_key: 'sf-veritas-local',
api_graphql_endpoint: 'http://localhost:6776/graphql/',
service_identifier: 'rack-app'
)
use SfVeritas::Middleware
end
run MyApp
Function Tracing
Manual Spans
Use SfVeritas.start_span for manual control over which functions appear in the Flamechart:
def process_order(order_id)
span = SfVeritas.start_span('OrderService#process_order',
arguments: { order_id: order_id }.to_json
)
begin
result = do_work(order_id)
span.finish(result)
result
rescue => e
span.finish(nil, error: e)
raise
end
end
Block Tracing
Use SfVeritas.trace for a cleaner block-based syntax that automatically handles finish and errors:
def process_order(order_id)
SfVeritas.trace('OrderService#process_order',
arguments: { order_id: order_id }.to_json
) do
do_work(order_id)
end
end
Automatic Function Capture (TracePoint)
For full automatic function tracing, set the SF_FUNCSPAN_AUTO_CAPTURE environment variable. This uses Ruby's TracePoint API to intercept all method calls in your application code:
SF_DEV=true SF_FUNCSPAN_AUTO_CAPTURE=true rails server
Auto-capture only instruments your application code — it automatically skips gems, stdlib, and SF Veritas internals.
User Identification
SfVeritas.identify('user-123', { email: 'user@example.com', name: 'Jane Doe', plan: 'enterprise' })
Exception Reporting
Exceptions are captured automatically, but you can also report them manually:
begin
risky_operation
rescue => e
SfVeritas::ExceptionHandler.report(e)
# Handle or re-raise
end
Environment Variables
| Variable | Default | Description |
|---|---|---|
SF_DEBUG | false | Enable debug logging to stderr |
SF_LOG_IGNORE_REGEX | — | Regex to suppress matching log messages |
SF_FUNCSPAN_AUTO_CAPTURE | false | Enable automatic function span capture via TracePoint |
SF_FUNCSPAN_CAPTURE_ARGUMENTS | false | Capture function arguments |
SF_FUNCSPAN_CAPTURE_RETURN_VALUE | false | Capture return values |
SF_FUNCSPAN_ARG_LIMIT_MB | 1 | Max argument capture size in MB |
SF_FUNCSPAN_RETURN_LIMIT_MB | 1 | Max return value capture size in MB |
SF_FUNCSPAN_ENABLE_SAMPLING | false | Enable span sampling |
SF_FUNCSPAN_SAMPLE_RATE | 1.0 | Function span sampling rate (0.0 to 1.0) |
SF_FUNCSPAN_AUTOCAPTURE_ALL_CHILD_FUNCTIONS | true | Auto-capture all child function calls |
SF_NETWORKHOP_CAPTURE_REQUEST_HEADERS | false | Capture HTTP request headers |
SF_NETWORKHOP_CAPTURE_REQUEST_BODY | false | Capture HTTP request bodies |
SF_NETWORKHOP_CAPTURE_RESPONSE_HEADERS | false | Capture HTTP response headers |
SF_NETWORKHOP_CAPTURE_RESPONSE_BODY | false | Capture HTTP response bodies |
SF_NETWORKHOP_REQUEST_LIMIT_MB | 1 | Max request body capture size in MB |
SF_NETWORKHOP_RESPONSE_LIMIT_MB | 1 | Max response body capture size in MB |
SF_DISABLE_INBOUND_NETWORK_TRACING_ON_ROUTES | — | Comma-separated routes to skip inbound tracing |
SF_DISABLE_PRINT_CAPTURE | false | Disable stdout capture |
Configuration File
Create a .sailfish file in your project root for per-file and per-function span configuration. Supports JSON, TOML, and YAML formats.
JSON
{
"funcspan": {
"default": {
"capture_arguments": true,
"capture_return_value": true,
"sample_rate": 1.0
},
"files": {
"app/models/*.rb": {
"capture_arguments": false
}
},
"functions": {
"User#save": {
"capture_arguments": true,
"capture_return_value": true,
"arg_limit_mb": 2
},
"HealthCheck#ping": {
"sample_rate": 0.0
}
}
}
}
TOML
[funcspan.default]
capture_arguments = true
capture_return_value = true
sample_rate = 1.0
[funcspan.files."app/models/*.rb"]
capture_arguments = false
[funcspan.functions."User#save"]
capture_arguments = true
capture_return_value = true
arg_limit_mb = 2
Inline Pragma
You can also add per-file configuration directly in your Ruby source files using a comment pragma in the first 50 lines:
# frozen_string_literal: true
# sailfish-funcspan: capture_arguments=true capture_return_value=false
class UsersController < ApplicationController
# ...
end
Configuration Priority
Settings are resolved in this order (highest priority first):
- Function-level —
.sailfishconfigfunctionssection - Inline pragma —
# sailfish-funcspan:comment in source file - File-level —
.sailfishconfigfilessection (glob matching) - Default —
.sailfishconfigdefaultsection - Environment variables —
SF_FUNCSPAN_*variables
Configuration Options
| Option | Type | Description |
|---|---|---|
capture_arguments | bool | Capture function arguments |
capture_return_value | bool | Capture return values |
arg_limit_mb | int | Max argument size in MB |
return_limit_mb | int | Max return value size in MB |
sample_rate | float | Sampling rate (0.0 to 1.0) |
enable_sampling | bool | Enable span sampling |
autocapture_all_children | bool | Auto-capture child function calls |
capture_sf_veritas | bool | Master kill switch for span capture |
parse_json_strings | bool | Parse JSON string arguments into structured data |
Verifying the Setup
- Start your application with
SF_DEV=true:- Rails:
SF_DEV=true rails server - Sinatra:
SF_DEV=true ruby app.rb - Rack:
SF_DEV=true bundle exec rackup
- Rails:
- Open the SF Veritas Desktop App
- Open the Console panel — you should see logs and print statements
- Trigger some HTTP requests — you should see them in the Network panel
- If using auto-capture or manual spans, open the Flamechart to see function traces
Debug Mode
Enable debug output to verify instrumentation is working:
SF_DEV=true SF_DEBUG=true rails server
You'll see output like:
[sf-veritas] Configuration: {...}
[sf-veritas] Initialized successfully (v0.1.0)
Troubleshooting
No logs appearing
- Check the desktop app: Ensure the SF Veritas Desktop App is running
- Verify the endpoint: Ensure
api_graphql_endpointmatches your server port - Check
SF_DEV: Must be set to"true" - Check terminal output: Look for
[sf-veritas]initialization messages
Connection refused errors
- Verify the SF Veritas Desktop App is installed and running
- Check that the local server is running (look for server status in the Desktop App)
- Ensure port 6776 is not blocked by a firewall
Gem not found
- Ensure the Sailfish gem source is added:
gem sources -lshould includehttps://ruby-gemrepo.sailfishqa.com/ - Re-add if missing:
gem sources -a https://ruby-gemrepo.sailfishqa.com/ - Run
bundle installagain if using Bundler - Verify Ruby 2.6+ is installed:
ruby --version
No function spans in Flamechart
- Ensure
SF_FUNCSPAN_AUTO_CAPTURE=trueis set (for automatic capture) - Or verify you're using
SfVeritas.start_span/SfVeritas.tracein your code (for manual capture) - Check that
SF_FUNCSPAN_CAPTURE_ARGUMENTSis not disabled if you expect argument capture
Multi-Service Setup
When running multiple Ruby services locally, give each a unique service_identifier:
# user-service/config/initializers/sf_veritas.rb
if ENV['SF_DEV'] == 'true'
require 'sf_veritas'
SfVeritas.setup_interceptors(
api_key: 'sf-veritas-local',
api_graphql_endpoint: 'http://localhost:6776/graphql/',
service_identifier: 'user-service',
service_version: '1.0.0'
)
end
# order-service/config/initializers/sf_veritas.rb
if ENV['SF_DEV'] == 'true'
require 'sf_veritas'
SfVeritas.setup_interceptors(
api_key: 'sf-veritas-local',
api_graphql_endpoint: 'http://localhost:6776/graphql/',
service_identifier: 'order-service',
service_version: '1.0.0'
)
end
Use the service filter in the Console to switch between services.