ruby-dtrace 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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