appsignal 0.8.0.alpha.0 → 0.8.0.beta.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTVhMjJhZmE1M2Y3ZTNmNzhhNjdlNDU1ZDRiN2ZkN2M5YmZhZjUwNQ==
4
+ N2ViNDUxNzQ5NTM1OTBiOWYwZmFjYzhiN2I1MDM0ZmQyM2E5MjE1MA==
5
5
  data.tar.gz: !binary |-
6
- ODVhZDM0M2FhMTkxNzgxZWI1NDBhNDI4YWNlMjJkMjBlNDE5ZmRlZg==
6
+ ZjI2YTk3MzMxYzVjZDVmYzJlM2JmZjg5NGNkNjZiNDk0YTU1YmFlMA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YzNjMmVhNzY2ZmNhNmFjMDc3NWM4YjA5YzQxYzc0YzkzMDVkOGI2NDc3MGVk
10
- MzI4N2NjMDMwODVjZGRhZTczNWI4MTkzZjViMzRjNmVjMmQ3MTk3NTZjY2E0
11
- OTQxOTFlOWNkMWVkOWMyNDI1ZDhhNjRlNGFjZjIwMmU2MDcxNmM=
9
+ YjFkN2M2OGYwZWRmOGVlMGVmN2NlODU2MzJmMGM5YWExZjBiYTdlMThkNGVh
10
+ NDQ2M2FjZDU0ZjQ2MThmYzJhMWVkNTY1ZjQzMTlmY2RjNGM3YTQzOGU1ZmYw
11
+ ZjRhY2FiN2JjNjc4MzYxZWFjMGExZjYwODVlZTBjMzcyMDNmMTQ=
12
12
  data.tar.gz: !binary |-
13
- YjZmMjExNzFhZTZlNzE2OWFjZmJmNTdkMTYwZmQ3NTNjOTZkNTQxMzhmMTA1
14
- ZDU0ZDhlOTM1NDBiN2U3YTAzNzc1YWQ1YTFlMTg1Y2JiYzBmMWM4NWYxMzAy
15
- NDYyM2RkNTU2YzI1YzgzMDYwZTE5ZjgzYzJlN2Y0YmUwYjBjNGQ=
13
+ OTkyOGYyZTUzZmYxMDA1Mjc3MmEyYjA5ODlkOGI5YjU3ZDQ2NzZhMGZlYjRj
14
+ MzE1MGI0ZDIxY2IyNDk0MWUwYTNjNTBlZWVkMGJhNTFiNGQxYmMxODI0MGY3
15
+ YjFiZDk2YzQ3OWFjNmY4MWIwZDZmYzIzNjhjNGNhMzNlYzcyNDA=
@@ -1,5 +1,5 @@
1
1
  # 0.8.0
2
- * Support for background processors
2
+ * Support for background processors (Delayed Job and Sidekiq)
3
3
 
4
4
  # 0.7.1
5
5
  * Better support for forking webservers
@@ -7,6 +7,25 @@ module Appsignal
7
7
  class << self
8
8
  attr_accessor :config, :logger, :agent, :in_memory_log
9
9
 
10
+ def load_integrations
11
+ require 'appsignal/integrations/delayed_job'
12
+ require 'appsignal/integrations/passenger'
13
+ require 'appsignal/integrations/unicorn'
14
+ require 'appsignal/integrations/sidekiq'
15
+ end
16
+
17
+ def extensions
18
+ @extensions ||= []
19
+ end
20
+
21
+ def initialize_extensions
22
+ Appsignal.logger.debug('Initializing extensions')
23
+ extensions.each do |extension|
24
+ Appsignal.logger.debug("Initializing #{extension}")
25
+ extension.initializer
26
+ end
27
+ end
28
+
10
29
  def start
11
30
  if config
12
31
  if config[:debug]
@@ -15,6 +34,8 @@ module Appsignal
15
34
  logger.level = Logger::INFO
16
35
  end
17
36
  logger.info("Starting appsignal-#{Appsignal::VERSION}")
37
+ load_integrations
38
+ initialize_extensions
18
39
  @agent = Appsignal::Agent.new
19
40
  at_exit { @agent.shutdown(true) }
20
41
  else
@@ -117,8 +138,4 @@ require 'appsignal/transaction/formatter'
117
138
  require 'appsignal/transaction/params_sanitizer'
118
139
  require 'appsignal/transmitter'
119
140
  require 'appsignal/version'
120
-
121
- require 'appsignal/integrations/passenger'
122
- require 'appsignal/integrations/unicorn'
123
141
  require 'appsignal/integrations/rails'
124
- require 'appsignal/integrations/sidekiq'
@@ -0,0 +1,41 @@
1
+ if defined?(::Delayed::Plugin)
2
+ Appsignal.logger.info('Loading Delayed Job integration')
3
+
4
+ module Appsignal
5
+ module Integrations
6
+ class DelayedPlugin < ::Delayed::Plugin
7
+ callbacks do |lifecycle|
8
+ lifecycle.around(:invoke_job) do |job, &block|
9
+ invoke_with_instrumentation(job, block)
10
+ end
11
+ end
12
+
13
+ def self.invoke_with_instrumentation(job, &block)
14
+ begin
15
+ Appsignal::Transaction.create(SecureRandom.uuid, ENV.to_hash)
16
+ class_name, method_name = job.name.split('#')
17
+ ActiveSupport::Notifications.instrument(
18
+ 'perform_job.delayed_job',
19
+ :class => class_name,
20
+ :method => method_name,
21
+ :priority => job.priority,
22
+ :attempts => job.attempts,
23
+ :queue => job.queue,
24
+ :queue_start => job.created_at
25
+ ) do
26
+ block.call(job)
27
+ end
28
+ rescue Exception => exception
29
+ unless Appsignal.is_ignored_exception?(exception)
30
+ Appsignal::Transaction.current.add_exception(exception)
31
+ end
32
+ raise exception
33
+ ensure
34
+ Appsignal::Transaction.current.complete!
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ ::Delayed::Worker.plugins << Appsignal::Integrations::DelayedPlugin
41
+ end
@@ -1,5 +1,5 @@
1
1
  if defined?(::PhusionPassenger)
2
- Appsignal.logger.info('Using Passenger')
2
+ Appsignal.logger.info('Loading Passenger integration')
3
3
 
4
4
  ::PhusionPassenger.on_event(:starting_worker_process) do |forked|
5
5
  Appsignal.logger.debug('starting worker process')
@@ -1,4 +1,6 @@
1
1
  if defined?(::Rails)
2
+ Appsignal.logger.info('Loading Rails integration')
3
+
2
4
  module Appsignal
3
5
  module Integrations
4
6
  class Railtie < ::Rails::Railtie
@@ -1,4 +1,6 @@
1
1
  if defined?(::Sidekiq)
2
+ Appsignal.logger.info('Loading Sidekiq integration')
3
+
2
4
  module Appsignal
3
5
  module Integrations
4
6
  class SidekiqPlugin
@@ -1,5 +1,5 @@
1
- if defined?(::Unicorn) && defined?(::Unicorn::HttpServer)
2
- Appsignal.logger.info('Using Unicorn')
1
+ if defined?(::Unicorn)
2
+ Appsignal.logger.info('Loading Unicorn integration')
3
3
 
4
4
  # We'd love to be able to hook this into Unicorn in a less
5
5
  # intrusive way, but this is the best we can do given the
@@ -1,3 +1,3 @@
1
1
  module Appsignal
2
- VERSION = '0.8.0.alpha.0'
2
+ VERSION = '0.8.0.beta.0'
3
3
  end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Delayed Job integration" do
4
+ let(:file) { File.expand_path('lib/appsignal/integrations/delayed_job.rb') }
5
+
6
+ context "with delayed job" do
7
+ before(:all) do
8
+ module Delayed
9
+ class Plugin
10
+ def self.callbacks
11
+ end
12
+ end
13
+
14
+ class Worker
15
+ def self.plugins
16
+ @plugins ||= []
17
+ end
18
+ end
19
+ end
20
+ end
21
+ before do
22
+ load file
23
+ start_agent
24
+ end
25
+
26
+ # We haven't found a way to test the hooks, we'll have to do that manually
27
+
28
+ describe ".invoke_with_instrumentation" do
29
+ let(:plugin) { Appsignal::Integrations::DelayedPlugin }
30
+ let(:time) { Time.parse('01-01-2001 10:01:00UTC') }
31
+ let(:job) do
32
+ double(
33
+ :name => 'TestClass#perform',
34
+ :priority => 1,
35
+ :attempts => 1,
36
+ :queue => 'default',
37
+ :created_at => time - 60_000
38
+ )
39
+ end
40
+ let(:invoked_block) { Proc.new { } }
41
+ let(:error) { StandardError.new }
42
+
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(
46
+ 'perform_job.delayed_job',
47
+ :class => 'TestClass',
48
+ :method => 'perform',
49
+ :priority => 1,
50
+ :attempts => 1,
51
+ :queue => 'default',
52
+ :queue_start => time - 60_000
53
+ )
54
+ Appsignal::Transaction.any_instance.should_receive(:complete!)
55
+
56
+ Timecop.freeze(time) do
57
+ plugin.invoke_with_instrumentation(job, &invoked_block)
58
+ end
59
+ end
60
+ end
61
+
62
+ context "with an erroring call" do
63
+ it "should add the error to the transaction" do
64
+ Appsignal::Transaction.any_instance.should_receive(:add_exception).with(error)
65
+ invoked_block.stub(:call).and_raise(error)
66
+ Appsignal::Transaction.any_instance.should_receive(:complete!)
67
+
68
+ lambda {
69
+ plugin.invoke_with_instrumentation(job, &invoked_block)
70
+ }.should raise_error(StandardError)
71
+ end
72
+ end
73
+ end
74
+
75
+ it "should add the plugin" do
76
+ ::Delayed::Worker.plugins.should include Appsignal::Integrations::DelayedPlugin
77
+ end
78
+ end
79
+
80
+ context "without delayed job" do
81
+ before(:all) { Object.send(:remove_const, :Delayed) }
82
+
83
+ specify { expect { ::Delayed }.to raise_error(NameError) }
84
+ specify { expect { load file }.to_not raise_error }
85
+ end
86
+ end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require './spec/support/mocks/mock_extension'
2
3
 
3
4
  describe Appsignal do
4
5
  before do
@@ -7,6 +8,7 @@ describe Appsignal do
7
8
  Appsignal.agent.shutdown if Appsignal.agent
8
9
  Appsignal.config = nil
9
10
  Appsignal.agent = nil
11
+ Appsignal.extensions.clear
10
12
  end
11
13
 
12
14
  let(:transaction) { regular_transaction }
@@ -21,6 +23,14 @@ describe Appsignal do
21
23
  end
22
24
  end
23
25
 
26
+ describe ".extensions" do
27
+ it "should keep a list of extensions" do
28
+ Appsignal.extensions.should be_empty
29
+ Appsignal.extensions << Appsignal::MockExtension
30
+ Appsignal.extensions.should have(1).item
31
+ end
32
+ end
33
+
24
34
  describe ".start" do
25
35
  it "should do nothing when config is not loaded" do
26
36
  Appsignal.logger.should_receive(:error).with(
@@ -38,6 +48,20 @@ describe Appsignal do
38
48
  Appsignal.agent.should be_a Appsignal::Agent
39
49
  Appsignal.logger.level.should == Logger::INFO
40
50
  end
51
+
52
+ it "should load integrations" do
53
+ Appsignal.should_receive(:load_integrations)
54
+ Appsignal.start
55
+ end
56
+
57
+ context "with an extension" do
58
+ before { Appsignal.extensions << Appsignal::MockExtension }
59
+
60
+ it "should call the extension's initializer" do
61
+ Appsignal::MockExtension.should_receive(:initializer)
62
+ Appsignal.start
63
+ end
64
+ end
41
65
  end
42
66
 
43
67
  context "with debug logging" do
@@ -0,0 +1,7 @@
1
+ module Appsignal
2
+ module MockExtension
3
+ def self.initializer
4
+ puts "Initialized"
5
+ end
6
+ end
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appsignal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0.alpha.0
4
+ version: 0.8.0.beta.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Beekman
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-12-24 00:00:00.000000000 Z
15
+ date: 2013-12-30 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport
@@ -166,6 +166,7 @@ files:
166
166
  - lib/appsignal/config.rb
167
167
  - lib/appsignal/integrations/capistrano.rb
168
168
  - lib/appsignal/integrations/capistrano/careful_logger.rb
169
+ - lib/appsignal/integrations/delayed_job.rb
169
170
  - lib/appsignal/integrations/passenger.rb
170
171
  - lib/appsignal/integrations/rails.rb
171
172
  - lib/appsignal/integrations/sidekiq.rb
@@ -194,6 +195,7 @@ files:
194
195
  - spec/lib/appsignal/cli_spec.rb
195
196
  - spec/lib/appsignal/config_spec.rb
196
197
  - spec/lib/appsignal/integrations/capistrano_spec.rb
198
+ - spec/lib/appsignal/integrations/delayed_job_spec.rb
197
199
  - spec/lib/appsignal/integrations/passenger_spec.rb
198
200
  - spec/lib/appsignal/integrations/rails_spec.rb
199
201
  - spec/lib/appsignal/integrations/sidekiq_spec.rb
@@ -216,6 +218,7 @@ files:
216
218
  - spec/support/helpers/config_helpers.rb
217
219
  - spec/support/helpers/notification_helpers.rb
218
220
  - spec/support/helpers/transaction_helpers.rb
221
+ - spec/support/mocks/mock_extension.rb
219
222
  - spec/support/project_fixture/config/appsignal.yml
220
223
  - spec/support/project_fixture/log/.gitkeep
221
224
  - spec/support/rails/my_app.rb
@@ -255,6 +258,7 @@ test_files:
255
258
  - spec/lib/appsignal/cli_spec.rb
256
259
  - spec/lib/appsignal/config_spec.rb
257
260
  - spec/lib/appsignal/integrations/capistrano_spec.rb
261
+ - spec/lib/appsignal/integrations/delayed_job_spec.rb
258
262
  - spec/lib/appsignal/integrations/passenger_spec.rb
259
263
  - spec/lib/appsignal/integrations/rails_spec.rb
260
264
  - spec/lib/appsignal/integrations/sidekiq_spec.rb
@@ -277,6 +281,7 @@ test_files:
277
281
  - spec/support/helpers/config_helpers.rb
278
282
  - spec/support/helpers/notification_helpers.rb
279
283
  - spec/support/helpers/transaction_helpers.rb
284
+ - spec/support/mocks/mock_extension.rb
280
285
  - spec/support/project_fixture/config/appsignal.yml
281
286
  - spec/support/project_fixture/log/.gitkeep
282
287
  - spec/support/rails/my_app.rb