appsignal 0.9.6 → 0.10.0.beta.0

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.
@@ -10,6 +10,12 @@ describe Appsignal::Agent do
10
10
 
11
11
  let(:transaction) { regular_transaction }
12
12
 
13
+ context "supporting objects" do
14
+ its(:mutex) { should be_a(Mutex) }
15
+ its(:aggregator) { should be_a(Appsignal::Aggregator) }
16
+ its(:transmitter) { should be_a(Appsignal::Transmitter) }
17
+ end
18
+
13
19
  context "pid" do
14
20
  its(:master_pid) { should == Process.pid }
15
21
  its(:pid) { should == Process.pid }
@@ -55,7 +61,7 @@ describe Appsignal::Agent do
55
61
  subject.should_receive(:send_queue).at_least(:twice)
56
62
 
57
63
  subject.start_thread
58
- sleep 2
64
+ sleep 1
59
65
  end
60
66
  end
61
67
 
@@ -218,11 +224,12 @@ describe Appsignal::Agent do
218
224
  end
219
225
 
220
226
  describe "#enqueue" do
227
+ let(:transaction) { double(:action => 'test#test', :request_id => 'id') }
221
228
  subject { Appsignal.agent }
222
229
 
223
230
  it "forwards to the aggregator" do
224
231
  subject.aggregator.should respond_to(:add)
225
- subject.aggregator.should_receive(:add).with(:foo)
232
+ subject.aggregator.should_receive(:add).with(transaction)
226
233
  subject.should_not_receive(:forked!)
227
234
  end
228
235
 
@@ -230,12 +237,20 @@ describe Appsignal::Agent do
230
237
  before { Process.stub(:pid => 9000000002) }
231
238
 
232
239
  it "should call forked!" do
233
- subject.aggregator.should_receive(:add).with(:foo)
240
+ subject.aggregator.should_receive(:add).with(transaction)
234
241
  subject.should_receive(:forked!)
235
242
  end
236
243
  end
237
244
 
238
- after { subject.enqueue(:foo) }
245
+ context "with ignored action" do
246
+ before { Appsignal.stub(:is_ignored_action? => true) }
247
+
248
+ it "should not add item to queue" do
249
+ subject.aggregator.should_not_receive(:add)
250
+ end
251
+ end
252
+
253
+ after { subject.enqueue(transaction) }
239
254
  end
240
255
 
241
256
  describe "#send_queue" do
@@ -17,6 +17,7 @@ describe Appsignal::Config do
17
17
  it "should merge with the default config and fill the config hash" do
18
18
  subject.config_hash.should == {
19
19
  :ignore_exceptions => [],
20
+ :ignore_actions => [],
20
21
  :instrument_net_http => true,
21
22
  :send_params => true,
22
23
  :endpoint => 'https://push.appsignal.com/1',
@@ -123,6 +124,7 @@ describe Appsignal::Config do
123
124
  subject.config_hash.should == {
124
125
  :push_api_key => 'push_api_key',
125
126
  :ignore_exceptions => [],
127
+ :ignore_actions => [],
126
128
  :send_params => true,
127
129
  :instrument_net_http => true,
128
130
  :endpoint => 'https://push.appsignal.com/1',
@@ -41,8 +41,8 @@ describe "Delayed Job integration" do
41
41
  let(:error) { StandardError.new }
42
42
 
43
43
  context "with a normal call" do
44
- it "should create an instrumentation with the correct params" do
45
- ActiveSupport::Notifications.should_receive(:instrument).with(
44
+ it "should wrap in a transaction with the correct params" do
45
+ Appsignal.should_receive(:monitor_transaction).with(
46
46
  'perform_job.delayed_job',
47
47
  :class => 'TestClass',
48
48
  :method => 'perform',
@@ -51,7 +51,6 @@ describe "Delayed Job integration" do
51
51
  :queue => 'default',
52
52
  :queue_start => time - 60_000
53
53
  )
54
- Appsignal::Transaction.any_instance.should_receive(:complete!)
55
54
 
56
55
  Timecop.freeze(time) do
57
56
  plugin.invoke_with_instrumentation(job, invoked_block)
@@ -38,8 +38,8 @@ describe "Resque integration" do
38
38
  Appsignal::Transaction.should_receive(:create).and_return(transaction)
39
39
  end
40
40
 
41
- it "should instrument with correct params" do
42
- ActiveSupport::Notifications.should_receive(:instrument).with(
41
+ it "should wrap in a transaction with the correct params" do
42
+ Appsignal.should_receive(:monitor_transaction).with(
43
43
  'perform_job.resque',
44
44
  :class => 'Resque::Job',
45
45
  :method => 'perform'
@@ -1,8 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- class VerySpecificError < RuntimeError
4
- end
5
-
6
3
  describe "Sidekiq integration" do
7
4
  let(:file) { File.expand_path('lib/appsignal/integrations/sidekiq.rb') }
8
5
  before :all do
@@ -32,8 +29,8 @@ describe "Sidekiq integration" do
32
29
  end
33
30
 
34
31
  context "with a performance call" do
35
- it "should create an instrumentation with the correct params" do
36
- ActiveSupport::Notifications.should_receive(:instrument).with(
32
+ it "should wrap in a transaction with the correct params" do
33
+ Appsignal.should_receive(:monitor_transaction).with(
37
34
  'perform_job.sidekiq',
38
35
  :class => 'TestClass',
39
36
  :method => 'perform',
@@ -54,7 +51,7 @@ describe "Sidekiq integration" do
54
51
 
55
52
  context "with an erroring call" do
56
53
  let(:error) { VerySpecificError.new('the roof') }
57
- it "should add exception to appsignal" do
54
+ it "should add the exception to appsignal" do
58
55
  current_transaction.should_receive(:add_exception).with(error)
59
56
  end
60
57
 
@@ -186,4 +186,22 @@ describe Appsignal::Transaction::Formatter do
186
186
  end
187
187
  end
188
188
  end
189
+
190
+ describe "#clean_backtrace" do
191
+ let(:transaction) { regular_transaction }
192
+
193
+ context "when backtrace is nil" do
194
+ let(:error) { double(:backtrace => nil) }
195
+
196
+ it "should not raise an error when backtrace is `nil`" do
197
+ expect {
198
+ formatter.send(:clean_backtrace, error)
199
+ }.to_not raise_error
200
+ end
201
+
202
+ it "should always return an array" do
203
+ expect( formatter.send(:clean_backtrace, error) ).to be_a(Array)
204
+ end
205
+ end
206
+ end
189
207
  end
@@ -234,15 +234,6 @@ describe Appsignal::Transaction do
234
234
  subject.process_action_event.payload.should be_empty
235
235
  subject.events.should be_empty
236
236
  subject.tags.should be_empty
237
- subject.truncated?.should be_true
238
- end
239
-
240
- it "should not truncate twice" do
241
- subject.process_action_event.payload.should_receive(:clear).once
242
- subject.events.should_receive(:clear).once
243
-
244
- subject.truncate!
245
- subject.truncate!
246
237
  end
247
238
  end
248
239
 
@@ -291,14 +282,6 @@ describe Appsignal::Transaction do
291
282
  subject
292
283
  event_payload.should == before
293
284
  end
294
-
295
- it "should not covert to primitives twice" do
296
- transaction.convert_values_to_primitives!
297
- transaction.have_values_been_converted_to_primitives?.should be_true
298
-
299
- Appsignal::Transaction::ParamsSanitizer.should_not_receive(:sanitize!)
300
- transaction.convert_values_to_primitives!
301
- end
302
285
  end
303
286
  end
304
287
 
@@ -372,20 +355,12 @@ describe Appsignal::Transaction do
372
355
 
373
356
  context 'when using pipes' do
374
357
  let(:pipe) { double }
375
- before do
376
- Appsignal::Pipe.stub(:current => pipe)
377
- pipe.stub(:write => true)
378
- transaction.stub(:convert_values_to_primitives! => true)
379
- end
358
+ before { Appsignal::Pipe.stub(:current => pipe) }
380
359
 
381
360
  it "should send itself trough the pipe" do
382
361
  pipe.should_receive(:write).with(transaction)
383
362
  end
384
363
 
385
- it "should convert itself to primitives" do
386
- transaction.should_receive(:convert_values_to_primitives!)
387
- end
388
-
389
364
  after { transaction.complete! }
390
365
  end
391
366
  end
@@ -40,18 +40,25 @@ describe Appsignal::Transmitter do
40
40
  end
41
41
 
42
42
  describe "#http_post" do
43
- before do
43
+ it "calls Net::HTTP.post_form with the correct params" do
44
+ post = double(:post)
45
+ post.should_receive(:[]=).with(
46
+ 'Content-Type',
47
+ 'application/json; charset=UTF-8'
48
+ )
49
+ post.should_receive(:[]=).with(
50
+ 'Content-Encoding',
51
+ 'gzip'
52
+ )
53
+ post.should_receive(:body=).with(
54
+ Zlib::Deflate.deflate("{\"the\":\"payload\"}", Zlib::BEST_SPEED)
55
+ )
44
56
  Socket.stub(:gethostname => 'app1.local')
45
- end
46
-
47
- subject { instance.send(:http_post, 'the' => 'payload') }
48
-
49
- its(:body) { should == Zlib::Deflate.deflate("{\"the\":\"payload\"}", Zlib::BEST_SPEED) }
50
- its(:path) { should == instance.uri.request_uri }
51
57
 
52
- it "should have the correct headers" do
53
- subject['Content-Type'].should == 'application/json; charset=UTF-8'
54
- subject['Content-Encoding'].should == 'gzip'
58
+ Net::HTTP::Post.should_receive(:new).with(
59
+ instance.uri.request_uri
60
+ ).and_return(post)
61
+ instance.send(:http_post, :the => :payload)
55
62
  end
56
63
  end
57
64
 
@@ -144,7 +144,7 @@ describe Appsignal do
144
144
  end
145
145
 
146
146
  context "not active" do
147
- describe "#enqueue" do
147
+ describe ".enqueue" do
148
148
  it "should do nothing" do
149
149
  lambda {
150
150
  Appsignal.enqueue(Appsignal::Transaction.create(SecureRandom.uuid, ENV))
@@ -152,7 +152,22 @@ describe Appsignal do
152
152
  end
153
153
  end
154
154
 
155
- describe "#listen_for_exception" do
155
+ describe ".monitor_transaction" do
156
+ it "should do nothing but still yield the block" do
157
+ Appsignal::Transaction.should_not_receive(:create)
158
+ ActiveSupport::Notifications.should_not_receive(:instrument)
159
+ object = double
160
+ object.should_receive(:some_method)
161
+
162
+ lambda {
163
+ Appsignal.monitor_transaction('perform_job.nothing') do
164
+ object.some_method
165
+ end
166
+ }.should_not raise_error
167
+ end
168
+ end
169
+
170
+ describe ".listen_for_exception" do
156
171
  it "should do nothing" do
157
172
  error = RuntimeError.new('specific error')
158
173
  lambda {
@@ -163,7 +178,7 @@ describe Appsignal do
163
178
  end
164
179
  end
165
180
 
166
- describe "#send_exception" do
181
+ describe ".send_exception" do
167
182
  it "should do nothing" do
168
183
  lambda {
169
184
  Appsignal.send_exception(RuntimeError.new)
@@ -171,7 +186,7 @@ describe Appsignal do
171
186
  end
172
187
  end
173
188
 
174
- describe "#add_exception" do
189
+ describe ".add_exception" do
175
190
  it "should do nothing" do
176
191
  lambda {
177
192
  Appsignal.add_exception(RuntimeError.new)
@@ -179,7 +194,7 @@ describe Appsignal do
179
194
  end
180
195
  end
181
196
 
182
- describe "#tag_request" do
197
+ describe ".tag_request" do
183
198
  it "should do nothing" do
184
199
  lambda {
185
200
  Appsignal.tag_request(:tag => 'tag')
@@ -188,7 +203,6 @@ describe Appsignal do
188
203
  end
189
204
  end
190
205
 
191
-
192
206
  context "with config and started" do
193
207
  before do
194
208
  Appsignal.config = project_fixture_config
@@ -205,6 +219,43 @@ describe Appsignal do
205
219
  end
206
220
  end
207
221
 
222
+ describe ".monitor_transaction" do
223
+ context "with a normall call" do
224
+ it "should instrument and complete" do
225
+ Appsignal::Transaction.stub(:current => transaction)
226
+ ActiveSupport::Notifications.should_receive(:instrument).with(
227
+ 'perform_job.something',
228
+ :class => 'Something'
229
+ ).and_yield
230
+ transaction.should_receive(:complete!)
231
+ object = double
232
+ object.should_receive(:some_method)
233
+
234
+ Appsignal.monitor_transaction(
235
+ 'perform_job.something',
236
+ :class => 'Something'
237
+ ) do
238
+ object.some_method
239
+ end
240
+ end
241
+ end
242
+
243
+ context "with an erroring call" do
244
+ let(:error) { VerySpecificError.new('the roof') }
245
+
246
+ it "should add the error to the current transaction and complete" do
247
+ Appsignal.should_receive(:add_exception).with(error)
248
+ Appsignal::Transaction.should_receive(:complete_current!)
249
+
250
+ lambda {
251
+ Appsignal.monitor_transaction('perform_job.something') do
252
+ raise error
253
+ end
254
+ }.should raise_error(error)
255
+ end
256
+ end
257
+ end
258
+
208
259
  describe ".tag_request" do
209
260
  before { Appsignal::Transaction.stub(:current => transaction) }
210
261
 
@@ -320,12 +371,6 @@ describe Appsignal do
320
371
  end
321
372
  end
322
373
 
323
- describe ".json" do
324
- subject { Appsignal.json }
325
-
326
- it { should == ActiveSupport::JSON }
327
- end
328
-
329
374
  describe ".post_processing_middleware" do
330
375
  before { Appsignal.instance_variable_set(:@post_processing_chain, nil) }
331
376
 
@@ -454,5 +499,51 @@ describe Appsignal do
454
499
  end
455
500
  end
456
501
  end
502
+
503
+ describe ".is_ignored_exception?" do
504
+ let(:exception) { StandardError.new }
505
+ before do
506
+ Appsignal.stub(
507
+ :config => {:ignore_exceptions => 'StandardError'}
508
+ )
509
+ end
510
+
511
+ subject { Appsignal.is_ignored_exception?(exception) }
512
+
513
+ it "should return true if it's in the ignored list" do
514
+ should be_true
515
+ end
516
+
517
+ context "when exception is not in the ingore list" do
518
+ let(:exception) { Object.new }
519
+
520
+ it "should return false" do
521
+ should be_false
522
+ end
523
+ end
524
+ end
525
+
526
+ describe ".is_ignored_action?" do
527
+ let(:action) { 'TestController#isup' }
528
+ before do
529
+ Appsignal.stub(
530
+ :config => {:ignore_actions => 'TestController#isup'}
531
+ )
532
+ end
533
+
534
+ subject { Appsignal.is_ignored_action?(action) }
535
+
536
+ it "should return true if it's in the ignored list" do
537
+ should be_true
538
+ end
539
+
540
+ context "when action is not in the ingore list" do
541
+ let(:action) { 'TestController#other_action' }
542
+
543
+ it "should return false" do
544
+ should be_false
545
+ end
546
+ end
547
+ end
457
548
  end
458
549
  end
data/spec/spec_helper.rb CHANGED
@@ -3,7 +3,6 @@ require 'rspec'
3
3
  require 'pry'
4
4
  require 'timecop'
5
5
  require 'webmock/rspec'
6
- require 'active_support/notifications'
7
6
 
8
7
  puts "Runnings specs in #{RUBY_VERSION} on #{RUBY_PLATFORM}"
9
8
 
@@ -64,3 +63,6 @@ RSpec.configure do |config|
64
63
  Appsignal.logger = nil
65
64
  end
66
65
  end
66
+
67
+ class VerySpecificError < RuntimeError
68
+ end
@@ -9,6 +9,10 @@ default: &defaults
9
9
  # The cuttoff point in ms above which a request is considered slow, default is 200
10
10
  # slow_request_threshold: 200
11
11
 
12
+ # Actions that should not be monitored by AppSignal
13
+ # ignore_actions:
14
+ # - ApplicationController#isup
15
+
12
16
  # Configuration per environment, leave out an environment or set active
13
17
  # to false to not push metrics for that environment.
14
18
  development: