instrumental 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rake', '0.8.7'
4
+ gem 'rspec'
5
+ gem 'jeweler'
@@ -0,0 +1,26 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.6.2)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.8.7)
11
+ rspec (2.6.0)
12
+ rspec-core (~> 2.6.0)
13
+ rspec-expectations (~> 2.6.0)
14
+ rspec-mocks (~> 2.6.0)
15
+ rspec-core (2.6.2)
16
+ rspec-expectations (2.6.0)
17
+ diff-lcs (~> 1.1.2)
18
+ rspec-mocks (2.6.0)
19
+
20
+ PLATFORMS
21
+ ruby
22
+
23
+ DEPENDENCIES
24
+ jeweler
25
+ rake (= 0.8.7)
26
+ rspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Shearer Consultancy Ltd.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,3 @@
1
+ For setup and configuration information, please see:
2
+
3
+ http://imperialapp.com/pages/ruby_on_rails
@@ -0,0 +1,34 @@
1
+ require 'rake'
2
+ require 'rspec/core/rake_task'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :spec
7
+
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = 'spec/**/*_spec.rb'
10
+ end
11
+
12
+ desc 'Generate documentation for the instrumental plugin.'
13
+ Rake::RDocTask.new(:rdoc) do |rdoc|
14
+ rdoc.rdoc_dir = 'rdoc'
15
+ rdoc.title = 'Instrumental'
16
+ rdoc.options << '--line-numbers' << '--inline-source'
17
+ rdoc.rdoc_files.include('README')
18
+ rdoc.rdoc_files.include('lib/**/*.rb')
19
+ end
20
+
21
+ desc "Default: run the specs"
22
+ task :default => [:spec]
23
+
24
+ begin
25
+ require 'jeweler'
26
+ Jeweler::Tasks.new do |s|
27
+ s.name = "instrumental"
28
+ s.summary = s.description = "Rails instrumentation and client for imperialapp.com"
29
+ s.email = "support@imperialapp.com"
30
+ s.homepage = "http://github.com/imperialapp/instrumental"
31
+ s.authors = ["Douglas F Shearer"]
32
+ s.files = `git ls-files`.split("\n")
33
+ end
34
+ end
data/TODO ADDED
@@ -0,0 +1,3 @@
1
+ Allow to be loaded in any rack app.
2
+ specs for everything
3
+ generator for config
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.4
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'instrumental'
@@ -0,0 +1,66 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{instrumental}
8
+ s.version = "0.1.4"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Douglas F Shearer"]
12
+ s.date = %q{2011-06-06}
13
+ s.description = %q{Rails instrumentation and client for imperialapp.com}
14
+ s.email = %q{support@imperialapp.com}
15
+ s.extra_rdoc_files = [
16
+ "README",
17
+ "TODO"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "MIT-LICENCE",
23
+ "README",
24
+ "Rakefile",
25
+ "TODO",
26
+ "VERSION",
27
+ "init.rb",
28
+ "instrumental.gemspec",
29
+ "lib/instrumental.rb",
30
+ "lib/instrumental/agent.rb",
31
+ "lib/instrumental/configuration.rb",
32
+ "lib/instrumental/instrument.rb",
33
+ "lib/instrumental/intervalometer.rb",
34
+ "lib/tasks/install.rake",
35
+ "lib/tasks/templates/instrumental.rb.erb",
36
+ "spec/instrumental/agent_spec.rb",
37
+ "spec/instrumental/configuration_spec.rb",
38
+ "spec/instrumental/instrument_methods_spec.rb",
39
+ "spec/instrumental/intervalometer_spec.rb",
40
+ "spec/instrumental/setup_methods_spec.rb",
41
+ "spec/spec_helper.rb"
42
+ ]
43
+ s.homepage = %q{http://github.com/imperialapp/instrumental}
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = %q{1.6.2}
46
+ s.summary = %q{Rails instrumentation and client for imperialapp.com}
47
+
48
+ if s.respond_to? :specification_version then
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<rake>, ["= 0.8.7"])
53
+ s.add_runtime_dependency(%q<rspec>, [">= 0"])
54
+ s.add_runtime_dependency(%q<jeweler>, [">= 0"])
55
+ else
56
+ s.add_dependency(%q<rake>, ["= 0.8.7"])
57
+ s.add_dependency(%q<rspec>, [">= 0"])
58
+ s.add_dependency(%q<jeweler>, [">= 0"])
59
+ end
60
+ else
61
+ s.add_dependency(%q<rake>, ["= 0.8.7"])
62
+ s.add_dependency(%q<rspec>, [">= 0"])
63
+ s.add_dependency(%q<jeweler>, [">= 0"])
64
+ end
65
+ end
66
+
@@ -0,0 +1,53 @@
1
+ require 'instrumental/agent'
2
+ require 'instrumental/configuration'
3
+ require 'instrumental/intervalometer'
4
+ require 'instrumental/instrument'
5
+
6
+ module Instrumental
7
+
8
+ @config = Configuration.new
9
+
10
+ def self.configure
11
+ yield @config
12
+ end
13
+
14
+ def self.boot!
15
+ if @config.enabled?
16
+
17
+ if defined?(PhusionPassenger)
18
+ PhusionPassenger.on_event(:starting_worker_process) do
19
+ @config.logger.debug('Starting a new worker process')
20
+ Agent.instance.setup_and_run
21
+ end
22
+
23
+ PhusionPassenger.on_event(:stopping_worker_process) do
24
+ @config.logger.debug('Killing worker process')
25
+ Agent.instance.stop
26
+ end
27
+
28
+ else
29
+ @config.logger.debug('Starting a new worker process')
30
+ Agent.instance.setup_and_run
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.config
36
+ @config
37
+ end
38
+
39
+ def self.count(name, value=1)
40
+ Agent.instance.report(:count, name, value)
41
+ end
42
+
43
+ def self.measure(name, value)
44
+ Agent.instance.report(:measure, name, value)
45
+ end
46
+
47
+ def self.timer(name)
48
+ start_time = Time.now
49
+ yield
50
+ self.measure(name, Time.now - start_time)
51
+ end
52
+
53
+ end
@@ -0,0 +1,100 @@
1
+ require 'singleton'
2
+ require 'net/http'
3
+ require 'cgi'
4
+
5
+ module Instrumental
6
+ class Agent
7
+ include Singleton
8
+
9
+ @@queue = { :count => {}, :measure => {} }
10
+ @@queue_mutex = Mutex.new
11
+
12
+ def report(type, name, value)
13
+ # TODO: Print this to log?
14
+ return nil unless config && config.enabled?
15
+
16
+ type = type.to_sym
17
+ @@queue_mutex.synchronize do
18
+ if type == :count
19
+ @@queue[:count][name] ||= 0
20
+ @@queue[:count][name] += value
21
+ else
22
+ @@queue[:measure][name] ||= []
23
+ @@queue[:measure][name] << value
24
+ end
25
+ end
26
+ end
27
+
28
+ def setup_and_run
29
+ @intervalometer = Intervalometer.new(config.report_interval)
30
+
31
+ config.logger.debug("Starting agent. Reporting every #{config.report_interval} seconds")
32
+ @thread = Thread.new do
33
+ begin
34
+ @intervalometer.run do
35
+ config.logger.debug('Intervalometer run')
36
+ new_queue_items = {}
37
+ @@queue_mutex.synchronize do
38
+ new_queue_items = @@queue.dup
39
+ @@queue[:count] = {}
40
+ @@queue[:measure] = {}
41
+ config.logger.debug("Queue contains #{new_queue_items.inspect}")
42
+ end
43
+
44
+ new_queue_items[:count].each do |name, value|
45
+ send_report(:count, name, value)
46
+ end
47
+
48
+ new_queue_items[:measure].each do |name, values|
49
+ send_report(:measure, name, values.join(','))
50
+ end
51
+ end
52
+ rescue => e
53
+ config.logger.error e
54
+ config.logger.error e.backtrace.join("\n")
55
+ end
56
+ end
57
+ end
58
+
59
+ def stop
60
+ # If the app crashes, Passenger calls halt as it winds-down the process.
61
+ # Only call halt if intervalometer exists.
62
+ @intervalometer && @intervalometer.halt
63
+ end
64
+
65
+ protected
66
+
67
+ def config
68
+ Instrumental.config
69
+ end
70
+
71
+ def send_report(type, name, value)
72
+ if type == :measure
73
+ attributes = { :values => value }
74
+ else
75
+ attributes = { :value => value }
76
+ end
77
+
78
+ attributes[:name] = URI.escape("#{ config.name_prefix }#{ name }")
79
+ attributes[:api_key] = config.api_key
80
+
81
+ # attributes_string = attributes.to_a.map{ |a| a.join('=') }.join('&')
82
+
83
+ path = "#{ config.path }#{ type }"
84
+ # config.logger.debug("Calling #{ path }")
85
+
86
+ response = post_response(path, attributes)
87
+
88
+ unless response.is_a?(Net::HTTPSuccess)
89
+ config.logger.error "[Instrumental] Unexpected response from server (#{ response.code }): #{ response.message }"
90
+ end
91
+ end
92
+
93
+ def post_response(path, params)
94
+ req = Net::HTTP::Post.new(path)
95
+ req.set_form_data(params)
96
+ Net::HTTP.new(config.host, config.port).start { |h| h.request(req) }
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,70 @@
1
+ require 'logger'
2
+
3
+ module Instrumental
4
+ class Configuration
5
+
6
+ DEFAULT_REPORT_INTERVAL = 15.0
7
+
8
+ attr_reader :host
9
+ attr_reader :port
10
+ attr_reader :path
11
+ attr_reader :report_interval
12
+ attr_accessor :enabled
13
+ attr_writer :logger
14
+ attr_accessor :name_prefix
15
+
16
+ def initialize
17
+ @enabled = defined?(::Rails.env) ? Rails.env.production? : true
18
+ @host = 'in.imperialapp.com'
19
+ @port = 80
20
+ @name_prefix = ''
21
+ @path = '/in/'
22
+ @report_interval = DEFAULT_REPORT_INTERVAL
23
+ end
24
+
25
+ def enabled?
26
+ !!@enabled
27
+ end
28
+
29
+ def host=(val)
30
+ @host = val
31
+
32
+ raise(ArgumentError, "host is invalid") unless @host =~ /^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?)?$/ix
33
+ end
34
+
35
+ def port=(val)
36
+ @port = val
37
+
38
+ raise(ArgumentError, "port must be an integer greater than 0") unless @port.to_i > 0
39
+ end
40
+
41
+ def path=(val)
42
+ @path = val
43
+
44
+ raise(ArgumentError, 'path is invalid') unless @path =~ /^\/(.+\/)?$/
45
+ end
46
+
47
+ def report_interval=(val)
48
+ @report_interval = val.to_f
49
+
50
+ raise(ArgumentError, "report_interval should be greater than or equal to #{DEFAULT_REPORT_INTERVAL}") if @report_interval < DEFAULT_REPORT_INTERVAL
51
+ end
52
+
53
+ def api_key=(val)
54
+ @api_key = val
55
+
56
+ raise(ArgumentError, 'API key is invalid') unless @api_key =~ /^[a-f\d]{32}$/
57
+ end
58
+
59
+ def api_key
60
+ @api_key || raise(ArgumentError, 'API key must be set in configuration')
61
+ end
62
+
63
+ def logger
64
+ # The Rails logger is not available in an initializer, so we have to look for on-demand.
65
+ @logger ||= defined?(::Rails.logger) ? Rails.logger : Logger.new(STDOUT)
66
+ @logger
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,19 @@
1
+ module Instrumental
2
+ module Instrument
3
+
4
+ def self.count(name, value=1)
5
+ Agent.instance.report(:count, name, value)
6
+ end
7
+
8
+ def self.measure(name, value)
9
+ Agent.instance.report(:measure, name, value)
10
+ end
11
+
12
+ def self.timer(name)
13
+ start_time = Time.now
14
+ yield
15
+ self.measure(name, Time.now - start_time)
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ module Instrumental
2
+ class Intervalometer
3
+
4
+ def initialize(period=60.0)
5
+ @period = period.to_f
6
+ @running = true
7
+ @run_next = Time.now
8
+ end
9
+
10
+ def halt
11
+ # TODO: See if it would be possible for the intervalometer to do a
12
+ # final run before the thread exits.
13
+ @running = false
14
+ end
15
+
16
+ # Runs a passed block at intervals defined by the period set during
17
+ # initialization. Uses intervalometer to keep reasonably precise intervals.
18
+ def run
19
+ while @running
20
+ if Time.now < @run_next
21
+ sleep @run_next - Time.now
22
+ end
23
+
24
+ @run_next = Time.now + @period
25
+ yield
26
+ end
27
+ end # run
28
+
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ namespace :instrumental do
2
+
3
+ desc 'Installs the configuration initializer'
4
+ task :install do
5
+ unless ENV.include?('api_key')
6
+ raise "usage: rake instrumental:install api_key=YOUR_API_KEY"
7
+ end
8
+
9
+ api_key = ENV['api_key']
10
+ template_path = File.expand_path(File.join(File.dirname(__FILE__), 'templates', 'instrumental.rb.erb'))
11
+ template = ERB.new(File.read(template_path))
12
+ location = File.join('config', 'initializers', 'instrumental.rb')
13
+
14
+ File.open(location, 'w+') do |f|
15
+ f.write template.result(binding)
16
+ end
17
+
18
+ puts 'Instrumental Installed!'
19
+ puts "Configuration written to #{location}"
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,4 @@
1
+ Instrumental.configure do |config|
2
+ config.api_key = "<%= api_key %>"
3
+ end
4
+ Instrumental.boot!
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'instrumental/agent'
3
+
4
+ include Instrumental
5
+
6
+ describe Instrumental::Agent do
7
+
8
+ describe "report" do
9
+
10
+ end
11
+
12
+ describe "setup_and_run" do
13
+
14
+ end
15
+
16
+ describe "stop" do
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,245 @@
1
+ require 'spec_helper'
2
+ require 'instrumental/configuration'
3
+
4
+ include Instrumental
5
+
6
+ class Rails;end # Used for testing the logger.
7
+
8
+ describe Instrumental::Configuration do
9
+
10
+ before(:each) do
11
+ @config = Configuration.new
12
+ end
13
+
14
+ describe "in the default state" do
15
+ it "should raise an argument error for the missing API key" do
16
+ lambda { @config.api_key }.should raise_error(ArgumentError, 'API key must be set in configuration')
17
+ end
18
+
19
+ it "should have a host" do
20
+ @config.host.should == 'in.imperialapp.com'
21
+ end
22
+
23
+ it "should have a port" do
24
+ @config.port.should == 80
25
+ end
26
+
27
+ it "should have a path" do
28
+ @config.path.should == '/in/'
29
+ end
30
+
31
+ it "should have a report interval" do
32
+ @config.report_interval.should == 15.0
33
+ end
34
+
35
+ it "should have a logger" do
36
+ @config.logger.should be_a(Logger)
37
+ end
38
+
39
+ it "should have enabled set to true" do
40
+ @config.logger.should be_true
41
+ end
42
+
43
+ it "should have an empty name prefix" do
44
+ @config.name_prefix.should be_empty
45
+ end
46
+ end
47
+
48
+ describe "where Rails is defined" do
49
+ context "production environment" do
50
+ before(:each) do
51
+ Rails.stub(:logger).and_return(@mock_logger = mock(:logger))
52
+ Rails.stub(:env).and_return(mock(:environment, :production? => true))
53
+ @rails_config = Configuration.new
54
+ end
55
+
56
+ it "should be the mock logger" do
57
+ @rails_config.logger.should == @mock_logger
58
+ end
59
+
60
+ it "should have enabled as true" do
61
+ @rails_config.enabled.should be_true
62
+ end
63
+ end
64
+
65
+ context "non-production environment" do
66
+ before(:each) do
67
+ Rails.stub(:env).and_return(mock(:environment, :production? => false))
68
+ @rails_config = Configuration.new
69
+ end
70
+
71
+ it "should have enabled as false" do
72
+ @rails_config.enabled.should be_false
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "Setting the API key" do
78
+ context "with a valid key" do
79
+ before(:each) do
80
+ @config.api_key = '01e694159b73a5f3784bbe9d63412b8d'
81
+ end
82
+
83
+ it "should not raise an error" do
84
+ lambda { @config.api_key }.should_not raise_error
85
+ end
86
+
87
+ it "should have an API key" do
88
+ @config.api_key.should == '01e694159b73a5f3784bbe9d63412b8d'
89
+ end
90
+ end
91
+
92
+ %w{cheese 123 01e694159b73a5f3784bbe9d63412b8 01e694159b73a5f3784bbe9d63412b8D}.each do |invalid_key|
93
+ context "with invalid key, #{invalid_key}," do
94
+ it "should raise an argument error" do
95
+ lambda { @config.api_key = invalid_key }.should raise_error(ArgumentError, 'API key is invalid')
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "Setting the report_interval" do
102
+ context "with a valid value" do
103
+ it "should not raise an error" do
104
+ lambda { @config.report_interval = 20.1 }.should_not raise_error
105
+ end
106
+
107
+ it "should have the report_interval set" do
108
+ @config.report_interval = 20.1
109
+ @config.report_interval.should == 20.1
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "Setting the host" do
115
+ %w{in.imperialapp.com foo.bar.com foo.bar.rar.me}.each do |valid_host|
116
+ context "with a valid host, #{valid_host}" do
117
+ it "should not raise an error" do
118
+ lambda { @config.host = valid_host }.should_not raise_error
119
+ end
120
+
121
+ it "should have the host set" do
122
+ @config.host = valid_host
123
+ @config.host.should == valid_host
124
+ end
125
+ end
126
+ end
127
+
128
+ %w{in.imperialapp.com/ http://in.imperialapp.com mince}.each do |invalid_host|
129
+ context "with invalid host, #{invalid_host}," do
130
+ it "should raise an argument error" do
131
+ lambda { @config.host = invalid_host }.should raise_error(ArgumentError, 'host is invalid')
132
+ end
133
+ end
134
+ end
135
+
136
+ context "with a blank host" do
137
+ it "should raise an argument error" do
138
+ lambda { @config.host = '' }.should raise_error(ArgumentError, 'host is invalid')
139
+ end
140
+ end
141
+ end
142
+
143
+ describe "Setting the port" do
144
+ context "with a valid port" do
145
+ it "should not raise an error" do
146
+ lambda { @config.port = 3000 }.should_not raise_error
147
+ end
148
+
149
+ it "should have the port set" do
150
+ @config.port = 3000
151
+ @config.port.should == 3000
152
+ end
153
+ end
154
+
155
+ context "with an invalid port" do
156
+ it "should raise an argument error for a string" do
157
+ lambda { @config.port = 'mince' }.should raise_error(ArgumentError, 'port must be an integer greater than 0')
158
+ end
159
+
160
+ it "should raise an argument error for nil" do
161
+ lambda { @config.port = nil }.should raise_error(ArgumentError, 'port must be an integer greater than 0')
162
+ end
163
+
164
+ it "should raise an argument error for 0" do
165
+ lambda { @config.port = 0 }.should raise_error(ArgumentError, 'port must be an integer greater than 0')
166
+ end
167
+ end
168
+ end
169
+
170
+ describe "Setting the path" do
171
+ %w{/ /foo/ /bar/rar/ /23/}.each do |valid_path|
172
+ context "with a valid path, #{valid_path}" do
173
+ it "should not raise an error" do
174
+ lambda { @config.path = valid_path }.should_not raise_error
175
+ end
176
+
177
+ it "should have the path set" do
178
+ @config.path = valid_path
179
+ @config.path.should == valid_path
180
+ end
181
+ end
182
+ end
183
+
184
+ %w{// bar/ /bar bar}.each do |invalid_path|
185
+ context "with invalid path, #{invalid_path}," do
186
+ it "should raise an argument error" do
187
+ lambda { @config.path = invalid_path }.should raise_error(ArgumentError, 'path is invalid')
188
+ end
189
+ end
190
+ end
191
+
192
+ context "with a blank path" do
193
+ it "should raise an argument error" do
194
+ lambda { @config.path = '' }.should raise_error(ArgumentError, 'path is invalid')
195
+ end
196
+ end
197
+ end
198
+
199
+ describe "setting the logger" do
200
+ it "should have the logger set" do
201
+ @config.logger = 'foo'
202
+ @config.logger.should == 'foo'
203
+ end
204
+ end
205
+
206
+ describe "setting enabled" do
207
+ before(:each) do
208
+ @config.enabled = 'non nil value'
209
+ end
210
+
211
+ it "should have the enabled status set" do
212
+ @config.enabled.should == 'non nil value'
213
+ end
214
+ end
215
+
216
+ describe "enabled?" do
217
+ it "should be false for nil" do
218
+ @config.enabled = nil
219
+ @config.should_not be_enabled
220
+ end
221
+
222
+ it "should be false for false" do
223
+ @config.enabled = false
224
+ @config.should_not be_enabled
225
+ end
226
+
227
+ it "should be true for true" do
228
+ @config.enabled = true
229
+ @config.should be_enabled
230
+ end
231
+
232
+ it "should be true for other values" do
233
+ @config.enabled = 'non nil value'
234
+ @config.should be_enabled
235
+ end
236
+ end
237
+
238
+ describe "setting the name_prefix" do
239
+ it "should have the name_prefix set" do
240
+ @config.name_prefix = 'my prefix'
241
+ @config.name_prefix.should == 'my prefix'
242
+ end
243
+ end
244
+
245
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+ require 'instrumental'
3
+
4
+ class Agent;end
5
+
6
+ describe 'public instrument methods' do
7
+
8
+ before(:each) do
9
+ Agent.stub(:instance).and_return(@mock_agent_instance = mock(:agent_instance))
10
+ end
11
+
12
+ describe "count" do
13
+ context "without a value" do
14
+ it "should send a value of 1" do
15
+ @mock_agent_instance.should_receive(:report).with(:count, 'my name', 1)
16
+
17
+ Instrument.count('my name')
18
+ end
19
+ end
20
+
21
+ context "with a value" do
22
+ it "should send the passed value" do
23
+ @mock_agent_instance.should_receive(:report).with(:count, 'my name', 23)
24
+
25
+ Instrument.count('my name', 23)
26
+ end
27
+ end
28
+ end
29
+
30
+ describe "measure" do
31
+ it "should send the passed value" do
32
+ @mock_agent_instance.should_receive(:report).with(:measure, 'my name', 19.2)
33
+
34
+ Instrument.measure('my name', 19.2)
35
+ end
36
+ end
37
+
38
+ describe "timer" do
39
+ it "should send the calculated time" do
40
+ delta = 1.574
41
+ Time.should_receive(:now).and_return(0)
42
+ Time.should_receive(:now).and_return(delta)
43
+
44
+ @mock_agent_instance.should_receive(:report).with(:measure, 'my name', delta)
45
+
46
+ Instrument.timer('my name') { 'do stuff' }
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'instrumental/intervalometer'
3
+
4
+ include Instrumental
5
+
6
+ describe Instrumental::Intervalometer do
7
+
8
+ describe "initialize" do
9
+
10
+ end
11
+
12
+ describe "halt" do
13
+
14
+ end
15
+
16
+ describe "run" do
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'instrumental'
3
+
4
+ describe 'setup methods' do
5
+
6
+ describe "configure" do
7
+
8
+ # Speccing yield. http://awesomeful.net/posts/75-spec-your-yields-in-rspec
9
+ it "should call yield" do
10
+ # Instrumental.should_receive(:yield).with(instance_of(Instrumental::Configuration))
11
+ #
12
+ # Instrumental.configure do |c|
13
+ # c.api_key = 'foo foo'
14
+ # end
15
+ end
16
+
17
+
18
+ end
19
+
20
+ describe "boot" do
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1 @@
1
+ require 'rspec/core'
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: instrumental
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 4
10
+ version: 0.1.4
11
+ platform: ruby
12
+ authors:
13
+ - Douglas F Shearer
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-06-06 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rake
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 49
30
+ segments:
31
+ - 0
32
+ - 8
33
+ - 7
34
+ version: 0.8.7
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :runtime
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: jeweler
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ description: Rails instrumentation and client for imperialapp.com
66
+ email: support@imperialapp.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - README
73
+ - TODO
74
+ files:
75
+ - Gemfile
76
+ - Gemfile.lock
77
+ - MIT-LICENCE
78
+ - README
79
+ - Rakefile
80
+ - TODO
81
+ - VERSION
82
+ - init.rb
83
+ - instrumental.gemspec
84
+ - lib/instrumental.rb
85
+ - lib/instrumental/agent.rb
86
+ - lib/instrumental/configuration.rb
87
+ - lib/instrumental/instrument.rb
88
+ - lib/instrumental/intervalometer.rb
89
+ - lib/tasks/install.rake
90
+ - lib/tasks/templates/instrumental.rb.erb
91
+ - spec/instrumental/agent_spec.rb
92
+ - spec/instrumental/configuration_spec.rb
93
+ - spec/instrumental/instrument_methods_spec.rb
94
+ - spec/instrumental/intervalometer_spec.rb
95
+ - spec/instrumental/setup_methods_spec.rb
96
+ - spec/spec_helper.rb
97
+ has_rdoc: true
98
+ homepage: http://github.com/imperialapp/instrumental
99
+ licenses: []
100
+
101
+ post_install_message:
102
+ rdoc_options: []
103
+
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 3
121
+ segments:
122
+ - 0
123
+ version: "0"
124
+ requirements: []
125
+
126
+ rubyforge_project:
127
+ rubygems_version: 1.6.2
128
+ signing_key:
129
+ specification_version: 3
130
+ summary: Rails instrumentation and client for imperialapp.com
131
+ test_files: []
132
+