diff --git a/bin/xray_top_10_busiest_code_path_for_process.d b/bin/xray_top_10_busiest_code_path_for_process.d new file mode 100755 index 0000000..d422ebb --- /dev/null +++ b/bin/xray_top_10_busiest_code_path_for_process.d @@ -0,0 +1,12 @@ +#!/usr/sbin/dtrace -s +#pragma D option quiet +#pragma D option aggsortrev +#pragma D option dynvarsize=64m +#pragma D option ustackframes=64 +#pragma D option strsize=2048 + +profile-997 +/pid == $target/ +{ + @num[ustack()] = count(); +} \ No newline at end of file diff --git a/bin/xray_top_10_busiest_code_path_on_system.d b/bin/xray_top_10_busiest_code_path_on_system.d new file mode 100755 index 0000000..f5d5ba7 --- /dev/null +++ b/bin/xray_top_10_busiest_code_path_on_system.d @@ -0,0 +1,35 @@ +#!/usr/sbin/dtrace -s +#pragma D option quiet +#pragma D option dynvarsize=64m + +dtrace:::BEGIN +{ + printf("Tracing... Hit Ctrl-C to end.\n"); + depth = 0; +} + + +profile-997 +{ + @kernel[stack(20)]=count(); +} + + + +profile-997 +/arg1/ /* user level PC. Make sure that we are in user space */ +{ + printf("%d\n", arg1); + @userspace[execname, ustack(10)]=count(); +} + +END { + trunc(@kernel, 10); + trunc(@userspace, 10); + + printf("%s", "\n =========== Top 10 Busiest Kernel Path =============\n"); + printa(@kernel); + + printf("%s", "\n =========== Top 10 Busiest User Path =============\n"); + printa(@userspace); +} \ No newline at end of file diff --git a/bin/xray_trace_rails_response_times.d b/bin/xray_trace_rails_response_times.d index 7114e5b..7820b16 100755 --- a/bin/xray_trace_rails_response_times.d +++ b/bin/xray_trace_rails_response_times.d @@ -24,14 +24,14 @@ this string name; this string action; this string query; -dtrace:::BEGIN +dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); depth = 0; } ruby$target::ruby_dtrace_probe: -/(this->name = copyinstr(arg0)) == "request-start"/ +/(this->name = copyinstr(arg0)) == "request-start"/ { self->request_start[copyinstr(arg1)] = timestamp; } diff --git a/examples/dtrace/custom_dtrace_instumentation_using_usdt_probes.rb b/examples/dtrace/custom_dtrace_instumentation_using_usdt_probes.rb new file mode 100644 index 0000000..747e539 --- /dev/null +++ b/examples/dtrace/custom_dtrace_instumentation_using_usdt_probes.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby -w +# +# Define how you can create custom DTrace probes on the fly from +# Ruby program using the ruby-dtrace gem (USDT provider). +# +# Trace all flight search probes with: +# +# sudo dtrace -n 'find-available-flights { printf("%s", copyinstr(arg0)); }' +# +# Trace all the flight booking probes with: +# +# sudo dtrace -n 'book { printf("%s %d", copyinstr(arg0), arg1); }' +# +require 'rubygems' +gem "ruby-dtrace" +require 'dtrace/provider' + +# +# Define custom DTrace USDT probes on the fly using ruby-dtrace +# native extensions. +# + +Dtrace::Provider.create :booking_engine do |p| + p.probe :boot + p.probe :find_available_flights, :string + p.probe :book, :string, :integer +end + +# +# Use these custom probes in your application +# + + +class BookingEngine + + def find_available_flights(destination) + Dtrace::Probe::BookingEngine.find_available_flights do |p| + p.fire(destination) + end + sleep 1 # Some business logic ;-) + ["AF98", "JB24"] + end + + def book(flight_number, number_of_seats) + Dtrace::Probe::BookingEngine.book do |p| + p.fire(flight_number, number_of_seats) + end + sleep 3 # Very slow business logic + end + + def book_all_available_flights + find_available_flights("SFO").collect do |flight_number| + book flight_number, rand(10) + end + end + +end + +class Application + + def self.boot + # Fire a custom DTrace probe without a block (no start/end concept) + Dtrace::Probe::BookingEngine.boot do |p| + p.fire + end + + booking_engine = BookingEngine.new + loop do + booking_engine.book_all_available_flights + end + end + +end + +Application.boot diff --git a/examples/dtrace/simple_ruby_script.rb b/examples/dtrace/simple_ruby_script.rb new file mode 100644 index 0000000..05e57a0 --- /dev/null +++ b/examples/dtrace/simple_ruby_script.rb @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby -w +# +# Simple Ruby script simulating a flight booking engine +# before we add any custon DTrace instrumentation +# +class BookingEngine + + def find_available_flights(destination) + sleep 1 # Some business logic ;-) + ["AF98", "JB24"] + end + + def book(flight_number, number_of_seats) + sleep 3 # Very slow business logic + end + + def book_all_available_flights + book flight_number, rand(10) + end + +end + +class Application + + def self.boot + booking_engine = BookingEngine.new + loop do + booking_engine.book_all_available_flights + end + end + +end + +Application.boot diff --git a/examples/dtrace/simple_ruby_script_with_tracer_custom_dtrace_instrumentation.rb b/examples/dtrace/simple_ruby_script_with_tracer_custom_dtrace_instrumentation.rb new file mode 100755 index 0000000..99df99e --- /dev/null +++ b/examples/dtrace/simple_ruby_script_with_tracer_custom_dtrace_instrumentation.rb @@ -0,0 +1,52 @@ +#!/usr/bin/env ruby -w +# +# Simple Ruby script demonstrating use of Tracer to install custom +# (application specific) Dtrace probes. +# +# Run the script, then watch your customn probes fire in another terminal with: +# +# sudo dtrace -n'ruby-probe { printf("%s %s", copyinstr(arg0), copyinstr(arg1)); }' +# +require "rubygems" +require "xray/dtrace/tracer" + +class BookingEngine + include XRay::DTrace::Tracer + + def find_available_flights(destination) + firing "find_available_flights", destination do + sleep 1 # Some business logic ;-) + ["AF98", "JB24"] + end + end + + def book(flight_number) + firing "book", flight_number do + sleep 3 # Very slow business logic + end + end + + def book_all_available_flights + find_available_flights("SFO").collect do |flight_number| + book flight_number + end + end + +end + +class Application + extend DTracer + + def self.boot + # Fire a custom DTrace probe without a block (no start/end concept) + fire "boot", Process.pid.to_s + + booking_engine = BookingEngine.new + loop do + booking_engine.book_all_available_flights + end + end + +end + +Application.boot