appsignal 0.8.15 → 0.9.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -2
  3. data/README.md +4 -0
  4. data/Rakefile +8 -0
  5. data/appsignal.gemspec +0 -1
  6. data/gemfiles/capistrano2.gemfile +5 -0
  7. data/gemfiles/capistrano3.gemfile +5 -0
  8. data/lib/appsignal.rb +10 -4
  9. data/lib/appsignal/agent.rb +5 -10
  10. data/lib/appsignal/capistrano.rb +8 -1
  11. data/lib/appsignal/config.rb +2 -1
  12. data/lib/appsignal/instrumentations/net_http.rb +15 -0
  13. data/lib/appsignal/integrations/capistrano/appsignal.cap +27 -0
  14. data/lib/appsignal/integrations/{capistrano.rb → capistrano/capistrano_2_tasks.rb} +2 -4
  15. data/lib/appsignal/integrations/capistrano/careful_logger.rb +1 -1
  16. data/lib/appsignal/integrations/delayed_job.rb +2 -4
  17. data/lib/appsignal/integrations/resque.rb +2 -4
  18. data/lib/appsignal/integrations/sidekiq.rb +2 -4
  19. data/lib/appsignal/marker.rb +1 -1
  20. data/lib/appsignal/rack/instrumentation.rb +1 -0
  21. data/lib/appsignal/rack/listener.rb +3 -4
  22. data/lib/appsignal/transaction.rb +16 -4
  23. data/lib/appsignal/version.rb +1 -1
  24. data/spec/lib/appsignal/agent_spec.rb +1 -23
  25. data/spec/lib/appsignal/config_spec.rb +2 -0
  26. data/spec/lib/appsignal/instrumentations/net_http_spec.rb +26 -0
  27. data/spec/lib/appsignal/integrations/capistrano2_spec.rb +178 -0
  28. data/spec/lib/appsignal/integrations/capistrano3_spec.rb +169 -0
  29. data/spec/lib/appsignal/integrations/resque_spec.rb +1 -1
  30. data/spec/lib/appsignal/marker_spec.rb +13 -10
  31. data/spec/lib/appsignal/transaction_spec.rb +34 -13
  32. data/spec/lib/appsignal_spec.rb +35 -0
  33. data/spec/lib/generators/appsignal/appsignal_generator_spec.rb +13 -14
  34. data/spec/spec_helper.rb +14 -0
  35. metadata +15 -21
  36. data/spec/lib/appsignal/integrations/capistrano_spec.rb +0 -151
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require File.expand_path('lib/appsignal/instrumentations/net_http')
3
+
4
+ describe "Net::HTTP instrumentation" do
5
+ let(:events) { [] }
6
+ before do
7
+ ActiveSupport::Notifications.subscribe(/^[^!]/) do |*args|
8
+ events << ActiveSupport::Notifications::Event.new(*args)
9
+ end
10
+ end
11
+
12
+ it "should instrument request" do
13
+ # We want to be absolutely sure the original method gets called correctly,
14
+ # so we actually do a HTTP request.
15
+ response = Net::HTTP.get_response(URI.parse('https://www.google.com'))
16
+
17
+ response.body.should include('google')
18
+
19
+ event = events.last
20
+ event.name.should == 'request.net_http'
21
+ event.payload[:host].should == 'www.google.com'
22
+ event.payload[:scheme].should == 'https'
23
+ event.payload[:path].should == '/'
24
+ event.payload[:method].should == 'GET'
25
+ end
26
+ end
@@ -0,0 +1,178 @@
1
+ require 'spec_helper'
2
+
3
+ if capistrano2_present?
4
+ require 'capistrano'
5
+ require 'capistrano/configuration'
6
+ require 'appsignal/capistrano'
7
+
8
+ describe "Capistrano 2 integration" do
9
+ let(:config) { project_fixture_config }
10
+
11
+ before :all do
12
+ @capistrano_config = Capistrano::Configuration.new
13
+ Appsignal::Integrations::Capistrano.tasks(@capistrano_config)
14
+ end
15
+
16
+ it "should have a deploy task" do
17
+ @capistrano_config.find_task('appsignal:deploy').should_not be_nil
18
+ end
19
+
20
+ describe "appsignal:deploy task" do
21
+ before do
22
+ @capistrano_config.set(:rails_env, 'production')
23
+ @capistrano_config.set(:repository, 'master')
24
+ @capistrano_config.set(:deploy_to, '/home/username/app')
25
+ @capistrano_config.set(:current_release, '')
26
+ @capistrano_config.set(:current_revision, '503ce0923ed177a3ce000005')
27
+ @capistrano_config.dry_run = false
28
+ ENV['USER'] = 'batman'
29
+ ENV['PWD'] = project_fixture_path
30
+ end
31
+
32
+ context "config" do
33
+ before do
34
+ @capistrano_config.dry_run = true
35
+ end
36
+
37
+ it "should be instantiated with the right params" do
38
+ Appsignal::Config.should_receive(:new).with(
39
+ project_fixture_path,
40
+ 'production',
41
+ {},
42
+ kind_of(Capistrano::Logger)
43
+ )
44
+ end
45
+
46
+ context "when appsignal_config is available" do
47
+ before do
48
+ @capistrano_config.set(:appsignal_config, :name => 'AppName')
49
+ end
50
+
51
+ it "should be instantiated with the right params" do
52
+ Appsignal::Config.should_receive(:new).with(
53
+ project_fixture_path,
54
+ 'production',
55
+ {:name => 'AppName'},
56
+ kind_of(Capistrano::Logger)
57
+ )
58
+ end
59
+
60
+ context "when rack_env is used instead of rails_env" do
61
+ before do
62
+ @capistrano_config.unset(:rails_env)
63
+ @capistrano_config.set(:rack_env, 'rack_production')
64
+ end
65
+
66
+ it "should be instantiated with the right params" do
67
+ Appsignal::Config.should_receive(:new).with(
68
+ project_fixture_path,
69
+ 'rack_production',
70
+ {:name => 'AppName'},
71
+ kind_of(Capistrano::Logger)
72
+ )
73
+ end
74
+ end
75
+ end
76
+
77
+ after { @capistrano_config.find_and_execute_task('appsignal:deploy') }
78
+ end
79
+
80
+ context "send marker" do
81
+ before :all do
82
+ @io = StringIO.new
83
+ @logger = Capistrano::Logger.new(:output => @io)
84
+ @logger.level = Capistrano::Logger::MAX_LEVEL
85
+ @capistrano_config.logger = @logger
86
+ end
87
+
88
+ let(:marker_data) do
89
+ {
90
+ :revision => '503ce0923ed177a3ce000005',
91
+ :user => 'batman'
92
+ }
93
+ end
94
+
95
+ context "when active for this environment" do
96
+ before do
97
+ @marker = Appsignal::Marker.new(
98
+ marker_data,
99
+ config,
100
+ @logger
101
+ )
102
+ Appsignal::Marker.stub(:new => @marker)
103
+ end
104
+
105
+ context "proper setup" do
106
+ before do
107
+ @transmitter = double
108
+ Appsignal::Transmitter.should_receive(:new).and_return(@transmitter)
109
+ end
110
+
111
+ it "should add the correct marker data" do
112
+ Appsignal::Marker.should_receive(:new).with(
113
+ marker_data,
114
+ kind_of(Appsignal::Config),
115
+ kind_of(Capistrano::Logger)
116
+ ).and_return(@marker)
117
+
118
+ @capistrano_config.find_and_execute_task('appsignal:deploy')
119
+ end
120
+
121
+ it "should transmit data" do
122
+ @transmitter.should_receive(:transmit).and_return('200')
123
+ @capistrano_config.find_and_execute_task('appsignal:deploy')
124
+ @io.string.should include('Notifying Appsignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman')
125
+ @io.string.should include('Appsignal has been notified of this deploy!')
126
+ end
127
+
128
+ context "with overridden revision" do
129
+ before do
130
+ @capistrano_config.set(:appsignal_revision, 'abc123')
131
+ end
132
+ it "should add the correct marker data" do
133
+ Appsignal::Marker.should_receive(:new).with(
134
+ {
135
+ :revision => 'abc123',
136
+ :user => 'batman'
137
+ },
138
+ kind_of(Appsignal::Config),
139
+ kind_of(Capistrano::Logger)
140
+ ).and_return(@marker)
141
+
142
+ @capistrano_config.find_and_execute_task('appsignal:deploy')
143
+ end
144
+ end
145
+ end
146
+
147
+ it "should not transmit data" do
148
+ @capistrano_config.find_and_execute_task('appsignal:deploy')
149
+ @io.string.should include('Notifying Appsignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman')
150
+ @io.string.should include('Something went wrong while trying to notify Appsignal:')
151
+ end
152
+
153
+ context "dry run" do
154
+ before { @capistrano_config.dry_run = true }
155
+
156
+ it "should not send deploy marker" do
157
+ @marker.should_not_receive(:transmit)
158
+ @capistrano_config.find_and_execute_task('appsignal:deploy')
159
+ @io.string.should include('Dry run: Deploy marker not actually sent.')
160
+ end
161
+ end
162
+ end
163
+
164
+ context "when not active for this environment" do
165
+ before do
166
+ @capistrano_config.set(:rails_env, 'nonsense')
167
+ end
168
+
169
+ it "should not send deploy marker" do
170
+ Appsignal::Marker.should_not_receive(:new)
171
+ @capistrano_config.find_and_execute_task('appsignal:deploy')
172
+ @io.string.should include("Not loading: config for 'nonsense' not found")
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,169 @@
1
+ require 'spec_helper'
2
+
3
+ if capistrano3_present?
4
+ require 'capistrano/all'
5
+ require 'capistrano/deploy'
6
+ require 'appsignal/capistrano'
7
+
8
+ include Capistrano::DSL
9
+
10
+ describe "Capistrano 3 integration" do
11
+ let(:config) { project_fixture_config }
12
+ let(:io) { StringIO.new }
13
+ let(:logger) { Logger.new(io) }
14
+
15
+ before do
16
+ @capistrano_config = Capistrano::Configuration.env
17
+ @capistrano_config.set(:log_level, :error)
18
+ @capistrano_config.set(:logger, logger)
19
+ end
20
+ before do
21
+ @original_stderr = $stderr
22
+ $stderr = io
23
+ end
24
+ after do
25
+ $stderr = @original_stderr
26
+ Rake::Task['appsignal:deploy'].reenable
27
+ end
28
+
29
+ it "should have a deploy task" do
30
+ Rake::Task.task_defined?('appsignal:deploy').should be_true
31
+ end
32
+
33
+ describe "appsignal:deploy task" do
34
+ before do
35
+ @capistrano_config.set(:rails_env, 'production')
36
+ @capistrano_config.set(:repository, 'master')
37
+ @capistrano_config.set(:deploy_to, '/home/username/app')
38
+ @capistrano_config.set(:current_release, '')
39
+ @capistrano_config.set(:current_revision, '503ce0923ed177a3ce000005')
40
+ ENV['USER'] = 'batman'
41
+ ENV['PWD'] = project_fixture_path
42
+ end
43
+
44
+ context "config" do
45
+ it "should be instantiated with the right params" do
46
+ Appsignal::Config.should_receive(:new).with(
47
+ project_fixture_path,
48
+ 'production',
49
+ {},
50
+ kind_of(Logger)
51
+ )
52
+ end
53
+
54
+ context "when appsignal_config is available" do
55
+ before do
56
+ @capistrano_config.set(:appsignal_config, :name => 'AppName')
57
+ end
58
+
59
+ it "should be instantiated with the right params" do
60
+ Appsignal::Config.should_receive(:new).with(
61
+ project_fixture_path,
62
+ 'production',
63
+ {:name => 'AppName'},
64
+ kind_of(Logger)
65
+ )
66
+ end
67
+
68
+ context "when rack_env is used instead of rails_env" do
69
+ before do
70
+ @capistrano_config.delete(:rails_env)
71
+ @capistrano_config.set(:rack_env, 'rack_production')
72
+ end
73
+
74
+ it "should be instantiated with the right params" do
75
+ Appsignal::Config.should_receive(:new).with(
76
+ project_fixture_path,
77
+ 'rack_production',
78
+ {:name => 'AppName'},
79
+ kind_of(Logger)
80
+ )
81
+ end
82
+ end
83
+ end
84
+
85
+ after { invoke('appsignal:deploy') }
86
+ end
87
+
88
+ context "send marker" do
89
+ let(:marker_data) do
90
+ {
91
+ :revision => '503ce0923ed177a3ce000005',
92
+ :user => 'batman'
93
+ }
94
+ end
95
+
96
+ context "when active for this environment" do
97
+ before do
98
+ @marker = Appsignal::Marker.new(
99
+ marker_data,
100
+ config,
101
+ logger
102
+ )
103
+ Appsignal::Marker.stub(:new => @marker)
104
+ end
105
+
106
+ context "proper setup" do
107
+ before do
108
+ @transmitter = double
109
+ Appsignal::Transmitter.should_receive(:new).and_return(@transmitter)
110
+ end
111
+
112
+ it "should add the correct marker data" do
113
+ Appsignal::Marker.should_receive(:new).with(
114
+ marker_data,
115
+ kind_of(Appsignal::Config),
116
+ kind_of(Logger)
117
+ ).and_return(@marker)
118
+
119
+ invoke('appsignal:deploy')
120
+ end
121
+
122
+ it "should transmit data" do
123
+ @transmitter.should_receive(:transmit).and_return('200')
124
+ invoke('appsignal:deploy')
125
+ io.string.should include('Notifying Appsignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman')
126
+ io.string.should include('ppsignal has been notified of this deploy!')
127
+ end
128
+
129
+ context "with overridden revision" do
130
+ before do
131
+ @capistrano_config.set(:appsignal_revision, 'abc123')
132
+ end
133
+ it "should add the correct marker data" do
134
+ Appsignal::Marker.should_receive(:new).with(
135
+ {
136
+ :revision => 'abc123',
137
+ :user => 'batman'
138
+ },
139
+ kind_of(Appsignal::Config),
140
+ kind_of(Logger)
141
+ ).and_return(@marker)
142
+
143
+ invoke('appsignal:deploy')
144
+ end
145
+ end
146
+ end
147
+
148
+ it "should not transmit data" do
149
+ invoke('appsignal:deploy')
150
+ io.string.should include('Notifying Appsignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman')
151
+ io.string.should include('Something went wrong while trying to notify Appsignal:')
152
+ end
153
+ end
154
+
155
+ context "when not active for this environment" do
156
+ before do
157
+ @capistrano_config.set(:rails_env, 'nonsense')
158
+ end
159
+
160
+ it "should not send deploy marker" do
161
+ Appsignal::Marker.should_not_receive(:new)
162
+ invoke('appsignal:deploy')
163
+ io.string.should include("Not loading: config for 'nonsense' not found")
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "ResquePlugin" do
3
+ describe "Resque integration" do
4
4
  let(:file) { File.expand_path('lib/appsignal/integrations/resque.rb') }
5
5
 
6
6
  context "with resque" do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'capistrano'
3
2
 
4
3
  describe Appsignal::Marker do
5
4
  let(:config) { project_fixture_config }
@@ -44,7 +43,7 @@ describe Appsignal::Marker do
44
43
 
45
44
  marker.transmit
46
45
 
47
- log.string.should include('Notifying Appsignal of deploy...')
46
+ log.string.should include('Notifying Appsignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman')
48
47
  log.string.should include('Appsignal has been notified of this deploy!')
49
48
  end
50
49
 
@@ -54,7 +53,7 @@ describe Appsignal::Marker do
54
53
 
55
54
  marker.transmit
56
55
 
57
- log.string.should include('Notifying Appsignal of deploy...')
56
+ log.string.should include('Notifying Appsignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman')
58
57
  log.string.should include(
59
58
  'Something went wrong while trying to notify Appsignal: 500 at http://localhost:3000/1/markers'
60
59
  )
@@ -66,14 +65,18 @@ describe Appsignal::Marker do
66
65
 
67
66
  it_should_behave_like "logging info and errors"
68
67
 
69
- context "with a Capistrano logger" do
70
- let(:logger) {
71
- Capistrano::Logger.new(:output => log).tap do |logger|
72
- logger.level = Capistrano::Logger::MAX_LEVEL
73
- end
74
- }
68
+ if capistrano2_present?
69
+ require 'capistrano'
75
70
 
76
- it_should_behave_like "logging info and errors"
71
+ context "with a Capistrano 2 logger" do
72
+ let(:logger) {
73
+ Capistrano::Logger.new(:output => log).tap do |logger|
74
+ logger.level = Capistrano::Logger::MAX_LEVEL
75
+ end
76
+ }
77
+
78
+ it_should_behave_like "logging info and errors"
79
+ end
77
80
  end
78
81
  end
79
82
  end
@@ -6,14 +6,16 @@ describe Appsignal::Transaction do
6
6
  end
7
7
 
8
8
  describe '.create' do
9
- before { Appsignal::Transaction.create('1', {}) }
9
+ subject { Appsignal::Transaction.create('1', {}) }
10
10
 
11
- it 'should add the id to the thread' do
11
+ it 'should add the request id to the thread local' do
12
+ subject
12
13
  Thread.current[:appsignal_transaction_id].should == '1'
13
14
  end
14
15
 
15
- it 'should add the transaction to the list' do
16
- Appsignal.transactions['1'].should be_a Appsignal::Transaction
16
+ it "should create a transaction" do
17
+ subject.should be_a Appsignal::Transaction
18
+ subject.request_id.should == '1'
17
19
  end
18
20
  end
19
21
 
@@ -27,6 +29,28 @@ describe Appsignal::Transaction do
27
29
  end
28
30
  end
29
31
 
32
+ describe "complete_current!" do
33
+ before { Thread.current[:appsignal_transaction_id] = nil }
34
+
35
+ context "with a current transaction" do
36
+ before { Appsignal::Transaction.create('2', {}) }
37
+
38
+ it "should complete the current transaction and reset the thread appsignal_transaction_id" do
39
+ Appsignal::Transaction.current.should_receive(:complete!)
40
+
41
+ Appsignal::Transaction.complete_current!
42
+
43
+ Thread.current[:appsignal_transaction_id].should be_nil
44
+ end
45
+ end
46
+
47
+ context "without a current transaction" do
48
+ it "should not raise an error" do
49
+ Appsignal::Transaction.complete_current!
50
+ end
51
+ end
52
+ end
53
+
30
54
  context "with transaction instance" do
31
55
  let(:env) do
32
56
  {
@@ -36,7 +60,12 @@ describe Appsignal::Transaction do
36
60
  'HTTP_X_REQUEST_START' => '1000000'
37
61
  }
38
62
  end
39
- let(:transaction) { Appsignal::Transaction.create('1', env) }
63
+ let(:transaction) { Appsignal::Transaction.create('3', env) }
64
+
65
+ it "should add the transaction to the list" do
66
+ transaction
67
+ Appsignal.transactions['3'].should == transaction
68
+ end
40
69
 
41
70
  describe '#request' do
42
71
  subject { transaction.request }
@@ -324,14 +353,6 @@ describe Appsignal::Transaction do
324
353
  after { transaction.complete! }
325
354
  end
326
355
 
327
- context 'thread' do
328
- before { transaction.complete! }
329
-
330
- it 'should reset the thread transaction id' do
331
- Thread.current[:appsignal_transaction_id].should be_nil
332
- end
333
- end
334
-
335
356
  context 'when using pipes' do
336
357
  let(:pipe) { double }
337
358
  before { Appsignal::Pipe.stub(:current => pipe) }