appsignal 0.8.0.alpha.0 → 0.8.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 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