appsignal 0.6.7 → 0.7.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +3 -2
  3. data/.travis.yml +11 -11
  4. data/CHANGELOG.md +6 -0
  5. data/README.md +26 -0
  6. data/Rakefile +32 -3
  7. data/appsignal.gemspec +25 -16
  8. data/gemfiles/no_dependencies.gemfile +3 -0
  9. data/gemfiles/{3.0.gemfile → rails-3.0.gemfile} +2 -1
  10. data/gemfiles/{3.1.gemfile → rails-3.1.gemfile} +2 -1
  11. data/gemfiles/{3.2.gemfile → rails-3.2.gemfile} +2 -1
  12. data/gemfiles/{4.0.gemfile → rails-4.0.gemfile} +2 -1
  13. data/gemfiles/sinatra.gemfile +5 -0
  14. data/lib/appsignal.rb +30 -25
  15. data/lib/appsignal/agent.rb +37 -17
  16. data/lib/appsignal/aggregator.rb +2 -4
  17. data/lib/appsignal/aggregator/middleware.rb +4 -0
  18. data/lib/appsignal/aggregator/middleware/action_view_sanitizer.rb +23 -0
  19. data/lib/appsignal/aggregator/middleware/active_record_sanitizer.rb +64 -0
  20. data/lib/appsignal/aggregator/middleware/chain.rb +101 -0
  21. data/lib/appsignal/aggregator/middleware/delete_blanks.rb +16 -0
  22. data/lib/appsignal/aggregator/post_processor.rb +21 -18
  23. data/lib/appsignal/auth_check.rb +7 -21
  24. data/lib/appsignal/capistrano.rb +1 -36
  25. data/lib/appsignal/cli.rb +30 -46
  26. data/lib/appsignal/config.rb +46 -61
  27. data/lib/appsignal/integrations/capistrano.rb +44 -0
  28. data/lib/appsignal/{careful_logger.rb → integrations/capistrano/careful_logger.rb} +2 -0
  29. data/lib/appsignal/integrations/passenger.rb +6 -6
  30. data/lib/appsignal/integrations/rails.rb +33 -0
  31. data/lib/appsignal/integrations/sinatra.rb +20 -0
  32. data/lib/appsignal/marker.rb +9 -10
  33. data/lib/appsignal/rack/instrumentation.rb +28 -0
  34. data/lib/appsignal/rack/listener.rb +33 -0
  35. data/lib/appsignal/transaction.rb +18 -12
  36. data/lib/appsignal/transaction/formatter.rb +96 -0
  37. data/lib/appsignal/transaction/params_sanitizer.rb +80 -78
  38. data/lib/appsignal/transmitter.rb +10 -9
  39. data/lib/appsignal/version.rb +1 -1
  40. data/lib/generators/appsignal/appsignal_generator.rb +20 -21
  41. data/lib/generators/appsignal/templates/appsignal.yml +15 -21
  42. data/spec/{appsignal → lib/appsignal}/agent_spec.rb +69 -1
  43. data/spec/lib/appsignal/aggregator/middleware/action_view_sanitizer_spec.rb +32 -0
  44. data/spec/lib/appsignal/aggregator/middleware/active_record_sanitizer_spec.rb +215 -0
  45. data/spec/{appsignal → lib/appsignal/aggregator}/middleware/chain_spec.rb +5 -5
  46. data/spec/{appsignal → lib/appsignal/aggregator}/middleware/delete_blanks_spec.rb +2 -2
  47. data/spec/{appsignal → lib/appsignal}/aggregator/post_processor_spec.rb +15 -6
  48. data/spec/{appsignal → lib/appsignal}/aggregator_spec.rb +4 -1
  49. data/spec/{appsignal → lib/appsignal}/auth_check_spec.rb +8 -23
  50. data/spec/{appsignal → lib/appsignal}/cli_spec.rb +65 -66
  51. data/spec/lib/appsignal/config_spec.rb +132 -0
  52. data/spec/lib/appsignal/integrations/capistrano_spec.rb +123 -0
  53. data/spec/{appsignal → lib/appsignal}/integrations/passenger_spec.rb +0 -1
  54. data/spec/lib/appsignal/integrations/rails_spec.rb +38 -0
  55. data/spec/lib/appsignal/integrations/sinatra_spec.rb +43 -0
  56. data/spec/{appsignal → lib/appsignal}/marker_spec.rb +20 -23
  57. data/spec/lib/appsignal/rack/instrumentation_spec.rb +49 -0
  58. data/spec/{appsignal → lib/appsignal/rack}/listener_spec.rb +39 -6
  59. data/spec/{appsignal/transaction/transaction_formatter_spec.rb → lib/appsignal/transaction/formatter_spec.rb} +29 -6
  60. data/spec/{appsignal → lib/appsignal}/transaction/params_sanitizer_spec.rb +13 -12
  61. data/spec/{appsignal → lib/appsignal}/transaction_spec.rb +52 -7
  62. data/spec/{appsignal → lib/appsignal}/transmitter_spec.rb +27 -20
  63. data/spec/lib/appsignal_spec.rb +230 -0
  64. data/spec/lib/generators/appsignal/appsignal_generator_spec.rb +166 -0
  65. data/spec/lib/tmp/config/appsignal.yml +2 -0
  66. data/spec/spec_helper.rb +29 -20
  67. data/spec/support/delegate_matcher.rb +0 -1
  68. data/spec/support/fixtures/generated_config.yml +20 -0
  69. data/{log/.gitkeep → spec/support/fixtures/uploaded_file.txt} +0 -0
  70. data/spec/support/helpers/config_helpers.rb +24 -0
  71. data/spec/support/helpers/notification_helpers.rb +0 -2
  72. data/spec/support/helpers/transaction_helpers.rb +17 -2
  73. data/spec/support/project_fixture/config/appsignal.yml +18 -0
  74. data/spec/support/project_fixture/log/.gitkeep +0 -0
  75. data/spec/support/rails/my_app.rb +6 -0
  76. metadata +99 -83
  77. data/config/appsignal.yml +0 -10
  78. data/lib/appsignal/listener.rb +0 -21
  79. data/lib/appsignal/middleware.rb +0 -3
  80. data/lib/appsignal/middleware/action_view_sanitizer.rb +0 -21
  81. data/lib/appsignal/middleware/active_record_sanitizer.rb +0 -62
  82. data/lib/appsignal/middleware/chain.rb +0 -99
  83. data/lib/appsignal/middleware/delete_blanks.rb +0 -12
  84. data/lib/appsignal/railtie.rb +0 -37
  85. data/lib/appsignal/to_appsignal_hash.rb +0 -21
  86. data/lib/appsignal/transaction/transaction_formatter.rb +0 -67
  87. data/spec/appsignal/capistrano_spec.rb +0 -81
  88. data/spec/appsignal/config_spec.rb +0 -177
  89. data/spec/appsignal/inactive_railtie_spec.rb +0 -32
  90. data/spec/appsignal/middleware/action_view_sanitizer_spec.rb +0 -27
  91. data/spec/appsignal/middleware/active_record_sanitizer_spec.rb +0 -212
  92. data/spec/appsignal/railtie_spec.rb +0 -74
  93. data/spec/appsignal/to_appsignal_hash_spec.rb +0 -29
  94. data/spec/appsignal_spec.rb +0 -195
  95. data/spec/generators/appsignal/appsignal_generator_spec.rb +0 -181
@@ -1,74 +0,0 @@
1
- require 'spec_helper'
2
- require 'action_controller/railtie'
3
- require 'appsignal/railtie'
4
-
5
- describe Appsignal::Railtie do
6
- it "should log to the in memory log before init" do
7
- Appsignal.logger.error('Log something before init')
8
- Appsignal.in_memory_log.string.should include('Log something before init')
9
- end
10
-
11
- context "after initializing the app" do
12
- before(:all) { MyApp::Application.initialize! }
13
-
14
- it "should start logging to file and have written the in memory log" do
15
- Appsignal.logger.should be_instance_of(Logger)
16
- File.open(log_file).read.should include(
17
- 'Log something before init'
18
- )
19
- end
20
-
21
- it "should have set the appsignal subscriber" do
22
- if defined? ActiveSupport::Notifications::Fanout::Subscribers::Timed
23
- # Rails 4
24
- Appsignal.subscriber.
25
- should be_a ActiveSupport::Notifications::Fanout::Subscribers::Timed
26
- else
27
- # Rails 3
28
- Appsignal.subscriber.
29
- should be_a ActiveSupport::Notifications::Fanout::Subscriber
30
- end
31
- end
32
-
33
- it "should have added the listener middleware for exceptions" do
34
- MyApp::Application.middleware.to_a.should include Appsignal::Listener
35
- end
36
-
37
- context "non action_controller event" do
38
- it "should call add_event for non action_controller event" do
39
- current = double(:current)
40
- current.should_receive(:add_event)
41
- Appsignal::Transaction.should_receive(:current).twice.
42
- and_return(current)
43
- end
44
-
45
- after { ActiveSupport::Notifications.instrument 'query.mongoid' }
46
- end
47
-
48
- context "action_controller event" do
49
- it "should call set_process_action_event for action_controller event" do
50
- current = double(:current)
51
- current.should_receive(:set_process_action_event)
52
- current.should_receive(:add_event)
53
- Appsignal::Transaction.should_receive(:current).exactly(3).times.
54
- and_return(current)
55
- end
56
-
57
- after do
58
- ActiveSupport::Notifications.
59
- instrument 'process_action.action_controller'
60
- end
61
- end
62
-
63
- context "event that starts with a bang" do
64
- it "should not be processed" do
65
- Appsignal::Transaction.should_not_receive(:current)
66
- end
67
-
68
- after do
69
- ActiveSupport::Notifications.
70
- instrument '!render_template'
71
- end
72
- end
73
- end
74
- end
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Appsignal::ToAppsignalHash do
4
- subject { notification_event }
5
-
6
- it { should be_instance_of ActiveSupport::Notifications::Event }
7
- it { should respond_to(:to_appsignal_hash) }
8
-
9
- describe "#to_appsignal_hash" do
10
- subject { notification_event.to_appsignal_hash }
11
-
12
- it { should == {
13
- :time => 978364860.0,
14
- :duration => be_within(0.01).of(100.0),
15
- :end => 978364860.1,
16
- :name => "process_action.action_controller",
17
- :payload => {
18
- :path=>"/blog",
19
- :action=>"show",
20
- :controller=>"BlogPostsController",
21
- :request_format=>"html",
22
- :request_method=>"GET",
23
- :status=>"200",
24
- :view_runtime=>500,
25
- :db_runtime=>500
26
- }
27
- } }
28
- end
29
- end
@@ -1,195 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Appsignal do
4
- it { should respond_to :subscriber }
5
- let(:transaction) { regular_transaction }
6
-
7
- describe ".enqueue" do
8
- subject { Appsignal.enqueue(transaction) }
9
-
10
- it "forwards the call to the agent" do
11
- Appsignal.agent.should respond_to(:enqueue)
12
- Appsignal.agent.should_receive(:enqueue).with(transaction)
13
- subject
14
- end
15
- end
16
-
17
- describe ".tag_request" do
18
- before { Appsignal::Transaction.stub(:current => transaction) }
19
-
20
- context "with transaction" do
21
- let(:transaction) { double }
22
-
23
- it "should call set_tags on transaction" do
24
- transaction.should_receive(:set_tags).with({'a' => 'b'})
25
- end
26
-
27
- after { Appsignal.tag_request({'a' => 'b'}) }
28
- end
29
-
30
- context "without transaction" do
31
- let(:transaction) { nil }
32
-
33
- it "should call set_tags on transaction" do
34
- Appsignal.tag_request.should be_false
35
- end
36
- end
37
- end
38
-
39
- describe ".transactions" do
40
- subject { Appsignal.transactions }
41
-
42
- it { should be_a Hash }
43
- end
44
-
45
- describe '.agent' do
46
- subject { Appsignal.agent }
47
-
48
- it { should be_a Appsignal::Agent }
49
- end
50
-
51
- describe '.logger' do
52
- subject { Appsignal.logger }
53
-
54
- it { should be_a Logger }
55
- its(:level) { should == Logger::INFO }
56
- end
57
-
58
- describe '.config' do
59
- subject { Appsignal.config }
60
-
61
- it 'should return the endpoint' do
62
- subject[:endpoint].should eq 'http://localhost:3000/1'
63
- end
64
-
65
- it 'should return the api key' do
66
- subject[:api_key].should eq 'ghi'
67
- end
68
-
69
- it 'should return ignored exceptions' do
70
- subject[:ignore_exceptions].should eq []
71
- end
72
-
73
- it 'should return the slow request threshold' do
74
- subject[:slow_request_threshold].should eq 200
75
- end
76
- end
77
-
78
- describe ".json" do
79
- subject { Appsignal.json }
80
-
81
- it { should == ActiveSupport::JSON }
82
- end
83
-
84
- describe ".post_processing_middleware" do
85
- before { Appsignal.instance_variable_set(:@post_processing_chain, nil) }
86
-
87
- it "returns the default middleware stack" do
88
- Appsignal::PostProcessor.should_receive(:default_middleware)
89
- Appsignal.post_processing_middleware
90
- end
91
-
92
- it "returns a chain when called without a block" do
93
- instance = Appsignal.post_processing_middleware
94
- instance.should be_an_instance_of Appsignal::Middleware::Chain
95
- end
96
-
97
- context "when passing a block" do
98
- it "yields an appsignal middleware chain" do
99
- Appsignal.post_processing_middleware do |o|
100
- o.should be_an_instance_of Appsignal::Middleware::Chain
101
- end
102
- end
103
- end
104
- end
105
-
106
- describe '.active?' do
107
- subject { Appsignal.active? }
108
-
109
- context "without config" do
110
- before { Appsignal.stub(:config => nil) }
111
-
112
- it { should be_false }
113
- end
114
-
115
- context "with config but inactive" do
116
- before { Appsignal.stub(:config => {:active => false}) }
117
-
118
- it { should be_false }
119
- end
120
-
121
- context "with active config" do
122
- before { Appsignal.stub(:config => {:active => true}) }
123
-
124
- it { should be_true }
125
- end
126
- end
127
-
128
- describe ".send_exception" do
129
- it "should send the exception to AppSignal" do
130
- agent = double
131
- Appsignal.stub(:agent).and_return(agent)
132
- agent.should_receive(:send_queue)
133
- agent.should_receive(:enqueue).with(kind_of(Appsignal::Transaction))
134
-
135
- Appsignal::Transaction.should_receive(:create).and_call_original
136
- end
137
-
138
- it "should not send the exception if it's in the ignored list" do
139
- Appsignal.stub(:is_ignored_exception? => true)
140
- Appsignal::Transaction.should_not_receive(:create)
141
- end
142
-
143
- after do
144
- begin
145
- raise "I am an exception"
146
- rescue Exception => e
147
- Appsignal.send_exception(e)
148
- end
149
- end
150
- end
151
-
152
- describe ".listen_for_exception" do
153
- it "should call send_exception and re-raise" do
154
- Appsignal.should_receive(:send_exception).with(kind_of(Exception))
155
- lambda {
156
- Appsignal.listen_for_exception do
157
- raise "I am an exception"
158
- end
159
- }.should raise_error(RuntimeError, "I am an exception")
160
- end
161
- end
162
-
163
- describe ".add_exception" do
164
- before { Appsignal::Transaction.stub(:current => transaction) }
165
- let(:exception) { RuntimeError.new('I am an exception') }
166
-
167
- it "should add the exception to the current transaction" do
168
- transaction.should_receive(:add_exception).with(exception)
169
-
170
- Appsignal.add_exception(exception)
171
- end
172
-
173
- it "should do nothing if there is no current transaction" do
174
- Appsignal::Transaction.stub(:current => nil)
175
-
176
- transaction.should_not_receive(:add_exception).with(exception)
177
-
178
- Appsignal.add_exception(exception)
179
- end
180
-
181
- it "should not add the exception if it's in the ignored list" do
182
- Appsignal.stub(:is_ignored_exception? => true)
183
-
184
- transaction.should_not_receive(:add_exception).with(exception)
185
-
186
- Appsignal.add_exception(exception)
187
- end
188
-
189
- it "should do nothing if the exception is nil" do
190
- transaction.should_not_receive(:add_exception)
191
-
192
- Appsignal.add_exception(nil)
193
- end
194
- end
195
- end
@@ -1,181 +0,0 @@
1
- require 'spec_helper'
2
- require 'generator_spec/test_case'
3
- require './lib/generators/appsignal/appsignal_generator'
4
-
5
- # The generator doesn't know we're testing
6
- # So change the path while running the generator
7
- # Change it back upon completion
8
- def run_generator_in_tmp(args=[])
9
- FileUtils.cd("spec/tmp") do
10
- @output = run_generator(args)
11
- end
12
- end
13
-
14
- describe AppsignalGenerator do
15
- include GeneratorSpec::TestCase
16
- destination File.expand_path("../../../tmp", __FILE__)
17
-
18
- context "with key" do
19
- context "known key" do
20
- before do
21
- prepare_destination
22
- authcheck = double
23
- Appsignal::AuthCheck.should_receive(:new).and_return(authcheck)
24
- authcheck.should_receive(:perform_with_result).
25
- and_return(['200', 'everything ok'])
26
- run_generator_in_tmp %w(production my_app_key)
27
- end
28
-
29
- specify "should mention successful auth check" do
30
- @output.should include('success everything ok')
31
- end
32
- end
33
-
34
- context "invalid key" do
35
- before do
36
- prepare_destination
37
- authcheck = double
38
- Appsignal::AuthCheck.should_receive(:new).and_return(authcheck)
39
- authcheck.should_receive(:perform_with_result).
40
- and_return(['401', 'unauthorized'])
41
- run_generator_in_tmp %w(production my_app_key)
42
- end
43
-
44
- specify "should mention invalid key" do
45
- @output.should include('error unauthorized')
46
- end
47
- end
48
-
49
- context "failed check" do
50
- before do
51
- prepare_destination
52
- authcheck = double
53
- Appsignal::AuthCheck.should_receive(:new).and_return(authcheck)
54
- authcheck.should_receive(:perform_with_result).
55
- and_return(['500', 'error!'])
56
- run_generator_in_tmp %w(production my_app_key)
57
- end
58
-
59
- specify "should mention failed check" do
60
- @output.should include('error error!')
61
- end
62
- end
63
-
64
- context "internal failure" do
65
- before do
66
- prepare_destination
67
- authcheck = Appsignal::AuthCheck.new
68
- Appsignal::AuthCheck.should_receive(:new).and_return(authcheck)
69
- authcheck.should_receive(:perform).
70
- and_throw(:error)
71
- run_generator_in_tmp %w(production my_app_key)
72
- end
73
-
74
- specify "should mention internal failure" do
75
- @output.should include('Something went wrong while trying to '\
76
- 'authenticate with AppSignal:')
77
- end
78
- end
79
- end
80
-
81
- context "without key" do
82
- before do
83
- prepare_destination
84
- run_generator_in_tmp %w()
85
- end
86
-
87
- specify "no config files are created" do
88
- destination_root.should have_structure {
89
- directory 'config' do
90
- no_file 'appsignal.yml'
91
- no_file 'deploy.rb'
92
- end
93
- }
94
- end
95
- end
96
-
97
- context "without capistrano" do
98
- before :all do
99
- prepare_destination
100
- run_generator_in_tmp %w(production my_app_key)
101
- end
102
-
103
- specify "config file is created" do
104
- destination_root.should have_structure {
105
- directory 'config' do
106
- file 'appsignal.yml'
107
- no_file 'deploy.rb'
108
- end
109
- }
110
- end
111
-
112
- specify "should mention the deploy task" do
113
- @output.should include('No capistrano setup detected!')
114
- @output.should include('appsignal notify_of_deploy -h')
115
- end
116
- end
117
-
118
- context "with capistrano" do
119
- before :all do
120
- prepare_destination
121
- cap_file = File.expand_path('Capfile', destination_root)
122
- File.open(cap_file, 'w') {}
123
- FileUtils.mkdir(File.expand_path('config', destination_root))
124
- deploy_file = File.expand_path(File.join('config', 'deploy.rb'),
125
- destination_root)
126
- File.open(deploy_file, 'w') {}
127
- run_generator_in_tmp %w(production my_app_key)
128
- end
129
-
130
- specify "config file is created and capistrano deploy file modified" do
131
- destination_root.should have_structure {
132
- file 'Capfile'
133
- directory 'config' do
134
- file 'appsignal.yml'
135
- file 'deploy.rb' do
136
- contains "require 'appsignal/capistrano'"
137
- end
138
- end
139
- }
140
- end
141
-
142
- specify "should not mention the deploy task" do
143
- @output.should_not include('No capistrano setup detected!')
144
- @output.should_not include('appsignal notify_of_deploy -h')
145
- end
146
- end
147
-
148
- context "with custom environment" do
149
- before do
150
- prepare_destination
151
- run_generator_in_tmp %w(development my_app_key)
152
- end
153
-
154
- specify "config file is created" do
155
- destination_root.should have_structure {
156
- directory 'config' do
157
- file 'appsignal.yml'
158
- no_file 'deploy.rb'
159
- end
160
- }
161
- end
162
- end
163
-
164
- context "with multiple environments" do
165
- context "with new environment" do
166
- before :all do
167
- prepare_destination
168
- FileUtils.mkdir(File.expand_path('config', destination_root))
169
- config_file = File.join('config', 'appsignal.yml')
170
- File.open(File.expand_path(config_file, destination_root), 'w') do |f|
171
- f.write("production:\n api_key: 111")
172
- end
173
- run_generator_in_tmp %w(development my_app_key)
174
- end
175
-
176
- it "exits and tells to manually edit config/appsignal.yml" do
177
- @output.should include('error Looks like you already have a config file')
178
- end
179
- end
180
- end
181
- end