appsignal 1.3.0.beta.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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