Created: 2008-07-23 05:36
Updated: 2018-09-05 18:35
License: other




XRay provides a lightweight yet powerful toolbox for troubleshooting Ruby applications when things stop making sense. XRay includes:

  • DTrace tooling
  • A thread dump utility that can dump the stack trace of all the threads in your Ruby VM when you send a QUIT signal.
  • GDB intrumentation to inspect C-level and Ruby level at the same time

Project Websites

GDB Instrumentation

Copy the gdb_macros file provided in the gem as your ~/.gdbinit file and you can access Ruby level and C level information at the same time! Invaluable to find tough problems on platforms where DTrace is not available. You can find more details on how to use the gdb macros, in the Troubleshooting Ruby Processes.

Thread Dump for All Threads

On any caller for all threads-enabled Ruby interpreter, you can install the XRay signal handler to dumping the stack trace for all the threads in your Ruby VM with:

require "rubygems"
require "xray/thread_dump_signal_handler"

If your Ruby interperter does not support caller_for_all_threads then you only get the stack trace of the current thread.

You can trigger a thread dump at any time with

kill -QUIT <pid of your ruby process>

For instance you were sending the QUIT signal to the following Ruby script:

#!/usr/bin/env ruby

require "rubygems"
require "xray/thread_dump_signal_handler"

a_thread =Thread.new do
  loop { sleep 1; puts "." }


You would get a thread dump like:

=============== XRay - Thread Dump ===============

#<Thread:0x255c9c sleep> alive=true priority=0
      \_ /tmp/sample.rb:7:in `loop'
      \_ /tmp/sample.rb:7
      \_ /tmp/sample.rb:6:in `initialize'
      \_ /tmp/sample.rb:6:in `new'
      \_ /tmp/sample.rb:6

#<Thread:0x22c6a8 run> [main] [current] alive=true priority=0
      \_ /tmp/sample.rb:10:in `call'
      \_ /tmp/sample.rb:10:in `join'
      \_ /tmp/sample.rb:10

=============== XRay - Done ===============

Please refer to the caller for all threads article for more details.


Collection of D scripts

Installed under /usr/bin, they all start with xray_

Out-of-the-box Rails DTrace Instrumentation

You are one require away from triggering automatically DTrace events for Rails requests, database access and template rendering. As simple as

# environment.rb
Rails::Initializer.run do |config|

  config.gem "xray"


If (like me) you like gem plugins. Or

# environment.rb
Rails::Initializer.run do |config|


  config.after_initialize do
    require "rubygems"
    require "xray/dtrace/rails/enable_tracing"

if you prefer tighter control.

You then get the following DTrace probes:

| Probe Name    | `arg0`         | `arg1`                | Semantics
--------------- | -------------- | --------------------- | ------------------------------------------
| `ruby-probe`  | request-start  | <controller>#<action> | Rails start processing a controller action
| `ruby-probe`  | request-end    | <controller>#<action> | Rails done processing a controller action
| `ruby-probe`  | render-start   | <render options>      | Rails rendering starts
| `ruby-probe`  | render-end     | <controller>#<action> | Rails done rendering
| `ruby-probe`  | db-start       | <sql query>           | Rails initiates a query to the database
| `ruby-probe`  | db-end         | <sql query>           | Rails done executing a database query

See lib/xray/dtrace/rails and the bundle D scripts for more details.

Fire Your Own Application-Specific DTrace Probes

See XRay::DTrace::Tracer for more details or look at a an example.


Philippe Hanrigou, http://ph7spot.com

Cookies help us deliver our services. By using our services, you agree to our use of cookies Learn more