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 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