Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merging with Rubyforge's svn

git-svn-id: svn+ssh://rubyforge.org/var/svn/xray@32 5dde6e04-f255-48cb-b2b1-8039b2f1cec5
  • Loading branch information...
commit 2f8deca89bd2bf6ea610f443565867fe4d1656fb 1 parent f384c5b
authored November 16, 2008
30  bin/install_dtrace_on_ubuntu
... ...
@@ -0,0 +1,30 @@
  1
+#!/usr/bin/env bash
  2
+#
  3
+# Painless DTrace install for Ubuntu
  4
+#
  5
+
  6
+DISTRIBUTION=dtrace-20081028
  7
+
  8
+download()
  9
+{
  10
+    sudo apt-get install curl
  11
+    if [ ! -e ${DISTRIBUTION} ]; then
  12
+        echo "\n==== Downloading DTrace for Linux ====\n"
  13
+        curl -O ftp://crisp.dynalias.com/pub/release/website/dtrace/${DISTRIBUTION}.tar.bz2
  14
+        tar jxvf ${DISTRIBUTION}.tar.bz2
  15
+    fi
  16
+}
  17
+
  18
+install_dependencies()
  19
+{
  20
+    sudo apt-get install zlib1g-dev flex bison elfutils libelf-dev libc6-dev linux-libc-dev
  21
+}
  22
+
  23
+build()
  24
+{
  25
+    make -C ${DISTRIBUTION} clean all
  26
+}
  27
+
  28
+download
  29
+install_dependencies
  30
+build
54  bin/xray_profile_ruby_function_calls.d
... ...
@@ -0,0 +1,54 @@
  1
+#!/usr/sbin/dtrace -s 
  2
+#pragma D option quiet
  3
+#pragma D option aggsortrev
  4
+#pragma D option dynvarsize=64m
  5
+
  6
+/* 
  7
+ * Trace all ruby function calls and display their total time, average time
  8
+ * an invocation number (slower first).
  9
+ *
  10
+ * Usage:
  11
+ *
  12
+ *     sudo /usr/bin/xray_profile_ruby_function_calls.d -p <a pid>
  13
+ *
  14
+ *     sudo /usr/bin/xray_profile_ruby_function_calls.d -c "ruby -v"
  15
+ *
  16
+ *     sudo dtrace -s /usr/bin/xray_profile_ruby_function_calls.d -p <a pid>
  17
+ */
  18
+ 
  19
+this string str;
  20
+
  21
+dtrace:::BEGIN
  22
+{
  23
+   printf("Tracing, please be patient... Ctrl-C to interrupt.\n");
  24
+   depth = 0;
  25
+}
  26
+
  27
+ruby$target:::function-entry
  28
+{
  29
+   self->depth++;
  30
+   self->start[copyinstr(arg0), copyinstr(arg1), self->depth] = timestamp;
  31
+}
  32
+
  33
+ruby$target:::function-return
  34
+/(this->class = copyinstr(arg0)) != NULL && \
  35
+ (this->func  = copyinstr(arg1)) != NULL && \
  36
+ self->start[this->class, this->func, self->depth]/
  37
+{
  38
+    this->elapsed = timestamp - self->start[this->class, this->func, self->depth];
  39
+    @num[this->class, this->func] = count();
  40
+    @eavg[this->class, this->func] = avg(this->elapsed);
  41
+    @esum[this->class, this->func] = sum(this->elapsed);
  42
+    self->start[this->class, this->func, self->depth] = 0;
  43
+    self->depth--;
  44
+}
  45
+
  46
+dtrace:::END
  47
+{
  48
+    normalize(@eavg, 1000);
  49
+    normalize(@esum, 1000);
  50
+    setopt("aggsortpos", "0");   /* Sort on total time */
  51
+    printf("%95s\n", "_______ ELAPSED ______");
  52
+    printf("%-40s %-30s %12s %10s %6s\n", "Class", "Method", "Total (us)", "Avg (us)", "Count\n");
  53
+    printa("%-40.40s %-30.30s %@12d %@10d %@6d\n", @esum, @eavg, @num);
  54
+}
12  bin/xray_top_10_busiest_code_path_for_process.d
... ...
@@ -0,0 +1,12 @@
  1
+#!/usr/sbin/dtrace -s
  2
+#pragma D option quiet
  3
+#pragma D option aggsortrev
  4
+#pragma D option dynvarsize=64m
  5
+#pragma D option ustackframes=64
  6
+#pragma D option strsize=2048
  7
+
  8
+profile-997
  9
+/pid == $target/ 
  10
+{ 
  11
+    @num[ustack()] = count(); 
  12
+}
35  bin/xray_top_10_busiest_code_path_on_system.d
... ...
@@ -0,0 +1,35 @@
  1
+#!/usr/sbin/dtrace -s
  2
+#pragma D option quiet
  3
+#pragma D option dynvarsize=64m
  4
+
  5
+dtrace:::BEGIN 
  6
+{
  7
+    printf("Tracing... Hit Ctrl-C to end.\n");
  8
+    depth = 0;
  9
+}
  10
+
  11
+
  12
+profile-997 
  13
+{
  14
+    @kernel[stack(20)]=count();
  15
+}
  16
+
  17
+
  18
+
  19
+profile-997 
  20
+/arg1/       /* user level PC. Make sure that we are in user space */
  21
+{
  22
+    printf("%d\n", arg1);
  23
+    @userspace[execname, ustack(10)]=count();
  24
+}
  25
+
  26
+END {
  27
+    trunc(@kernel, 10);
  28
+    trunc(@userspace, 10); 
  29
+    
  30
+    printf("%s", "\n =========== Top 10 Busiest Kernel Path =============\n");
  31
+    printa(@kernel);
  32
+    
  33
+     printf("%s", "\n =========== Top 10 Busiest User Path =============\n");
  34
+     printa(@userspace);
  35
+}
25  bin/xray_trace_all_custom_ruby_probes.d
... ...
@@ -0,0 +1,25 @@
  1
+#!/usr/sbin/dtrace -s 
  2
+#pragma D option quiet
  3
+
  4
+/*
  5
+ * Trace all the custom ruby probes defined in your application
  6
+ * using XRay::DTrace, Apple's DTracer or Joyent's Tracer module.
  7
+ *
  8
+ * Usage:
  9
+ *
  10
+ *     sudo /usr/bin/xray_trace_all_custom_ruby_probes.d -p <a pid>
  11
+ *
  12
+ *     sudo /usr/bin/xray_trace_all_custom_ruby_probes.d -c "ruby -v"
  13
+ *
  14
+ *     sudo dtrace -s /usr/bin/xray_trace_all_custom_ruby_probes.d -p <a pid>
  15
+ */
  16
+
  17
+dtrace:::BEGIN
  18
+{
  19
+    printf("Tracing... Hit Ctrl-C to end.\n");
  20
+}
  21
+
  22
+ruby$target:::ruby-probe
  23
+{
  24
+	printf("=> %d == cpu: %2d == %15s '%s'\n", timestamp, cpu, copyinstr(arg0), copyinstr(arg1))
  25
+}
20  bin/xray_trace_all_ruby_probes.d
... ...
@@ -0,0 +1,20 @@
  1
+#!/usr/sbin/dtrace -s 
  2
+#pragma D option quiet
  3
+#pragma D option dynvarsize=64m
  4
+
  5
+/*
  6
+ * Trace all the probes of the ruby provider
  7
+ *
  8
+ * Usage:
  9
+ *
  10
+ *     sudo /usr/bin/xray_trace_all_ruby_probes.d -p <a pid>
  11
+ *
  12
+ *     sudo /usr/bin/xray_trace_all_ruby_probes.d -c "ruby -v"
  13
+ *
  14
+ *     sudo dtrace -s /usr/bin/xray_trace_all_ruby_probes.d -p <a pid>
  15
+ */
  16
+
  17
+ruby$target::: 
  18
+{ 
  19
+    printf("=> cpu %2d == %-15.15s == %-15.15s == %s\n", cpu, probename, copyinstr(arg0), copyinstr(arg1)) 
  20
+}
20  bin/xray_trace_memcached.d
... ...
@@ -0,0 +1,20 @@
  1
+#!/usr/sbin/dtrace -s
  2
+#pragma D option quiet
  3
+#pragma D option dynvarsize=64m
  4
+
  5
+
  6
+pid*:memcached:*do_item_update*:entry { 
  7
+    printf("COMMAND == %s \n", probefunc);
  8
+}
  9
+
  10
+pid*:memcached:process_get_command:entry { 
  11
+    self->conn_id = arg0;
  12
+/*    self->pointer_to_string = copyin(arg1, 4); */
  13
+    printf("GET == connection %d == update %p %d\n", arg0, arg1, arg2);
  14
+}
  15
+
  16
+pid*:memcached:process_update_command:entry { 
  17
+    self->conn_id = arg0;
  18
+/*    self->pointer_to_string = copyin(arg1, 4); */
  19
+    printf("UPDATE == connection %d == update %p %d\n", arg0, arg1, arg2);
  20
+}
30  bin/xray_trace_mysql.d
... ...
@@ -0,0 +1,30 @@
  1
+#!/usr/sbin/dtrace -s
  2
+#pragma D option quiet
  3
+#pragma D option dynvarsize=64m
  4
+
  5
+
  6
+/*
  7
+ * Inspired by Joyent's http://www.joyeur.com/2007/10/03/using-dtrace-on-mysql
  8
+ */
  9
+ 
  10
+/*
  11
+ * MySQL query parsing (captures all incoming queries)
  12
+ */
  13
+ 
  14
+ /* TODO For example we can see what queries are executed the most: => Top 10 queries */
  15
+pid*::*mysql*:entry
  16
+{
  17
+    printf("%Y %s\n", walltimestamp, copyinstr(arg1));
  18
+}
  19
+
  20
+
  21
+/*
  22
+ * Now lets say we want to find out how long a query took to execute. 
  23
+ * The function mysql_execute_command does the actual execution of 
  24
+ * the queries so all we do here is subtract the entry and return 
  25
+ * timestamps of this function.
  26
+ */
  27
+pid*:mysqld:*mysql_execute_command*:entry
  28
+{
  29
+    printf("OK");
  30
+}
114  bin/xray_trace_rails_response_times.d
... ...
@@ -0,0 +1,114 @@
  1
+#!/usr/sbin/dtrace -s
  2
+#pragma D option quiet
  3
+#pragma D option aggsortrev
  4
+#pragma D option dynvarsize=64m
  5
+
  6
+/*
  7
+ * Trace Rails controller actions and database response times.
  8
+ * 
  9
+ * Report average response time, total elapsed time and invocation count
  10
+ * for all controller actions and datase queries.
  11
+ *
  12
+ * Also print response time distribution diagrams for global and individual
  13
+ * action / query.
  14
+ *
  15
+ * Usage:
  16
+ *
  17
+ *     sudo /usr/bin/xray_trace_rails_response_times.d -p <a pid>
  18
+ *
  19
+ *     sudo /usr/bin/xray_trace_rails_response_times.d -c "ruby -v"
  20
+ *
  21
+ *     sudo dtrace -s /usr/bin/xray_trace_rails_response_times.d -p <a pid>
  22
+ */ 
  23
+this string name;
  24
+this string action;
  25
+this string query;
  26
+
  27
+dtrace:::BEGIN 
  28
+{
  29
+    printf("Tracing... Hit Ctrl-C to end.\n");
  30
+    depth = 0;
  31
+}
  32
+
  33
+ruby$target::ruby_dtrace_probe:
  34
+/(this->name = copyinstr(arg0)) == "request-start"/ 
  35
+{
  36
+    self->request_start[copyinstr(arg1)] = timestamp;
  37
+}
  38
+
  39
+
  40
+ruby$target::ruby_dtrace_probe:
  41
+/(this->name = copyinstr(arg0)) == "request-end" && self->request_start[(this->action = copyinstr(arg1))]/ 
  42
+{	
  43
+    this->elapsed = timestamp - self->request_start[this->action];
  44
+    @re_count[this->action] = count();
  45
+    @re_eavg[this->action] = avg(this->elapsed);
  46
+    @re_esum[this->action] = sum(this->elapsed);
  47
+    @re_edist[this->action] = quantize(this->elapsed);
  48
+    @re_all_edist["All Requests"] = quantize(this->elapsed);
  49
+    self->request_start[this->action] = 0;
  50
+}
  51
+
  52
+ruby$target::ruby_dtrace_probe:
  53
+/(this->name = copyinstr(arg0)) == "db-start"/
  54
+{
  55
+    self->db_start[copyinstr(arg1)] = timestamp;
  56
+}
  57
+
  58
+
  59
+ruby$target::ruby_dtrace_probe:
  60
+/(this->name = copyinstr(arg0)) == "db-end" && self->db_start[(this->query = copyinstr(arg1))]/ 
  61
+{	
  62
+    @db_count[this->query] = count();
  63
+    this->elapsed = timestamp - self->db_start[this->query];
  64
+    @db_eavg[this->query] = avg(this->elapsed);
  65
+    @db_esum[this->query] = sum(this->elapsed);
  66
+    @db_edist[this->query] = quantize(this->elapsed);
  67
+    @db_all_edist["All Queries"] = quantize(this->elapsed);
  68
+    self->db_start[this->query] = 0;
  69
+}
  70
+
  71
+dtrace:::END
  72
+{
  73
+    normalize(@re_eavg, 1000);
  74
+    normalize(@re_esum, 1000); 
  75
+    normalize(@db_eavg, 1000);
  76
+    normalize(@db_esum, 1000);
  77
+
  78
+    printf("\n================================================\n");
  79
+    printf("        Controller Response Times\n");
  80
+    printf("================================================\n\n");
  81
+
  82
+    setopt("aggsortpos", "0");   /* Sort on avg time */
  83
+    printf("%-50s %s\n", " _________ Action _________", "_ Avg. (us) _  Total (us) _ Count _\n");
  84
+    printa("%-50.50s %@12d %@12d %@6d\n", @re_eavg, @re_esum, @re_count);
  85
+    
  86
+
  87
+    printf("\n================================================\n");
  88
+    printf("        Database Response Times\n");
  89
+    printf("================================================\n");
  90
+
  91
+    setopt("aggsortpos", "0");   /* Sort on avg time */
  92
+    printf("%-100s %s\n", " _________ Query _________", "_ Avg. (us) _  Total (us) _ Count _\n");
  93
+    printa("%-100.100s %@12d %@12d %@6d\n", @db_eavg, @db_esum, @db_count);
  94
+
  95
+    printf("\n================================================\n");
  96
+    printf("        Response Time Summary\n");
  97
+    printf("================================================\n\n");
  98
+    
  99
+    printa(@re_all_edist);
  100
+    printa(@db_all_edist);
  101
+
  102
+    printf("\n================================================\n");
  103
+    printf("        Controller Response Time Distribution\n");
  104
+    printf("================================================\n\n");
  105
+    
  106
+    printa(@re_edist);
  107
+
  108
+    printf("\n================================================\n");
  109
+    printf("        DB Response Time Distribution\n");
  110
+    printf("================================================\n\n");
  111
+    
  112
+    printa(@db_edist);    
  113
+}
  114
+
78  examples/dtrace/custom_dtrace_instumentation_with_ruby_dtrace.rb
... ...
@@ -0,0 +1,78 @@
  1
+#!/usr/bin/env ruby -w
  2
+#
  3
+# Define how you can create custom DTrace probes on the fly from
  4
+# Ruby program using the ruby-dtrace gem (USDT provider).
  5
+#
  6
+# Trace all flight search probes with:
  7
+#
  8
+#     sudo dtrace -n 'find-available-flights { printf("%s", copyinstr(arg0)); }'
  9
+#
  10
+# Trace all the flight booking probes with:
  11
+#
  12
+#     sudo dtrace -n 'book { printf("%s %d", copyinstr(arg0), arg1); }'
  13
+#
  14
+# sudo dtrace -n 'book-start { printf("%s %d", copyinstr(arg0), arg1); } book-end { printf("%s %d", copyinstr(arg0), arg1); } find-available-flights-start { printf("%s", copyinstr(arg0)); } '
  15
+
  16
+require 'rubygems'
  17
+gem "ruby-dtrace"
  18
+require 'dtrace/provider'
  19
+require File.dirname(__FILE__) + '/../../lib/xray/dtrace/usdt/provider_extensions'
  20
+
  21
+#
  22
+# Define custom DTrace USDT probes on the fly using ruby-dtrace
  23
+# native extensions.
  24
+# 
  25
+
  26
+Dtrace::Provider.create :booking_engine do |p|
  27
+  p.probe :boot
  28
+  p.probe :find_available_flights_start, :string
  29
+  p.probe :find_available_flights_end, :string
  30
+  p.probe :book_start, :string, :integer
  31
+  p.probe :book_end, :string, :integer
  32
+end
  33
+
  34
+#
  35
+# Use these custom probes in your application
  36
+#
  37
+
  38
+class BookingEngine
  39
+  include Dtrace::Probe::BookingEngine::XRay
  40
+  
  41
+  def find_available_flights(destination)
  42
+    firing :find_available_flights, destination do
  43
+      sleep 1  # Some business logic ;-)
  44
+      ["AF98", "JB24"]
  45
+    end
  46
+  end
  47
+  
  48
+  def book(flight_number, number_of_seats)
  49
+    firing :book, flight_number, number_of_seats do
  50
+      sleep 3  # Very slow business logic   
  51
+    end
  52
+  end
  53
+  
  54
+  def book_all_available_flights
  55
+    find_available_flights("SFO").collect do |flight_number| 
  56
+      book flight_number, rand(10)
  57
+    end
  58
+  end
  59
+  
  60
+end
  61
+
  62
+class Application
  63
+  extend Dtrace::Probe::BookingEngine::XRay
  64
+
  65
+  def self.boot  
  66
+      
  67
+    # Fire a custom DTrace probe without a block (no start/end concept)
  68
+    fire :boot
  69
+    
  70
+    booking_engine = BookingEngine.new
  71
+    loop do      
  72
+      booking_engine.book_all_available_flights
  73
+    end
  74
+  end
  75
+  
  76
+end
  77
+
  78
+Application.boot
75  examples/dtrace/custom_dtrace_instumentation_with_ruby_dtrace_verbose.rb
... ...
@@ -0,0 +1,75 @@
  1
+#!/usr/bin/env ruby -w
  2
+#
  3
+# Define how you can create custom DTrace probes on the fly from
  4
+# Ruby program using the ruby-dtrace gem (USDT provider).
  5
+#
  6
+# Trace all flight search probes with:
  7
+#
  8
+#     sudo dtrace -n 'find-available-flights { printf("%s", copyinstr(arg0)); }'
  9
+#
  10
+# Trace all the flight booking probes with:
  11
+#
  12
+#     sudo dtrace -n 'book { printf("%s %d", copyinstr(arg0), arg1); }'
  13
+#
  14
+require 'rubygems'
  15
+gem "ruby-dtrace"
  16
+require 'dtrace/provider'
  17
+require File.dirname(__FILE__) + '/../../lib/xray/dtrace/usdt/provider_extensions'
  18
+
  19
+#
  20
+# Define custom DTrace USDT probes on the fly using ruby-dtrace
  21
+# native extensions.
  22
+# 
  23
+
  24
+Dtrace::Provider.create :booking_engine do |p|
  25
+  p.probe :boot
  26
+  p.probe :find_available_flights, :string
  27
+  p.probe :book, :string, :integer
  28
+end
  29
+
  30
+#
  31
+# Use these custom probes in your application
  32
+#
  33
+
  34
+class BookingEngine
  35
+  
  36
+  def find_available_flights(destination)
  37
+    Dtrace::Probe::BookingEngine.find_available_flights do |p|
  38
+      p.fire(destination)
  39
+    end
  40
+    sleep 1  # Some business logic ;-)
  41
+    ["AF98", "JB24"]
  42
+  end
  43
+  
  44
+  def book(flight_number, number_of_seats)
  45
+    Dtrace::Probe::BookingEngine.book do |p|
  46
+      p.fire(flight_number, number_of_seats)
  47
+    end
  48
+    sleep 3  # Very slow business logic   
  49
+  end
  50
+  
  51
+  def book_all_available_flights
  52
+    find_available_flights("SFO").collect do |flight_number| 
  53
+      book flight_number, rand(10)
  54
+    end
  55
+  end
  56
+  
  57
+end
  58
+
  59
+class Application
  60
+
  61
+  def self.boot  
  62
+    # Fire a custom DTrace probe without a block (no start/end concept)
  63
+    Dtrace::Probe::BookingEngine.boot do |p|
  64
+      p.fire
  65
+    end
  66
+    
  67
+    booking_engine = BookingEngine.new
  68
+    loop do      
  69
+      booking_engine.book_all_available_flights
  70
+    end
  71
+  end
  72
+  
  73
+end
  74
+
  75
+Application.boot
19  examples/dtrace/simple_memcache_client.rb
... ...
@@ -0,0 +1,19 @@
  1
+#!/usr/bin/env ruby -w
  2
+
  3
+require "rubygems"
  4
+gem "memcache-client"
  5
+require "memcache"
  6
+
  7
+CACHE = MemCache.new 'localhost:11211', :namespace => 'my_namespace'
  8
+
  9
+CACHE.set "a_key", "a_valuexxxx"
  10
+# CACHE.set "a_key", "a_value"
  11
+# CACHE.set "a_key", "a_value"
  12
+# CACHE.set "a_key", "a_value"
  13
+# CACHE.set "a_key", "a_value"
  14
+# CACHE.add "a_key_that_expires", "another_value", 10
  15
+CACHE.get "a_key"
  16
+CACHE.get "a_key_that_expires"
  17
+CACHE.get "a_key"
  18
+
  19
+
34  examples/dtrace/simple_ruby_script.rb
... ...
@@ -0,0 +1,34 @@
  1
+#!/usr/bin/env ruby -w
  2
+#
  3
+# Simple Ruby script simulating a flight booking engine
  4
+# before we add any custon DTrace instrumentation
  5
+#
  6
+class BookingEngine
  7
+  
  8
+  def find_available_flights(destination)
  9
+      sleep 1  # Some business logic ;-)
  10
+      ["AF98", "JB24"]
  11
+  end
  12
+  
  13
+  def book(flight_number, number_of_seats)
  14
+      sleep 3  # Very slow business logic   
  15
+  end
  16
+  
  17
+  def book_all_available_flights
  18
+      book flight_number, rand(10)
  19
+  end
  20
+  
  21
+end
  22
+
  23
+class Application
  24
+
  25
+  def self.boot  
  26
+    booking_engine = BookingEngine.new
  27
+    loop do      
  28
+      booking_engine.book_all_available_flights
  29
+    end
  30
+  end
  31
+  
  32
+end
  33
+
  34
+Application.boot
52  examples/dtrace/simple_ruby_script_with_tracer_custom_dtrace_instrumentation.rb
... ...
@@ -0,0 +1,52 @@
  1
+#!/usr/bin/env ruby -w
  2
+#
  3
+# Simple Ruby script demonstrating use of Tracer to install custom
  4
+# (application specific) Dtrace probes.
  5
+# 
  6
+# Run the script, then watch your customn probes fire in another terminal with:
  7
+#
  8
+#     sudo dtrace -n'ruby-probe { printf("%s %s", copyinstr(arg0), copyinstr(arg1)); }'
  9
+#
  10
+require "rubygems"
  11
+require "xray/dtrace/tracer"
  12
+
  13
+class BookingEngine
  14
+  include XRay::DTrace::Tracer
  15
+  
  16
+  def find_available_flights(destination)
  17
+    firing "find_available_flights", destination do  
  18
+      sleep 1  # Some business logic ;-)
  19
+      ["AF98", "JB24"]
  20
+    end
  21
+  end
  22
+  
  23
+  def book(flight_number)
  24
+    firing "book", flight_number do
  25
+      sleep 3  # Very slow business logic   
  26
+    end
  27
+  end
  28
+  
  29
+  def book_all_available_flights
  30
+    find_available_flights("SFO").collect do |flight_number| 
  31
+      book flight_number
  32
+    end
  33
+  end
  34
+  
  35
+end
  36
+
  37
+class Application
  38
+  extend DTracer
  39
+
  40
+  def self.boot  
  41
+    # Fire a custom DTrace probe without a block (no start/end concept)
  42
+    fire "boot", Process.pid.to_s
  43
+    
  44
+    booking_engine = BookingEngine.new
  45
+    loop do      
  46
+      booking_engine.book_all_available_flights
  47
+    end
  48
+  end
  49
+  
  50
+end
  51
+
  52
+Application.boot
25  lib/xray/dtrace/tracer/joyent.rb
... ...
@@ -0,0 +1,25 @@
  1
+module XRay
  2
+  module DTrace
  3
+    module Tracer
  4
+    
  5
+      # Wrapper around OS X DTracer exposing a custom API and namespace.
  6
+      module Joyent
  7
+
  8
+        def fire(name, data = nil)    #:nodoc: all      
  9
+          ::Tracer.fire(name, data)
  10
+        end
  11
+
  12
+        def firing(name, data = nil) #:nodoc: all      
  13
+          ::Tracer.fire(name, data)
  14
+        end
  15
+      
  16
+        def enabled?  #:nodoc: all      
  17
+          STDERR.puts "WARNING: XRay::DTrace.Tracer.enabled? does not work with Joyent Tracer"
  18
+          false
  19
+        end
  20
+            
  21
+      end
  22
+      
  23
+    end  
  24
+  end
  25
+end
28  lib/xray/dtrace/tracer/leopard.rb
... ...
@@ -0,0 +1,28 @@
  1
+module XRay
  2
+  module DTrace
  3
+    module Tracer
  4
+
  5
+      # Wrapper around OS X DTracer exposing a custom API and namespace.
  6
+      module Leopard
  7
+      
  8
+        def fire(name, data = nil)
  9
+          DTracer.fire(name, data)
  10
+        end
  11
+
  12
+        def firing(name, data = nil)
  13
+          fire(name + "-start", data)
  14
+          result = yield
  15
+          fire(name + "-end", data)
  16
+          result
  17
+        end
  18
+
  19
+        def enabled?
  20
+          DTracer.enabled?
  21
+        end
  22
+      
  23
+      end
  24
+      
  25
+    end
  26
+    
  27
+  end
  28
+end
45  lib/xray/dtrace/usdt/provider_extensions.rb
... ...
@@ -0,0 +1,45 @@
  1
+#
  2
+# Extend ruby-dtrace API with a more convenient one to fire custom USDT
  3
+# probes
  4
+#
  5
+
  6
+require "rubygems"
  7
+require 'dtrace/provider'
  8
+
  9
+class Dtrace
  10
+
  11
+  class Provider
  12
+    
  13
+    alias :original_load :load
  14
+    def load
  15
+      provider_module = original_load
  16
+      
  17
+      xray_extension_module = Module.new do
  18
+        @@provider_module = provider_module
  19
+        
  20
+        def firing(function_prefix, *args)
  21
+          @@provider_module.send :"#{function_prefix}_start" do |probe|
  22
+            probe.fire(*args)
  23
+          end
  24
+          result = yield
  25
+          @@provider_module.send :"#{function_prefix}_end" do |probe|
  26
+            probe.fire(*args)
  27
+          end
  28
+          result
  29
+        end
  30
+
  31
+        def fire(function_name, *args)
  32
+          @@provider_module.send function_name do |p|
  33
+            p.fire(*args)
  34
+          end
  35
+        end
  36
+
  37
+      end
  38
+              
  39
+      provider_module.const_set :XRay, xray_extension_module
  40
+      provider_module     
  41
+    end
  42
+    
  43
+  end
  44
+  
  45
+end

0 notes on commit 2f8deca

Please sign in to comment.
Something went wrong with that request. Please try again.