appsignal 1.3.0.beta.3 → 1.3.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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e73535489669f40b80aa41c5f757e02779f0156f
4
- data.tar.gz: 24d7abe5c05024103e5654b59a2a056625e131be
3
+ metadata.gz: a5650fcfbab387eedbf59754caf1f53d98aea242
4
+ data.tar.gz: c0c6b2105ff5229592046ec9c8bed2e7aa9124bf
5
5
  SHA512:
6
- metadata.gz: c48a0f36c7ba4bc2481e215b7a60b363528bfafa10c7e1a07094ac147319fca0a7ca2dcaac49b44258021baaa26cc2816fe13a59b2c40b9b232b104bbad851cc
7
- data.tar.gz: 3edface3054bd2eaf48fd5d9b9fed014b68e4c3cb61ebd0423c44619f723f3a2858cb6d09b0a807c13655dd05bf72177af165e66d035491f1c496e823f2331a6
6
+ metadata.gz: b120abf95956270500254bba64828e8f056e249f167b43fa52181a6413b3e348d41f2edcd2a624aad743f41e184caa7ecc7e24512d60b164db80808cdf9f9f6b
7
+ data.tar.gz: e6dd70aedfb84937035aac71d2b8709628611aa1e9c7e6021cccd9bf26d5aa3e64c6d0495b11849f4ab768ff5715bf7a55a11b25015887b1f4c38acc336dcbe3
@@ -1,6 +1,7 @@
1
1
  sudo: false
2
2
 
3
3
  language: ruby
4
+ cache: bundler
4
5
 
5
6
  rvm:
6
7
  - "2.0.0"
@@ -12,6 +12,10 @@
12
12
  * `record_event` method to instrument events without a start hook
13
13
  * `send_params` is now configurable via the environment
14
14
  * Add DataMapper integration
15
+ * Add webmachine integration
16
+ * Allow overriding Padrino environment with APPSIGNAL_APP_ENV
17
+ * Add mkmf.log to diagnose command
18
+ * Allow for local install with bundler `bundle exec rake install`
15
19
 
16
20
  # 1.2.5
17
21
  * Bugfix in CPU utilization calculation for host metrics
data/Rakefile CHANGED
@@ -1,4 +1,6 @@
1
+ require 'bundler'
1
2
  require 'rspec/core/rake_task'
3
+
2
4
  GEMFILES = %w(
3
5
  capistrano2
4
6
  capistrano3
@@ -14,6 +16,8 @@ GEMFILES = %w(
14
16
  sequel
15
17
  sequel-435
16
18
  sinatra
19
+ grape
20
+ webmachine
17
21
  )
18
22
 
19
23
  RUBY_VERSIONS = %w(
@@ -102,8 +106,10 @@ end
102
106
 
103
107
  task :install do
104
108
  system 'cd ext && rm -f libappsignal.a appsignal-agent appsignal_extension.h Makefile appsignal_extension.bundle && ruby extconf.rb && make && cd ..'
105
- GEMFILES.each do |gemfile|
106
- system "bundle --gemfile gemfiles/#{gemfile}.gemfile"
109
+ Bundler.with_clean_env do
110
+ GEMFILES.each do |gemfile|
111
+ system "bundle --gemfile gemfiles/#{gemfile}.gemfile"
112
+ end
107
113
  end
108
114
  end
109
115
 
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'webmachine'
4
+
5
+ gemspec :path => '../'
@@ -61,10 +61,18 @@ module Appsignal
61
61
  require 'bundler/cli'
62
62
  require "bundler/cli/common"
63
63
  path = Bundler::CLI::Common.select_spec('appsignal').full_gem_path
64
- log_path = "#{path.strip}/ext/install.log"
65
- puts "Showing last lines of extension install log: #{log_path}"
66
- puts File.read(log_path)
64
+ install_log_path = "#{path.strip}/ext/install.log"
65
+ puts "Showing last lines of extension install log: #{install_log_path}"
66
+ puts File.read(install_log_path)
67
67
  puts "\n"
68
+ mkmf_log_path = "#{path.strip}/ext/mkmf.log"
69
+ if File.exists?(mkmf_log_path)
70
+ puts "Showing last lines of extension compilation log: #{mkmf_log_path}"
71
+ puts File.read(mkmf_log_path)
72
+ puts "\n"
73
+ else
74
+ puts "#{mkmf_log_path} not present"
75
+ end
68
76
  end
69
77
  end
70
78
  end
@@ -97,4 +97,5 @@ require 'appsignal/hooks/shoryuken'
97
97
  require 'appsignal/hooks/sidekiq'
98
98
  require 'appsignal/hooks/unicorn'
99
99
  require 'appsignal/hooks/mongo_ruby_driver'
100
+ require 'appsignal/hooks/webmachine'
100
101
  require 'appsignal/hooks/data_mapper'
@@ -0,0 +1,22 @@
1
+ module Appsignal
2
+ class Hooks
3
+ class WebmachineHook < Appsignal::Hooks::Hook
4
+ register :webmachine
5
+
6
+ def dependencies_present?
7
+ defined?(::Webmachine)
8
+ end
9
+
10
+ def install
11
+ require 'appsignal/integrations/webmachine'
12
+ ::Webmachine::Decision::FSM.class_eval do
13
+ include Appsignal::Integrations::WebmachinePlugin::FSM
14
+ alias run_without_appsignal run
15
+ alias run run_with_appsignal
16
+ alias handle_exceptions_without_appsignal handle_exceptions
17
+ alias handle_exceptions handle_exceptions_with_appsignal
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,13 +1,16 @@
1
1
  module Appsignal
2
2
  class Hooks
3
3
  module DataMapperLogListener
4
+ SQL_CLASSES = [
5
+ "DataObjects::SqlServer::Connection",
6
+ "DataObjects::Sqlite3::Connection",
7
+ "DataObjects::Mysql::Connection",
8
+ "DataObjects::Postgres::Connection"
9
+ ]
4
10
 
5
11
  def log(message)
6
- # Attempt to find the scheme used for this message
7
- scheme = instance_variable_get(:@uri).scheme
8
-
9
12
  # If scheme is SQL-like, try to sanitize it, otherwise clear the body
10
- if %w(sqlite sqlite3 mysql postgres).include?(scheme)
13
+ if SQL_CLASSES.include?(self.class.to_s)
11
14
  body_content = message.query
12
15
  body_format = Appsignal::EventFormatter::SQL_BODY_FORMAT
13
16
  else
@@ -8,7 +8,7 @@ module Appsignal::Integrations
8
8
  root = Padrino.mounted_root
9
9
  Appsignal.config = Appsignal::Config.new(
10
10
  root,
11
- Padrino.env,
11
+ ENV.fetch('APPSIGNAL_APP_ENV'.freeze, Padrino.env.to_s),
12
12
  :log_path => File.join(root, 'log')
13
13
  )
14
14
 
@@ -0,0 +1,36 @@
1
+ module Appsignal::Integrations
2
+ module WebmachinePlugin
3
+ module FSM
4
+
5
+ def run_with_appsignal
6
+ transaction = Appsignal::Transaction.create(
7
+ SecureRandom.uuid,
8
+ Appsignal::Transaction::HTTP_REQUEST,
9
+ request,
10
+ {:params_method => :query}
11
+ )
12
+
13
+ transaction.set_action("#{resource.class.name}##{request.method}")
14
+
15
+ ActiveSupport::Notifications.instrument('process_action.webmachine') do
16
+ run_without_appsignal
17
+ end
18
+
19
+ Appsignal::Transaction.complete_current!
20
+ end
21
+
22
+ private
23
+
24
+ def handle_exceptions_with_appsignal
25
+ handle_exceptions_without_appsignal do
26
+ begin
27
+ yield
28
+ rescue Exception => e
29
+ Appsignal.set_error(e)
30
+ raise e
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,5 +1,5 @@
1
1
  require 'yaml'
2
2
 
3
3
  module Appsignal
4
- VERSION = '1.3.0.beta.3'
4
+ VERSION = '1.3.0'
5
5
  end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ if webmachine_present?
4
+
5
+ describe Appsignal::Hooks::WebmachineHook do
6
+ context "with webmachine" do
7
+ before(:all) do
8
+ Appsignal::Hooks::WebmachineHook.new.install
9
+ end
10
+
11
+ its(:dependencies_present?) { should be_true }
12
+
13
+ let(:fsm) { Webmachine::Decision::FSM.new(double(:trace? => false), double, double) }
14
+
15
+ it "should include the run alias methods" do
16
+ expect( fsm ).to respond_to(:run_with_appsignal)
17
+ expect( fsm ).to respond_to(:run_without_appsignal)
18
+ end
19
+
20
+ it "should include the handle_exceptions alias methods" do
21
+ expect(
22
+ fsm.respond_to?(:handle_exceptions_with_appsignal, true)
23
+ ).to be_true
24
+
25
+ expect(
26
+ fsm.respond_to?(:handle_exceptions_without_appsignal, true)
27
+ ).to be_true
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -8,30 +8,27 @@ describe Appsignal::Hooks::DataMapperLogListener do
8
8
  end
9
9
  end
10
10
 
11
- class DataMapperTestClass
12
- include DataMapperLog
13
- include Appsignal::Hooks::DataMapperLogListener
14
-
15
- def initialize(uri)
16
- @uri = uri
17
- end
18
- end
19
-
20
11
  describe "#log" do
21
- let!(:data_mapper_class) { DataMapperTestClass.new(uri) }
22
- let(:uri) { double(:scheme => 'mysql') }
23
- let(:transaction) { double }
12
+ let(:transaction) { double }
24
13
  let(:message) do
25
14
  double(
26
15
  :query => "SELECT * from users",
27
16
  :duration => 100
28
17
  )
29
18
  end
30
-
31
- before do
32
- Appsignal::Transaction.stub(:current) { transaction }
19
+ let(:connection_class) do
20
+ module DataObjects
21
+ module Sqlite3
22
+ class Connection
23
+ include DataMapperLog
24
+ include Appsignal::Hooks::DataMapperLogListener
25
+ end
26
+ end
27
+ end
33
28
  end
34
29
 
30
+ before { Appsignal::Transaction.stub(:current) { transaction } }
31
+
35
32
  it "should record the log entry in an event" do
36
33
  expect( transaction ).to receive(:record_event).with(
37
34
  'query.data_mapper',
@@ -43,7 +40,16 @@ describe Appsignal::Hooks::DataMapperLogListener do
43
40
  end
44
41
 
45
42
  context "when scheme is not sql-like" do
46
- let(:uri) { double(:scheme => 'mongodb') }
43
+ let(:connection_class) do
44
+ module DataObjects
45
+ module MongoDB
46
+ class Connection
47
+ include DataMapperLog
48
+ include Appsignal::Hooks::DataMapperLogListener
49
+ end
50
+ end
51
+ end
52
+ end
47
53
 
48
54
  it "should record the log entry in an event without body" do
49
55
  expect( transaction ).to receive(:record_event).with(
@@ -56,6 +62,6 @@ describe Appsignal::Hooks::DataMapperLogListener do
56
62
  end
57
63
  end
58
64
 
59
- after { data_mapper_class.log(message) }
65
+ after { connection_class.new.log(message) }
60
66
  end
61
67
  end
@@ -38,6 +38,28 @@ if padrino_present?
38
38
  end
39
39
  end
40
40
 
41
+ context "when APPSIGNAL_APP_ENV ENV var is provided" do
42
+ it 'should use this as the environment' do
43
+ ENV['APPSIGNAL_APP_ENV'] = 'custom'
44
+
45
+ # Reset the plugin to pull down the latest data
46
+ Appsignal::Integrations::PadrinoPlugin.init
47
+
48
+ expect(Appsignal.config.env).to eq 'custom'
49
+ end
50
+ end
51
+
52
+ context "when APPSIGNAL_APP_ENV ENV var is not provided" do
53
+ it 'should use the Padrino environment' do
54
+ ENV['APPSIGNAL_APP_ENV'] = nil
55
+
56
+ # Reset the plugin to pull down the latest data
57
+ Appsignal::Integrations::PadrinoPlugin.init
58
+
59
+ expect(Appsignal.config.env).to eq Padrino.env.to_s
60
+ end
61
+ end
62
+
41
63
  after { Appsignal::Integrations::PadrinoPlugin.init }
42
64
  end
43
65
 
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+ if webmachine_present?
3
+
4
+ require 'appsignal/integrations/webmachine'
5
+
6
+ describe Appsignal::Integrations::WebmachinePlugin::FSM do
7
+ before(:all) do
8
+ Appsignal::Hooks::WebmachineHook.new.install
9
+ end
10
+ let(:request) do
11
+ Webmachine::Request.new('GET', 'http://google.com:80/foo', {}, nil)
12
+ end
13
+ let(:resource) { double(:trace? => false, :handle_exception => true) }
14
+ let(:response) { double }
15
+ let(:transaction) { double(:set_action => true) }
16
+
17
+ let(:fsm) { Webmachine::Decision::FSM.new(resource, request, response) }
18
+
19
+ # Make sure the request responds to the method we need to get query params.
20
+ describe "request" do
21
+ it "should respond to `query`" do
22
+ expect( request ).to respond_to(:query)
23
+ end
24
+ end
25
+
26
+ describe "#run_with_appsignal" do
27
+ before do
28
+ allow( fsm ).to receive(:request).and_return(request)
29
+ allow( fsm ).to receive(:run_without_appsignal).and_return(true)
30
+ allow( SecureRandom ).to receive(:uuid).and_return( 'uuid')
31
+ allow( Appsignal::Transaction ).to receive(:create).and_return(transaction)
32
+ end
33
+
34
+ it "should create a transaction" do
35
+ expect( Appsignal::Transaction ).to receive(:create).with(
36
+ 'uuid',
37
+ Appsignal::Transaction::HTTP_REQUEST,
38
+ request,
39
+ {:params_method => :query}
40
+ ).and_return(transaction)
41
+ end
42
+
43
+ it "should set the action" do
44
+ expect( transaction ).to receive(:set_action).with("RSpec::Mocks::Mock#GET")
45
+ end
46
+
47
+ it "should call the original method" do
48
+ expect( fsm ).to receive(:run_without_appsignal)
49
+ end
50
+
51
+ it "should instrument the original method" do
52
+ expect( ActiveSupport::Notifications ).to receive(:instrument).with('process_action.webmachine')
53
+ end
54
+
55
+ it "should close the transaction" do
56
+ expect( Appsignal::Transaction ).to receive(:complete_current!)
57
+ end
58
+
59
+ after { fsm.run }
60
+ end
61
+
62
+ describe "handle_exceptions_with_appsignal" do
63
+ let(:error) { VerySpecificError.new('error') }
64
+
65
+ it "should catch the error and send it to AppSignal" do
66
+ expect( Appsignal ).to receive(:set_error).with(error)
67
+ end
68
+
69
+ after do
70
+ begin
71
+ fsm.send(:handle_exceptions) { raise error };
72
+ rescue VerySpecificError => e
73
+ end
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -1,4 +1,6 @@
1
1
  ENV['RAILS_ENV'] ||= 'test'
2
+ ENV['PADRINO_ENV'] ||= 'test'
3
+
2
4
  require 'rack'
3
5
  require 'rspec'
4
6
  require 'pry'
@@ -69,15 +71,6 @@ rescue LoadError
69
71
  false
70
72
  end
71
73
 
72
- def active_job_present?
73
- begin
74
- require 'active_job'
75
- true
76
- rescue LoadError
77
- false
78
- end
79
- end
80
-
81
74
  def sinatra_present?
82
75
  begin
83
76
  require 'sinatra'
@@ -101,18 +94,33 @@ rescue LoadError
101
94
  false
102
95
  end
103
96
 
97
+ def webmachine_present?
98
+ require 'webmachine'
99
+ true
100
+ rescue LoadError
101
+ false
102
+ end
103
+
104
104
  require 'appsignal'
105
105
 
106
- Dir[File.expand_path(File.join(File.dirname(__FILE__), 'support/helpers','*.rb'))].each {|f| require f}
106
+ def spec_dir
107
+ File.dirname(__FILE__)
108
+ end
107
109
 
108
110
  def tmp_dir
109
- @tmp_dir ||= File.expand_path(File.join(File.dirname(__FILE__), 'tmp'))
111
+ @tmp_dir ||= File.expand_path('tmp', spec_dir)
110
112
  end
111
113
 
112
114
  def fixtures_dir
113
- @fixtures_dir ||= File.expand_path(File.join(File.dirname(__FILE__), 'support/fixtures'))
115
+ @fixtures_dir ||= File.expand_path('support/fixtures', spec_dir)
116
+ end
117
+
118
+ def helpers_dir
119
+ @helpers_dir ||= File.expand_path('support/helpers', spec_dir)
114
120
  end
115
121
 
122
+ Dir[File.join(helpers_dir, '*.rb')].each { |file| require file }
123
+
116
124
  # Add way to clear subscribers between specs
117
125
  module ActiveSupport
118
126
  module Notifications
@@ -143,6 +151,7 @@ RSpec.configure do |config|
143
151
 
144
152
  config.before do
145
153
  ENV['RAILS_ENV'] = 'test'
154
+ ENV['PADRINO_ENV'] = 'test'
146
155
 
147
156
  # Clean environment
148
157
  ENV.keys.select { |key| key.start_with?('APPSIGNAL_') }.each do |key|
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: 1.3.0.beta.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Beekman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-08-19 00:00:00.000000000 Z
12
+ date: 2016-08-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -147,6 +147,7 @@ files:
147
147
  - gemfiles/sequel-435.gemfile
148
148
  - gemfiles/sequel.gemfile
149
149
  - gemfiles/sinatra.gemfile
150
+ - gemfiles/webmachine.gemfile
150
151
  - lib/appsignal.rb
151
152
  - lib/appsignal/auth_check.rb
152
153
  - lib/appsignal/capistrano.rb
@@ -178,6 +179,7 @@ files:
178
179
  - lib/appsignal/hooks/shoryuken.rb
179
180
  - lib/appsignal/hooks/sidekiq.rb
180
181
  - lib/appsignal/hooks/unicorn.rb
182
+ - lib/appsignal/hooks/webmachine.rb
181
183
  - lib/appsignal/integrations/capistrano/appsignal.cap
182
184
  - lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb
183
185
  - lib/appsignal/integrations/data_mapper.rb
@@ -191,6 +193,7 @@ files:
191
193
  - lib/appsignal/integrations/resque.rb
192
194
  - lib/appsignal/integrations/resque_active_job.rb
193
195
  - lib/appsignal/integrations/sinatra.rb
196
+ - lib/appsignal/integrations/webmachine.rb
194
197
  - lib/appsignal/js_exception_transaction.rb
195
198
  - lib/appsignal/marker.rb
196
199
  - lib/appsignal/minutely.rb
@@ -246,6 +249,7 @@ files:
246
249
  - spec/lib/appsignal/hooks/shoryuken_spec.rb
247
250
  - spec/lib/appsignal/hooks/sidekiq_spec.rb
248
251
  - spec/lib/appsignal/hooks/unicorn_spec.rb
252
+ - spec/lib/appsignal/hooks/webmachine_spec.rb
249
253
  - spec/lib/appsignal/hooks_spec.rb
250
254
  - spec/lib/appsignal/integrations/data_mapper_spec.rb
251
255
  - spec/lib/appsignal/integrations/grape_spec.rb
@@ -256,6 +260,7 @@ files:
256
260
  - spec/lib/appsignal/integrations/resque_active_job_spec.rb
257
261
  - spec/lib/appsignal/integrations/resque_spec.rb
258
262
  - spec/lib/appsignal/integrations/sinatra_spec.rb
263
+ - spec/lib/appsignal/integrations/webmachine_spec.rb
259
264
  - spec/lib/appsignal/js_exception_transaction_spec.rb
260
265
  - spec/lib/appsignal/marker_spec.rb
261
266
  - spec/lib/appsignal/minutely_spec.rb
@@ -307,9 +312,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
307
312
  version: '1.9'
308
313
  required_rubygems_version: !ruby/object:Gem::Requirement
309
314
  requirements:
310
- - - ">"
315
+ - - ">="
311
316
  - !ruby/object:Gem::Version
312
- version: 1.3.1
317
+ version: '0'
313
318
  requirements: []
314
319
  rubyforge_project:
315
320
  rubygems_version: 2.5.1
@@ -347,6 +352,7 @@ test_files:
347
352
  - spec/lib/appsignal/hooks/shoryuken_spec.rb
348
353
  - spec/lib/appsignal/hooks/sidekiq_spec.rb
349
354
  - spec/lib/appsignal/hooks/unicorn_spec.rb
355
+ - spec/lib/appsignal/hooks/webmachine_spec.rb
350
356
  - spec/lib/appsignal/hooks_spec.rb
351
357
  - spec/lib/appsignal/integrations/data_mapper_spec.rb
352
358
  - spec/lib/appsignal/integrations/grape_spec.rb
@@ -357,6 +363,7 @@ test_files:
357
363
  - spec/lib/appsignal/integrations/resque_active_job_spec.rb
358
364
  - spec/lib/appsignal/integrations/resque_spec.rb
359
365
  - spec/lib/appsignal/integrations/sinatra_spec.rb
366
+ - spec/lib/appsignal/integrations/webmachine_spec.rb
360
367
  - spec/lib/appsignal/js_exception_transaction_spec.rb
361
368
  - spec/lib/appsignal/marker_spec.rb
362
369
  - spec/lib/appsignal/minutely_spec.rb