How to Track the Execution Process of Ruby Program

How to track the execution process of ruby program

I think you can use the Ruby's stdlib Tracer.

I wrote a code in my test.rb file :

require 'tracer'

Tracer.on

class A
def square(a)
@b = a*a
result
end
def result
@b
end
end

a = A.new
puts a.square(5)

Tracer.off

Now run the code, and see all what's going on under the hood :

(arup~>Ruby)$ ruby test.rb
#0:test.rb:5::-: class A
#0:test.rb:5::C: class A
#0:test.rb:6::-: def square(a)
#0:test.rb:10::-: def result
#0:test.rb:13::E: end
#0:test.rb:15::-: a = A.new
#0:test.rb:16::-: puts a.square(5)
#0:test.rb:6:A:>: def square(a)
#0:test.rb:7:A:-: @b = a*a
#0:test.rb:8:A:-: result
#0:test.rb:10:A:>: def result
#0:test.rb:11:A:-: @b
#0:test.rb:12:A:<: end
#0:test.rb:9:A:<: end
25
#0:test.rb:18::-: Tracer.off
(arup~>Ruby)$

Again look at the code. Now I changed trace point.

require 'tracer'

class A
def square(a)
@b = a*a
result
end
def result
@b
end
end

Tracer.on

a = A.new
puts a.square(5)

Tracer.off

Now run the code, and see all what's going on under the hood :

(arup~>Ruby)$ ruby test.rb
#0:test.rb:15::-: a = A.new
#0:test.rb:16::-: puts a.square(5)
#0:test.rb:4:A:>: def square(a)
#0:test.rb:5:A:-: @b = a*a
#0:test.rb:6:A:-: result
#0:test.rb:8:A:>: def result
#0:test.rb:9:A:-: @b
#0:test.rb:10:A:<: end
#0:test.rb:7:A:<: end
25
#0:test.rb:18::-: Tracer.off
(arup~>Ruby)$

print ruby code during execution

As pointed out by Arup, this is a dupe.

Ruby's Tracer class fits my needs.

How do I log every method that's called in a Ruby program?

This is definitely possible -- in fact, there's even a method for it! Just add this somewhere in your code before the point that you want to start logging things:

set_trace_func proc { |event, file, line, id, binding, classname|
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}

The secret sauce you want comes from Kernel#set_trace_func, as noted above:

  • set_trace_func(proc) => proc
  • set_trace_func(nil) => nil

Establishes proc as the handler for tracing, or disables tracing if the parameter is nil. proc takes up to six parameters: an event name, a filename, a line number, an object id, a binding, and the name of a class. proc is invoked whenever an event occurs. Events are: c-call (call a C-language routine), c-return (return from a C-language routine), call (call a Ruby method), class (start a class or module definition), end (finish a class or module definition), line (execute code on a new line), raise (raise an exception), and return (return from a Ruby method). Tracing is disabled within the context of proc.

Here's a handy example:

class Test
def test
a = 1
b = 2
end
end

set_trace_func proc { |event, file, line, id, binding, classname|
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
}

t = Test.new
t.test

(Note: don't try this in irb unless you want a huge scrolling screen of text.) The resulting output is:

    line test.rb:11               false
c-call test.rb:11 new Class
c-call test.rb:11 initialize Object
c-return test.rb:11 initialize Object
c-return test.rb:11 new Class
line test.rb:12 false
call test.rb:2 test Test
line test.rb:3 test Test
line test.rb:4 test Test
return test.rb:4 test Test

You can play around with the formatting string above to get just the results you want to log (for example, it sounds like you're only interested in call events). Hope that helps, and good luck with sorting through all those unit tests!

Find the Run Time of Select Ruby Code

Ruby has the Benchmark module for timing how long things take. I've never used this outside of seeing if a method is taking too long to run, etc. in development, not sure if this is 'recommended' for production code or for keeping things above a minimum runtime (as it sounds like you might be doing), but take a look and see how it feels for your use case.

It also sounds like you might be interested in the Timeout module as well (for making sure things don't take longer than a set amount of time).

If you really have a use case for making sure something takes a minimum amount of time, timing the code (either using a Benchmark method or just Time or another solution) and then sleep the difference is the only thing that comes to mind.

ruby restart script automatically once it ends execution

I have a ruby daemon running on my server and for some mysterious reasons it crashes some times. I wrapped it into a while true loop and print me some timestamps to stdout, like that:

#!/bin/bash
while true; do
echo $(date +%Y%m%d%H%M%S) "Starting my custom ruby daemon..."
ruby /home/user/my/custom/ruby/daemon.rb
echo $(date +%Y%m%d%H%M%S) "My custom ruby daemon crashed. Respawning in 10 sec..."
sleep 10
done

That works well. Putting a sleep into it is highly recommended, in case something goes wrong the loop wont blow up your shell.

Run a command in current terminal in ruby then execute code when it exits

Thanks a lot to hek2mgl for pointing in the right direction:

include Signal
include Process

# Handling SIGINT by doing nothing prevents default behaviour
# (killing both processes)
Signal.trap("INT") {}

# Fork off subprocess (so exec won't exit from your main process)
pid = fork
if pid == nil then
# Child code. Use exec(!) to avoid the signal handler
# getting called in the child.
exec 'heroku run console'
else
# Wait for subprocess to exit
wait pid
# "wait" sets the $? according to the subprocess exit status
exit_status = $?.exitstatus

p "Execute more ruby code"
exit exit_status
end


Related Topics



Leave a reply



Submit