DEV Community

Dmitry Daw
Dmitry Daw

Posted on

How to use rbtrace from outside of docker container

Rbtrace is a great tool to see which functions your app is calling at the time.

In most cases you want it to be installed inside a docker container, but sometimes you can't.

In this cases, you could run it from outside, but you need to share several things with the host:

  1. IPC(Inter-process communication) namespace. Rbtrace is using IPC to connect his inside app process with the outside tracer.
  2. PID namespace. Rbtrace is sending signals to PID, so you should be able to send these.
  3. The /tmp folder. Rbtrace creates sockets to connect with process, like /tmp/rbtrace-1688246.sock.

So, you can setup your app like this:

Inside the app

docker-compose.yml

  app:
    # ...
    ipc: host
    pid: host
    volumes:
      - /tmp/:/tmp
      # ...
Enter fullscreen mode Exit fullscreen mode

Gemfile

gem 'rbtrace'
Enter fullscreen mode Exit fullscreen mode

Outside the app

# run as root
$ rbtrace -p 1688246 --firehose
Enter fullscreen mode Exit fullscreen mode

where 1688246 - is PID of the process you want to trace.
And voila! You could get your nice and shiny traces, e.g.

Kernel#public_send                                      
  Puma::ThreadPool#reap                                    
    Thread::Mutex#synchronize                                  
      Array#reject                                      
        Thread#alive? <0.000002>                                  
        Thread#alive? <0.000001>                              
        Thread#alive? <0.000001>                                 
        Thread#alive? <0.000001>                                  
        Thread#alive? <0.000002>                               
      Array#reject <0.000020>                                  
      Array#each <0.000002>
      Array#delete_if
        Array#include? <0.000002>
        Array#include? <0.000001>
        Array#include? <0.000001>
        Array#include? <0.000001>
        Array#include? <0.000002>
      Array#delete_if <0.000019>
    Thread::Mutex#synchronize <0.000053> 
  Puma::ThreadPool#reap <0.000058>
Kernel#public_send <0.000067>
Enter fullscreen mode Exit fullscreen mode

Another great parameter for rbtrace is --slow, which shows only methods that took more than N ms.

rbtrace -p 1746688 --slow=500 > trace.slow.log
Enter fullscreen mode Exit fullscreen mode

NOTE: rbtrace uses PID in three ways - as PID to send signals, as a key for IPC message queue, and as a prefix for the socket file.

Links:

  1. rbtrace
  2. usage as pid
  3. usage as IPC key
  4. usage as socket path

Top comments (0)