ruby-dtrace 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ require 'drb'
2
+
3
+ class DtracerClient
4
+
5
+ def initialize
6
+ DRb.start_service
7
+ @tracer = DRbObject.new(nil, 'druby://localhost:2999')
8
+ end
9
+
10
+ def start_dtrace(pid)
11
+ @tracer.start_dtrace(pid)
12
+ end
13
+
14
+ def end_dtrace
15
+ @tracer.end_dtrace
16
+ end
17
+
18
+ end
@@ -0,0 +1,48 @@
1
+ body {
2
+ margin-bottom:25px;
3
+ }
4
+
5
+ #dtrace {
6
+ width:100%;
7
+ }
8
+
9
+ #dtrace td, #dtrace th, #dtrace div, #dtrace p {
10
+ text-align:left;
11
+ }
12
+
13
+ #dtrace a,
14
+ #dtrace a:visited {
15
+ color:#005;
16
+ text-decoration:none;
17
+ }
18
+
19
+ #dtrace a:hover,
20
+ #dtrace a:active {
21
+ text-decoration:underline;
22
+ }
23
+
24
+ #dtrace .dtrace-tab {
25
+ background-color:#fff;
26
+ padding:1em;
27
+ margin:0;
28
+ }
29
+
30
+ #dtrace-tabs {
31
+ width:100%;
32
+ height:25px;
33
+ margin:0; padding:0;
34
+ list-style-type:none;
35
+ background:#000;
36
+ }
37
+
38
+ #dtrace-tabs li {
39
+ float:left;
40
+ }
41
+
42
+ #dtrace-tabs li a,
43
+ #dtrace-tabs li a:visited {
44
+ display:block;
45
+ line-height:25px;
46
+ margin:0 1em;
47
+ color:#fff;
48
+ }
@@ -0,0 +1,52 @@
1
+ namespace :dtrace do
2
+
3
+ desc 'Set up dtrace in your rails application'
4
+ task :setup do
5
+ ['dtracer'].each do |script|
6
+ script_dest = "#{RAILS_ROOT}/script/#{script}"
7
+ script_src = File.dirname(__FILE__) + "/../bin/#{script}.rb"
8
+
9
+ FileUtils.chmod 0774, script_src
10
+
11
+ unless File.exists?(script_dest)
12
+ puts "Copying acts_as_encrypted script #{script}.rb to #{script_dest}"
13
+ FileUtils.cp_r(script_src, script_dest)
14
+ end
15
+ end
16
+
17
+ ['stylesheets/dtrace.css'].each do |asset|
18
+ asset_dest = "#{RAILS_ROOT}/public/#{asset}"
19
+ asset_src = File.dirname(__FILE__) + "/../public/#{asset}"
20
+
21
+ FileUtils.chmod 0774, asset_src
22
+
23
+ unless File.exists?(asset_dest)
24
+ puts "Copying acts_as_encrypted asset #{asset} to #{asset_dest}"
25
+ FileUtils.cp_r(asset_src, asset_dest)
26
+ end
27
+ end
28
+ end
29
+
30
+ desc 'Remove dtrace from your rails application'
31
+ task :remove do
32
+ ['dtracer'].each do |script|
33
+ script_dest = "#{RAILS_ROOT}/script/#{script}"
34
+
35
+ if File.exists?(script_dest)
36
+ puts "Removing #{script_dest} ..."
37
+ FileUtils.rm(script_dest, :force => true)
38
+ end
39
+ end
40
+
41
+ ['stylesheets/dtrace.css'].each do |asset|
42
+ asset_dest = "#{RAILS_ROOT}/public/#{asset}"
43
+
44
+ if File.exists?(asset_dest)
45
+ puts "Removing #{asset_dest} ..."
46
+ FileUtils.rm(asset_dest, :force => true)
47
+ end
48
+ end
49
+ end
50
+
51
+ end
52
+
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+
3
+ class DtraceTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_this_plugin
6
+ flunk
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ <div id="dtrace-report">
2
+ <p>...dtrace report...</p>
3
+ <table>
4
+ <% controller.dtrace_report.sort {|a,b| b[1] <=> a[1] }.each do |e| %>
5
+ <tr>
6
+ <td><%= e[0] %></td>
7
+ <td><%= e[1] %></td>
8
+ </tr>
9
+ <% end %>
10
+ </table>
11
+ </div>
@@ -0,0 +1,415 @@
1
+ #
2
+ # Ruby-Dtrace
3
+ # (c) 2007 Chris Andrews <chris@nodnol.org>
4
+ #
5
+
6
+ require 'dtrace'
7
+ require 'test/unit'
8
+
9
+ class TestDtrace < Test::Unit::TestCase
10
+ def test_dtrace
11
+ t = Dtrace.new
12
+ assert_equal Object, Dtrace.superclass
13
+ assert_equal Dtrace, t.class
14
+ end
15
+
16
+ def test_list_probes
17
+ t = Dtrace.new
18
+ probe_count = 0
19
+ t.each_probe do |probe|
20
+ assert probe.provider
21
+ assert probe.mod
22
+ assert probe.func
23
+ assert probe.name
24
+ probe_count += 1
25
+ end
26
+ assert probe_count
27
+ end
28
+
29
+ def test_compile
30
+ t = Dtrace.new
31
+
32
+ progtext = "syscall:::entry
33
+ {
34
+ @calls[execname] = count();
35
+ @fcalls[probefunc] = count();
36
+ }"
37
+
38
+ prog = t.compile progtext
39
+ assert prog
40
+ prog.execute
41
+
42
+ info = prog.info
43
+ assert info
44
+ assert info.aggregates_count
45
+ assert_equal 0, info.speculations_count
46
+ assert info.recgens_count
47
+ assert info.matches_count
48
+ end
49
+
50
+ def test_compile_with_args
51
+ t = Dtrace.new
52
+
53
+ progtext = "syscall:::entry
54
+ /pid == $1/
55
+ {
56
+ @calls[execname] = count();
57
+ @fcalls[probefunc] = count();
58
+ }"
59
+
60
+ prog = t.compile(progtext, $$.to_s)
61
+ assert prog
62
+ prog.execute
63
+
64
+ info = prog.info
65
+ assert info
66
+ assert_equal 2, info.aggregates_count
67
+ assert_equal 0, info.speculations_count
68
+ assert_equal 4, info.recgens_count
69
+
70
+ # matches_count is platform dependent
71
+ assert info.matches_count
72
+ end
73
+
74
+ def test_run
75
+ t = Dtrace.new
76
+
77
+ t.setopt("aggsize", "4m")
78
+ t.setopt("bufsize", "4m")
79
+
80
+ progtext = "syscall:::entry
81
+ {
82
+ @calls[execname] = count();
83
+ @fcalls[probefunc] = count();
84
+ }"
85
+
86
+ prog = t.compile progtext
87
+ assert prog
88
+ prog.execute
89
+ assert_equal 0, t.status # none
90
+
91
+ t.go
92
+
93
+ assert_equal 1, t.status # ok
94
+ sleep 1
95
+ assert_equal 1, t.status # ok
96
+ t.stop
97
+ assert_equal 4, t.status # stopped
98
+ end
99
+
100
+ def test_aggregate_print
101
+ t = Dtrace.new
102
+
103
+ t.setopt("aggsize", "4m")
104
+ t.setopt("bufsize", "4m")
105
+
106
+ progtext = "syscall:::entry
107
+ {
108
+ @calls[execname] = count();
109
+ @fcalls[probefunc] = count();
110
+ }"
111
+
112
+ prog = t.compile progtext
113
+ assert prog
114
+ prog.execute
115
+
116
+ t.go
117
+ sleep 1
118
+ t.stop
119
+
120
+ t.aggregate_snap
121
+ t.aggregate_print
122
+ end
123
+
124
+ def test_aggregate_walk
125
+ t = Dtrace.new
126
+
127
+ t.setopt("aggsize", "4m")
128
+ t.setopt("bufsize", "4m")
129
+
130
+ progtext = "syscall:::entry
131
+ {
132
+ @fcalls[probefunc] = count();
133
+ @calls[execname] = count();
134
+ }"
135
+
136
+ prog = t.compile progtext
137
+ assert prog
138
+ prog.execute
139
+
140
+ t.go
141
+ sleep 1
142
+ t.stop
143
+
144
+ t.aggregate_snap
145
+
146
+ t.each_aggregate do |agg|
147
+ agg.each_record do |rec|
148
+ assert rec
149
+ assert rec.data
150
+ end
151
+ end
152
+ end
153
+
154
+ def test_aggregate_record_array
155
+ t = Dtrace.new
156
+
157
+ t.setopt("aggsize", "4m")
158
+ t.setopt("bufsize", "4m")
159
+
160
+ progtext = "syscall:::entry
161
+ {
162
+ @calls[execname] = count();
163
+ }"
164
+
165
+ prog = t.compile progtext
166
+ assert prog
167
+ prog.execute
168
+
169
+ t.go
170
+ sleep 1
171
+ t.stop
172
+
173
+ t.aggregate_snap
174
+
175
+ t.each_aggregate do |agg|
176
+ assert agg
177
+ assert agg.num_records
178
+ (0..(agg.num_records - 1)).each do |i|
179
+ rec = agg[i]
180
+ assert rec.data
181
+ end
182
+ end
183
+ end
184
+
185
+ def test_aggregate_record_array_continuous
186
+ t = Dtrace.new
187
+
188
+ t.setopt("aggsize", "4m")
189
+ t.setopt("bufsize", "4m")
190
+
191
+ progtext = "syscall:::entry
192
+ {
193
+ @calls[execname] = count();
194
+ }"
195
+
196
+ prog = t.compile progtext
197
+ assert prog
198
+ prog.execute
199
+
200
+ t.go
201
+
202
+ (1..10).each do
203
+ sleep 1
204
+ t.aggregate_snap
205
+
206
+ t.each_aggregate do |agg|
207
+ assert agg
208
+ assert agg.num_records
209
+ (0..(agg.num_records - 1)).each do |i|
210
+ rec = agg[i]
211
+ assert rec.data
212
+ end
213
+ end
214
+ t.aggregate_clear
215
+ end
216
+
217
+ t.stop
218
+ end
219
+
220
+ def test_bad_program
221
+ t = Dtrace.new
222
+ progtext = "blah blahb albhacasfas"
223
+ e = assert_raise DtraceException do
224
+ prog = t.compile progtext
225
+ end
226
+ assert_equal "probe description :::blah does not match any probes", e.message
227
+ end
228
+
229
+ def test_rubys_own_dtrace
230
+ t = Dtrace.new
231
+
232
+ t.setopt("aggsize", "4m")
233
+ t.setopt("bufsize", "4m")
234
+
235
+ progtext = "ruby*:::function-entry{ @[copyinstr(arg1)] = count(); }"
236
+
237
+ prog = t.compile progtext
238
+ assert prog
239
+ prog.execute
240
+
241
+ t.go
242
+
243
+ foo = 0
244
+ (1..1000).each do |i|
245
+ foo = foo + i
246
+ end
247
+
248
+ t.stop
249
+ t.aggregate_snap
250
+
251
+ t.each_aggregate do |agg|
252
+ assert agg
253
+ assert agg.num_records
254
+ (0..(agg.num_records - 1)).each do |i|
255
+ rec = agg[i]
256
+ assert rec.data
257
+ end
258
+ end
259
+ end
260
+
261
+ def test_multiple_programs
262
+ t = Dtrace.new
263
+
264
+ t.setopt("aggsize", "4m")
265
+ t.setopt("bufsize", "4m")
266
+
267
+ progtext = "syscall:::entry
268
+ {
269
+ @calls[execname] = count();
270
+ }"
271
+
272
+ prog1 = t.compile progtext
273
+ assert prog1
274
+
275
+ progtext = "syscall:::entry
276
+ {
277
+ @fcalls[probefunc] = count();
278
+ }"
279
+
280
+ prog2 = t.compile progtext
281
+ assert prog2
282
+
283
+ prog1.execute
284
+ prog2.execute
285
+
286
+ info1 = prog1.info
287
+ assert info1
288
+ assert_equal 1, info1.aggregates_count
289
+ assert_equal 0, info1.speculations_count
290
+ assert_equal 2, info1.recgens_count
291
+ assert info1.matches_count
292
+
293
+ info2 = prog2.info
294
+ assert info2
295
+ assert_equal 1, info2.aggregates_count
296
+ assert_equal 0, info2.speculations_count
297
+ assert_equal 2, info2.recgens_count
298
+ assert info2.matches_count
299
+
300
+ t.go
301
+ sleep 2
302
+ t.stop
303
+ t.aggregate_snap
304
+
305
+ t.each_aggregate do |agg|
306
+ assert agg
307
+ assert agg.num_records
308
+ (0..(agg.num_records - 1)).each do |i|
309
+ rec = agg[i]
310
+ assert rec.data
311
+ end
312
+ end
313
+ end
314
+
315
+ def test_multiple_runs
316
+ t = Dtrace.new
317
+ t.setopt("aggsize", "4m")
318
+ t.setopt("bufsize", "4m")
319
+
320
+ progtext = "ruby*:::function-entry{ @[copyinstr(arg1)] = count(); }"
321
+
322
+ prog = t.compile progtext
323
+ assert prog
324
+ prog.execute
325
+
326
+ t.go
327
+
328
+ foo = 0
329
+ (1..1000).each do |i|
330
+ foo = foo + i
331
+ end
332
+
333
+ t.stop
334
+ t.aggregate_snap
335
+
336
+ t.each_aggregate do |agg|
337
+ assert agg
338
+ assert agg.num_records
339
+ (0..(agg.num_records - 1)).each do |i|
340
+ rec = agg[i]
341
+ assert rec.data
342
+ end
343
+ end
344
+
345
+ t = Dtrace.new
346
+ t.setopt("aggsize", "4m")
347
+ t.setopt("bufsize", "4m")
348
+
349
+ prog = t.compile progtext
350
+ assert prog
351
+
352
+ prog.execute
353
+
354
+ t.go
355
+
356
+ foo = 0
357
+ (1..1000).each do |i|
358
+ foo = foo + i
359
+ end
360
+
361
+ t.stop
362
+ t.aggregate_snap
363
+
364
+ t.each_aggregate do |agg|
365
+ assert agg
366
+ assert agg.num_records
367
+ (0..(agg.num_records - 1)).each do |i|
368
+ rec = agg[i]
369
+ assert rec.data
370
+ end
371
+ end
372
+
373
+ end
374
+
375
+ def test_aggdata_probe
376
+ t = Dtrace.new
377
+
378
+ t.setopt("aggsize", "4m")
379
+ t.setopt("bufsize", "4m")
380
+
381
+ progtext = "ruby*:::function-entry{ @[copyinstr(arg1)] = count(); }"
382
+
383
+ prog = t.compile progtext
384
+ assert prog
385
+ prog.execute
386
+
387
+ t.go
388
+
389
+ foo = 0
390
+ (1..1000).each do |i|
391
+ foo = foo + i
392
+ end
393
+
394
+ t.stop
395
+
396
+ t.aggregate_snap
397
+
398
+ t.each_aggregate do |agg|
399
+
400
+ probe = agg.probe
401
+ assert probe.provider
402
+ assert probe.mod
403
+ assert probe.func
404
+ assert probe.name
405
+
406
+ agg.each_record do |rec|
407
+ assert rec
408
+ assert rec.data
409
+ end
410
+ end
411
+
412
+
413
+ end
414
+
415
+ end