rails-dtrace 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
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 notification subscriber responds to #call, ActiveSupport::Notifications will send methods in the Rails 3 way. For this reason the rails-dtrace code is incompatible at this time. It could conceivably be done with some metaprogramming to trick the Rails framework, but I'd prefer to keep the rails-dtrace code small and readable.
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,4 +1,5 @@
1
1
  require "rails-dtrace/version"
2
+ require "rails-dtrace/provider"
2
3
  require "rails-dtrace/subscriber"
3
4
 
4
5
  require 'rails-dtrace/railtie' if defined?(Rails)
@@ -0,0 +1,11 @@
1
+ require 'usdt'
2
+
3
+ module DTrace
4
+ module Provider
5
+ class << self
6
+ def new
7
+ USDT::Provider.create :ruby, :rails
8
+ end
9
+ end
10
+ end
11
+ end
@@ -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, :provider
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
- attr_writer :logger
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
 
@@ -1,3 +1,3 @@
1
1
  module Dtrace
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/rails-dtrace.gemspec CHANGED
@@ -16,5 +16,6 @@ Gem::Specification.new do |gem|
16
16
  gem.version = Dtrace::VERSION
17
17
 
18
18
  gem.add_dependency 'ruby-usdt'
19
+ gem.add_dependency 'rails', '>= 3.0'
19
20
  gem.add_development_dependency 'rspec'
20
21
  end
@@ -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
@@ -4,6 +4,8 @@
4
4
  # loaded once.
5
5
  #
6
6
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ #
8
+
7
9
  RSpec.configure do |config|
8
10
  config.treat_symbols_as_metadata_keys_with_true_values = true
9
11
  config.run_all_when_everything_filtered = true
@@ -0,0 +1,16 @@
1
+ class TestLogger
2
+ def debug(string)
3
+ entries << string
4
+ end
5
+
6
+ def latest_entry
7
+ entries.last
8
+ end
9
+
10
+ private
11
+
12
+ def entries
13
+ @entries ||= []
14
+ end
15
+ end
16
+
@@ -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.3
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-16 00:00:00.000000000 Z
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: 860083072597597217
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: 860083072597597217
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