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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -3
- data/appsignal.gemspec +0 -1
- data/lib/appsignal.rb +29 -6
- data/lib/appsignal/agent.rb +11 -6
- data/lib/appsignal/cli.rb +2 -1
- data/lib/appsignal/config.rb +1 -0
- data/lib/appsignal/integrations/delayed_job.rb +11 -19
- data/lib/appsignal/integrations/resque.rb +1 -9
- data/lib/appsignal/integrations/sidekiq.rb +1 -7
- data/lib/appsignal/transaction.rb +1 -14
- data/lib/appsignal/transaction/formatter.rb +1 -0
- data/lib/appsignal/transmitter.rb +2 -1
- data/lib/appsignal/version.rb +1 -1
- data/lib/generators/appsignal/templates/appsignal.yml +4 -0
- data/lib/vendor/active_support/notifications.rb +212 -0
- data/lib/vendor/active_support/notifications/fanout.rb +157 -0
- data/lib/vendor/active_support/notifications/instrumenter.rb +73 -0
- data/lib/vendor/active_support/per_thread_registry.rb +53 -0
- data/resources/cacert.pem +502 -485
- data/spec/lib/appsignal/agent_spec.rb +19 -4
- data/spec/lib/appsignal/config_spec.rb +2 -0
- data/spec/lib/appsignal/integrations/delayed_job_spec.rb +2 -3
- data/spec/lib/appsignal/integrations/resque_spec.rb +2 -2
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +3 -6
- data/spec/lib/appsignal/transaction/formatter_spec.rb +18 -0
- data/spec/lib/appsignal/transaction_spec.rb +1 -26
- data/spec/lib/appsignal/transmitter_spec.rb +17 -10
- data/spec/lib/appsignal_spec.rb +103 -12
- data/spec/spec_helper.rb +3 -1
- data/spec/support/fixtures/generated_config.yml +4 -0
- metadata +8 -18
@@ -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
|
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(
|
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(
|
240
|
+
subject.aggregator.should_receive(:add).with(transaction)
|
234
241
|
subject.should_receive(:forked!)
|
235
242
|
end
|
236
243
|
end
|
237
244
|
|
238
|
-
|
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
|
45
|
-
|
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
|
42
|
-
|
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
|
36
|
-
|
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
|
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
|
-
|
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
|
-
|
53
|
-
|
54
|
-
|
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
|
|
data/spec/lib/appsignal_spec.rb
CHANGED
@@ -144,7 +144,7 @@ describe Appsignal do
|
|
144
144
|
end
|
145
145
|
|
146
146
|
context "not active" do
|
147
|
-
describe "
|
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 "
|
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 "
|
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 "
|
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 "
|
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:
|