rails-dtrace 0.0.3 → 0.0.4
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.
- data/Gemfile +7 -0
- data/Guardfile +9 -0
- data/README.md +1 -1
- data/lib/rails-dtrace.rb +1 -0
- data/lib/rails-dtrace/provider.rb +11 -0
- data/lib/rails-dtrace/subscriber.rb +6 -5
- data/lib/rails-dtrace/version.rb +1 -1
- data/rails-dtrace.gemspec +1 -0
- data/spec/rails-dtrace/provider_spec.rb +10 -0
- data/spec/rails-dtrace/subscriber_spec.rb +163 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/test_logger.rb +16 -0
- data/spec/support/test_provider.rb +36 -0
- metadata +30 -4
data/Gemfile
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
gem 'ruby-usdt', :git => 'https://github.com/chrisa/ruby-usdt.git',
|
4
|
+
:submodules => true, :branch => 'disable_provider'
|
5
|
+
|
3
6
|
# Specify your gem's dependencies in rails-dtrace.gemspec
|
4
7
|
gemspec
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem "guard-rspec"
|
11
|
+
end
|
data/Guardfile
ADDED
data/README.md
CHANGED
@@ -89,7 +89,7 @@ In newer Rails, notifications become more dtrace-like. Rather than a notificatio
|
|
89
89
|
|
90
90
|
In *rails-dtrace*, the notification name becomes the probe function, and we map `start -> entry` and `finish -> exit`.
|
91
91
|
|
92
|
-
If a
|
92
|
+
If a subscriber responds to `#start` and `#finish` it will work in the new way. If it does not, Rails will try to fall back to the older way with `#call`. Because of this, rails-dtrace can be used with either codebase.
|
93
93
|
|
94
94
|
Arguments to probes are:
|
95
95
|
|
data/lib/rails-dtrace.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'usdt'
|
2
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
3
|
+
require 'rails-dtrace/provider'
|
2
4
|
|
3
5
|
module DTrace
|
4
6
|
class Subscriber
|
5
7
|
MAX_INT = 2147483647
|
6
8
|
|
7
|
-
cattr_reader :probes
|
9
|
+
cattr_reader :probes
|
8
10
|
|
9
|
-
@@provider = USDT::Provider.create :ruby, :rails
|
10
11
|
@@probes = {}
|
11
12
|
@@enabled = false
|
12
13
|
|
@@ -15,7 +16,9 @@ module DTrace
|
|
15
16
|
@logger ||= Rails.logger if defined?(Rails)
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
+
def provider
|
20
|
+
@provider ||= DTrace::Provider.new
|
21
|
+
end
|
19
22
|
|
20
23
|
# Rails 3.x define instruments as blocks that wrap code. When the code
|
21
24
|
# finishes executing, subscribers are called with the start and end time.
|
@@ -35,8 +38,6 @@ module DTrace
|
|
35
38
|
fire_probe(notification, id, payload, 'exit')
|
36
39
|
end
|
37
40
|
|
38
|
-
protected
|
39
|
-
|
40
41
|
def find_or_create_probe(probe_func, probe_name)
|
41
42
|
probe_id = "#{probe_func}::#{probe_name}"
|
42
43
|
|
data/lib/rails-dtrace/version.rb
CHANGED
data/rails-dtrace.gemspec
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rails-dtrace/provider'
|
3
|
+
|
4
|
+
describe DTrace::Provider, '#new' do
|
5
|
+
it "should create a new USDT::Provider" do
|
6
|
+
provider = double("provider")
|
7
|
+
USDT::Provider.should_receive(:create).with(:ruby, :rails).and_return(provider)
|
8
|
+
DTrace::Provider.new.should == provider
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rails-dtrace/subscriber'
|
3
|
+
require 'support/test_provider'
|
4
|
+
require 'support/test_logger'
|
5
|
+
|
6
|
+
describe DTrace::Subscriber, 'provider' do
|
7
|
+
it "should return a new DTrace::Provider" do
|
8
|
+
provider = double('provider')
|
9
|
+
DTrace::Provider.should_receive(:new).and_return(provider)
|
10
|
+
DTrace::Subscriber.provider.should == provider
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe DTrace::Subscriber do
|
15
|
+
subject { DTrace::Subscriber }
|
16
|
+
|
17
|
+
let(:provider) {TestProvider.new}
|
18
|
+
let(:logger) { TestLogger.new }
|
19
|
+
|
20
|
+
before do
|
21
|
+
subject.stub(:provider).and_return(provider)
|
22
|
+
subject.stub(:logger).and_return(logger)
|
23
|
+
subject.probes.clear
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '.find_or_create_probe' do
|
27
|
+
context "with a new notification" do
|
28
|
+
let(:probe) { provider.probes.last }
|
29
|
+
|
30
|
+
it "creates a DTrace probe" do
|
31
|
+
expect {
|
32
|
+
subject.find_or_create_probe("test.notification", "event")
|
33
|
+
}.to change {
|
34
|
+
provider.probes.size
|
35
|
+
}.by 1
|
36
|
+
end
|
37
|
+
|
38
|
+
it "registers the notification name as the probe function" do
|
39
|
+
subject.find_or_create_probe("test.notification", "event")
|
40
|
+
probe.probe_func.should == "test.notification"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "registers 'event' as the probe name" do
|
44
|
+
subject.find_or_create_probe("test.notification", "event")
|
45
|
+
probe.probe_name.should == "event"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "registers probe argument types" do
|
49
|
+
subject.find_or_create_probe("test.notification", "event")
|
50
|
+
probe.probe_args.should == [:string, :string, :integer]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "logs the new probe name" do
|
54
|
+
subject.find_or_create_probe("test.notification", "event")
|
55
|
+
logger.latest_entry.should == "Adding DTrace probe: test.notification::event"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "enables the DTrace provider" do
|
59
|
+
provider.should_not be_enabled
|
60
|
+
subject.find_or_create_probe("test.notification", "event")
|
61
|
+
provider.should be_enabled
|
62
|
+
end
|
63
|
+
|
64
|
+
it "disables the DTrace provider before re-enabling it" do
|
65
|
+
subject.find_or_create_probe("first.notification", "event")
|
66
|
+
provider.should_receive(:disable)
|
67
|
+
subject.find_or_create_probe("second.notification", "event")
|
68
|
+
provider.should be_enabled
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with an existing notification" do
|
73
|
+
before do
|
74
|
+
subject.find_or_create_probe("test.notification", "event")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not create a new probe" do
|
78
|
+
expect {
|
79
|
+
subject.find_or_create_probe("test.notification", "event")
|
80
|
+
}.not_to change {
|
81
|
+
provider.probes.size
|
82
|
+
}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe '.call' do
|
88
|
+
let(:probe) { double(:fire => true, :enabled? => false) }
|
89
|
+
|
90
|
+
it "registers a probe with probe_name 'event'" do
|
91
|
+
subject.should_receive(:find_or_create_probe).with("test.notification", "event").and_return(probe)
|
92
|
+
subject.call("test.notification", nil, nil, "event-id", {})
|
93
|
+
end
|
94
|
+
|
95
|
+
it "fires the probe" do
|
96
|
+
expect {
|
97
|
+
subject.call("test.notification", nil, nil, "event-id", {})
|
98
|
+
}.to change {
|
99
|
+
provider.fired_probes.size
|
100
|
+
}.by(1)
|
101
|
+
|
102
|
+
provider.fired_probes.last.should == ["event-id", "{}", 0]
|
103
|
+
end
|
104
|
+
|
105
|
+
context "timestamps" do
|
106
|
+
it "outputs time diff in nanoseconds" do
|
107
|
+
start_time = Time.now
|
108
|
+
end_time = start_time + 1
|
109
|
+
|
110
|
+
subject.call("test.notification", start_time, end_time, "event-id", {})
|
111
|
+
|
112
|
+
provider.fired_probes.last.should == ["event-id", "{}", 1000000000]
|
113
|
+
end
|
114
|
+
|
115
|
+
it "bounds time diffs by the maximum value of a C int" do
|
116
|
+
start_time = Time.now
|
117
|
+
end_time = start_time + 1000000
|
118
|
+
|
119
|
+
subject.call("test.notification", start_time, end_time, "event-id", {})
|
120
|
+
|
121
|
+
provider.fired_probes.last.should == ["event-id", "{}", 2147483647]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '.start' do
|
127
|
+
let(:probe) { double(:fire => true, :enabled? => false) }
|
128
|
+
|
129
|
+
it "registers a probe with probe_name 'entry'" do
|
130
|
+
subject.should_receive(:find_or_create_probe).with("test.notification", "entry").and_return(probe)
|
131
|
+
subject.start("test.notification", "event-id", {})
|
132
|
+
end
|
133
|
+
|
134
|
+
it "fires the probe" do
|
135
|
+
expect {
|
136
|
+
subject.start("test.notification", "event-id", {})
|
137
|
+
}.to change {
|
138
|
+
provider.fired_probes.size
|
139
|
+
}.by(1)
|
140
|
+
|
141
|
+
provider.fired_probes.last.should == ["event-id", "{}", 0]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '.finish' do
|
146
|
+
let(:probe) { double(:fire => true, :enabled? => false) }
|
147
|
+
|
148
|
+
it "registers a probe with probe_name 'exit'" do
|
149
|
+
subject.should_receive(:find_or_create_probe).with("test.notification", "exit").and_return(probe)
|
150
|
+
subject.finish("test.notification", "event-id", {})
|
151
|
+
end
|
152
|
+
|
153
|
+
it "fires the probe" do
|
154
|
+
expect {
|
155
|
+
subject.finish("test.notification", "event-id", {})
|
156
|
+
}.to change {
|
157
|
+
provider.fired_probes.size
|
158
|
+
}.by(1)
|
159
|
+
|
160
|
+
provider.fired_probes.last.should == ["event-id", "{}", 0]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rspec/mocks'
|
2
|
+
|
3
|
+
class TestProvider
|
4
|
+
include RSpec::Mocks::ExampleMethods
|
5
|
+
|
6
|
+
attr_reader :probes, :fired_probes
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@probes = []
|
11
|
+
@fired_probes = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def enabled?
|
15
|
+
@enabled
|
16
|
+
end
|
17
|
+
|
18
|
+
def probe(func, name, *args)
|
19
|
+
p = double('probe', :probe_func => func, :probe_name => name, :probe_args => args, :enabled? => true)
|
20
|
+
|
21
|
+
p.stub(:fire) do |*args|
|
22
|
+
fired_probes << args
|
23
|
+
end
|
24
|
+
|
25
|
+
probes << p
|
26
|
+
p
|
27
|
+
end
|
28
|
+
|
29
|
+
def disable
|
30
|
+
@enabled = false
|
31
|
+
end
|
32
|
+
|
33
|
+
def enable
|
34
|
+
@enabled = true
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-dtrace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ruby-usdt
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rails
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '3.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.0'
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: rspec
|
32
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,15 +70,21 @@ files:
|
|
54
70
|
- .gitignore
|
55
71
|
- .rspec
|
56
72
|
- Gemfile
|
73
|
+
- Guardfile
|
57
74
|
- LICENSE
|
58
75
|
- README.md
|
59
76
|
- Rakefile
|
60
77
|
- lib/rails-dtrace.rb
|
78
|
+
- lib/rails-dtrace/provider.rb
|
61
79
|
- lib/rails-dtrace/railtie.rb
|
62
80
|
- lib/rails-dtrace/subscriber.rb
|
63
81
|
- lib/rails-dtrace/version.rb
|
64
82
|
- rails-dtrace.gemspec
|
83
|
+
- spec/rails-dtrace/provider_spec.rb
|
84
|
+
- spec/rails-dtrace/subscriber_spec.rb
|
65
85
|
- spec/spec_helper.rb
|
86
|
+
- spec/support/test_logger.rb
|
87
|
+
- spec/support/test_provider.rb
|
66
88
|
homepage: https://github.com/sax/rails-dtrace
|
67
89
|
licenses: []
|
68
90
|
post_install_message:
|
@@ -77,7 +99,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
99
|
version: '0'
|
78
100
|
segments:
|
79
101
|
- 0
|
80
|
-
hash:
|
102
|
+
hash: 2731423727273104030
|
81
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
104
|
none: false
|
83
105
|
requirements:
|
@@ -86,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
86
108
|
version: '0'
|
87
109
|
segments:
|
88
110
|
- 0
|
89
|
-
hash:
|
111
|
+
hash: 2731423727273104030
|
90
112
|
requirements: []
|
91
113
|
rubyforge_project:
|
92
114
|
rubygems_version: 1.8.24
|
@@ -94,4 +116,8 @@ signing_key:
|
|
94
116
|
specification_version: 3
|
95
117
|
summary: Add DTrace probes to Rails
|
96
118
|
test_files:
|
119
|
+
- spec/rails-dtrace/provider_spec.rb
|
120
|
+
- spec/rails-dtrace/subscriber_spec.rb
|
97
121
|
- spec/spec_helper.rb
|
122
|
+
- spec/support/test_logger.rb
|
123
|
+
- spec/support/test_provider.rb
|