Permalink
Browse files

Merging with Rubyforge's svn

git-svn-id: svn+ssh://rubyforge.org/var/svn/xray@32 5dde6e04-f255-48cb-b2b1-8039b2f1cec5
  • Loading branch information...
1 parent f384c5b commit 2f8deca89bd2bf6ea610f443565867fe4d1656fb ph7 committed Nov 16, 2008
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+#
+# Painless DTrace install for Ubuntu
+#
+
+DISTRIBUTION=dtrace-20081028
+
+download()
+{
+ sudo apt-get install curl
+ if [ ! -e ${DISTRIBUTION} ]; then
+ echo "\n==== Downloading DTrace for Linux ====\n"
+ curl -O ftp://crisp.dynalias.com/pub/release/website/dtrace/${DISTRIBUTION}.tar.bz2
+ tar jxvf ${DISTRIBUTION}.tar.bz2
+ fi
+}
+
+install_dependencies()
+{
+ sudo apt-get install zlib1g-dev flex bison elfutils libelf-dev libc6-dev linux-libc-dev
+}
+
+build()
+{
+ make -C ${DISTRIBUTION} clean all
+}
+
+download
+install_dependencies
+build
@@ -0,0 +1,54 @@
+#!/usr/sbin/dtrace -s
+#pragma D option quiet
+#pragma D option aggsortrev
+#pragma D option dynvarsize=64m
+
+/*
+ * Trace all ruby function calls and display their total time, average time
+ * an invocation number (slower first).
+ *
+ * Usage:
+ *
+ * sudo /usr/bin/xray_profile_ruby_function_calls.d -p <a pid>
+ *
+ * sudo /usr/bin/xray_profile_ruby_function_calls.d -c "ruby -v"
+ *
+ * sudo dtrace -s /usr/bin/xray_profile_ruby_function_calls.d -p <a pid>
+ */
+
+this string str;
+
+dtrace:::BEGIN
+{
+ printf("Tracing, please be patient... Ctrl-C to interrupt.\n");
+ depth = 0;
+}
+
+ruby$target:::function-entry
+{
+ self->depth++;
+ self->start[copyinstr(arg0), copyinstr(arg1), self->depth] = timestamp;
+}
+
+ruby$target:::function-return
+/(this->class = copyinstr(arg0)) != NULL && \
+ (this->func = copyinstr(arg1)) != NULL && \
+ self->start[this->class, this->func, self->depth]/
+{
+ this->elapsed = timestamp - self->start[this->class, this->func, self->depth];
+ @num[this->class, this->func] = count();
+ @eavg[this->class, this->func] = avg(this->elapsed);
+ @esum[this->class, this->func] = sum(this->elapsed);
+ self->start[this->class, this->func, self->depth] = 0;
+ self->depth--;
+}
+
+dtrace:::END
+{
+ normalize(@eavg, 1000);
+ normalize(@esum, 1000);
+ setopt("aggsortpos", "0"); /* Sort on total time */
+ printf("%95s\n", "_______ ELAPSED ______");
+ printf("%-40s %-30s %12s %10s %6s\n", "Class", "Method", "Total (us)", "Avg (us)", "Count\n");
+ printa("%-40.40s %-30.30s %@12d %@10d %@6d\n", @esum, @eavg, @num);
+}
@@ -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();
+}
@@ -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);
+}
@@ -0,0 +1,25 @@
+#!/usr/sbin/dtrace -s
+#pragma D option quiet
+
+/*
+ * Trace all the custom ruby probes defined in your application
+ * using XRay::DTrace, Apple's DTracer or Joyent's Tracer module.
+ *
+ * Usage:
+ *
+ * sudo /usr/bin/xray_trace_all_custom_ruby_probes.d -p <a pid>
+ *
+ * sudo /usr/bin/xray_trace_all_custom_ruby_probes.d -c "ruby -v"
+ *
+ * sudo dtrace -s /usr/bin/xray_trace_all_custom_ruby_probes.d -p <a pid>
+ */
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ruby$target:::ruby-probe
+{
+ printf("=> %d == cpu: %2d == %15s '%s'\n", timestamp, cpu, copyinstr(arg0), copyinstr(arg1))
+}
@@ -0,0 +1,20 @@
+#!/usr/sbin/dtrace -s
+#pragma D option quiet
+#pragma D option dynvarsize=64m
+
+/*
+ * Trace all the probes of the ruby provider
+ *
+ * Usage:
+ *
+ * sudo /usr/bin/xray_trace_all_ruby_probes.d -p <a pid>
+ *
+ * sudo /usr/bin/xray_trace_all_ruby_probes.d -c "ruby -v"
+ *
+ * sudo dtrace -s /usr/bin/xray_trace_all_ruby_probes.d -p <a pid>
+ */
+
+ruby$target:::
+{
+ printf("=> cpu %2d == %-15.15s == %-15.15s == %s\n", cpu, probename, copyinstr(arg0), copyinstr(arg1))
+}
@@ -0,0 +1,20 @@
+#!/usr/sbin/dtrace -s
+#pragma D option quiet
+#pragma D option dynvarsize=64m
+
+
+pid*:memcached:*do_item_update*:entry {
+ printf("COMMAND == %s \n", probefunc);
+}
+
+pid*:memcached:process_get_command:entry {
+ self->conn_id = arg0;
+/* self->pointer_to_string = copyin(arg1, 4); */
+ printf("GET == connection %d == update %p %d\n", arg0, arg1, arg2);
+}
+
+pid*:memcached:process_update_command:entry {
+ self->conn_id = arg0;
+/* self->pointer_to_string = copyin(arg1, 4); */
+ printf("UPDATE == connection %d == update %p %d\n", arg0, arg1, arg2);
+}
@@ -0,0 +1,30 @@
+#!/usr/sbin/dtrace -s
+#pragma D option quiet
+#pragma D option dynvarsize=64m
+
+
+/*
+ * Inspired by Joyent's http://www.joyeur.com/2007/10/03/using-dtrace-on-mysql
+ */
+
+/*
+ * MySQL query parsing (captures all incoming queries)
+ */
+
+ /* TODO For example we can see what queries are executed the most: => Top 10 queries */
+pid*::*mysql*:entry
+{
+ printf("%Y %s\n", walltimestamp, copyinstr(arg1));
+}
+
+
+/*
+ * Now lets say we want to find out how long a query took to execute.
+ * The function mysql_execute_command does the actual execution of
+ * the queries so all we do here is subtract the entry and return
+ * timestamps of this function.
+ */
+pid*:mysqld:*mysql_execute_command*:entry
+{
+ printf("OK");
+}
@@ -0,0 +1,114 @@
+#!/usr/sbin/dtrace -s
+#pragma D option quiet
+#pragma D option aggsortrev
+#pragma D option dynvarsize=64m
+
+/*
+ * Trace Rails controller actions and database response times.
+ *
+ * Report average response time, total elapsed time and invocation count
+ * for all controller actions and datase queries.
+ *
+ * Also print response time distribution diagrams for global and individual
+ * action / query.
+ *
+ * Usage:
+ *
+ * sudo /usr/bin/xray_trace_rails_response_times.d -p <a pid>
+ *
+ * sudo /usr/bin/xray_trace_rails_response_times.d -c "ruby -v"
+ *
+ * sudo dtrace -s /usr/bin/xray_trace_rails_response_times.d -p <a pid>
+ */
+this string name;
+this string action;
+this string query;
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+ depth = 0;
+}
+
+ruby$target::ruby_dtrace_probe:
+/(this->name = copyinstr(arg0)) == "request-start"/
+{
+ self->request_start[copyinstr(arg1)] = timestamp;
+}
+
+
+ruby$target::ruby_dtrace_probe:
+/(this->name = copyinstr(arg0)) == "request-end" && self->request_start[(this->action = copyinstr(arg1))]/
+{
+ this->elapsed = timestamp - self->request_start[this->action];
+ @re_count[this->action] = count();
+ @re_eavg[this->action] = avg(this->elapsed);
+ @re_esum[this->action] = sum(this->elapsed);
+ @re_edist[this->action] = quantize(this->elapsed);
+ @re_all_edist["All Requests"] = quantize(this->elapsed);
+ self->request_start[this->action] = 0;
+}
+
+ruby$target::ruby_dtrace_probe:
+/(this->name = copyinstr(arg0)) == "db-start"/
+{
+ self->db_start[copyinstr(arg1)] = timestamp;
+}
+
+
+ruby$target::ruby_dtrace_probe:
+/(this->name = copyinstr(arg0)) == "db-end" && self->db_start[(this->query = copyinstr(arg1))]/
+{
+ @db_count[this->query] = count();
+ this->elapsed = timestamp - self->db_start[this->query];
+ @db_eavg[this->query] = avg(this->elapsed);
+ @db_esum[this->query] = sum(this->elapsed);
+ @db_edist[this->query] = quantize(this->elapsed);
+ @db_all_edist["All Queries"] = quantize(this->elapsed);
+ self->db_start[this->query] = 0;
+}
+
+dtrace:::END
+{
+ normalize(@re_eavg, 1000);
+ normalize(@re_esum, 1000);
+ normalize(@db_eavg, 1000);
+ normalize(@db_esum, 1000);
+
+ printf("\n================================================\n");
+ printf(" Controller Response Times\n");
+ printf("================================================\n\n");
+
+ setopt("aggsortpos", "0"); /* Sort on avg time */
+ printf("%-50s %s\n", " _________ Action _________", "_ Avg. (us) _ Total (us) _ Count _\n");
+ printa("%-50.50s %@12d %@12d %@6d\n", @re_eavg, @re_esum, @re_count);
+
+
+ printf("\n================================================\n");
+ printf(" Database Response Times\n");
+ printf("================================================\n");
+
+ setopt("aggsortpos", "0"); /* Sort on avg time */
+ printf("%-100s %s\n", " _________ Query _________", "_ Avg. (us) _ Total (us) _ Count _\n");
+ printa("%-100.100s %@12d %@12d %@6d\n", @db_eavg, @db_esum, @db_count);
+
+ printf("\n================================================\n");
+ printf(" Response Time Summary\n");
+ printf("================================================\n\n");
+
+ printa(@re_all_edist);
+ printa(@db_all_edist);
+
+ printf("\n================================================\n");
+ printf(" Controller Response Time Distribution\n");
+ printf("================================================\n\n");
+
+ printa(@re_edist);
+
+ printf("\n================================================\n");
+ printf(" DB Response Time Distribution\n");
+ printf("================================================\n\n");
+
+ printa(@db_edist);
+}
+
Oops, something went wrong.

0 comments on commit 2f8deca

Please sign in to comment.