OpenTelemetry::SDK.configure sets up the shared resource and tracing — instrumenting Rails, Rack, Active Record, Faraday, and Redis through use_all — and a logger provider and metric reader add the other two signals.
The application exports to an OpenTelemetry Collector, which forwards to Bronto. If you don’t run a Collector, export directly to Bronto instead — the code is identical, only two environment variables change.
The Ruby logs and metrics SDKs are newer than tracing and their APIs are still settling. Pin your gem versions and check the OpenTelemetry Ruby documentation for the release you deploy. Tracing is stable.
Prerequisites
- Ruby 3.0 or later, and Bundler
- An OTel Collector reachable from your application, with
logs,metrics, andtracespipelines forwarding to Bronto — see Connect OpenTelemetry Collector to Bronto
Install dependencies
Gemfile
Configure the environment
The exporters read their endpoint and identity from environment variables, so nothing in the code below is environment-specific./v1/logs, /v1/metrics, /v1/traces) to OTEL_EXPORTER_OTLP_ENDPOINT automatically.
Two resource attributes determine how Bronto organises your data:
http://localhost:4318 is the standard OTLP/HTTP address for a Collector on the same host. Use the address reachable from your application if the Collector runs in another container, pod, or host. No authentication is needed between the application and the Collector — the Collector holds the Bronto API key.Initialise the SDK
Load this once at startup — in Rails, asconfig/initializers/opentelemetry.rb:
otel.rb
Instrument your application
Spans and instruments come from the global providers:Logs need an explicit bridge. The official SDK does not yet ship a handler for Ruby’s standard A log emitted inside an active span picks up that span’s
Logger, so application logs are emitted through the OTel Logs API directly:trace_id and span_id from the current context. Community bridges for Rails and Sidekiq are in development — until one lands, an alternative is to write JSON logs to a file and tail them with the Collector’s filelog receiver.Verify
Run your application, then check each signal in Bronto, filtering by theservice.name you set:
- Logs — the Search page, in the dataset named after your service
- Metrics — the Metric Explorer
- Traces — the Explore Traces page
- Confirm the Collector is running and reachable at
OTEL_EXPORTER_OTLP_ENDPOINT, and that its pipelines include anotlpreceiver and the Bronto exporters. - Confirm the initialiser runs before the first span or log emission.
- The batch processors export on a background thread — keep the
at_exitshutdown so short-lived scripts flush before exit.
Direct export to Bronto
Without a Collector, the application exports straight to Bronto over OTLP/HTTP. The code inotel.rb is unchanged — point the endpoint at your Bronto region and add your API key:
See API Keys for how to create a key with ingestion permissions.
GenAI semantic conventions
If your application calls an LLM, OpenTelemetry’s GenAI semantic conventions definegen_ai.* span attributes for model, token usage, and prompt and response content.
Manual spans
Ruby has no first-party instrumentation emitting GenAI-semconv spans, so set the attributes yourself around each model call:gen_ai.input.messages / gen_ai.output.messages) is opt-in by convention and off by default in the languages that have auto-instrumentation. Since you are setting attributes by hand, apply the same discipline — gate prompt and response content behind your own config flag rather than always sending it.
See the GenAI span conventions for the full attribute list.
For the recommended attribute set and Bronto search queries, see LLM Observability.
