appsignal 0.11.18 → 0.12.beta.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/CHANGELOG.md +4 -38
- data/Rakefile +14 -6
- data/appsignal.gemspec +3 -1
- data/benchmark.rake +12 -16
- data/ext/appsignal_extension.c +183 -0
- data/ext/extconf.rb +39 -0
- data/gemfiles/capistrano2.gemfile +0 -1
- data/gemfiles/capistrano3.gemfile +0 -1
- data/gemfiles/rails-4.2.gemfile +1 -1
- data/lib/appsignal.rb +23 -61
- data/lib/appsignal/capistrano.rb +1 -2
- data/lib/appsignal/config.rb +13 -1
- data/lib/appsignal/event_formatter.rb +67 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +23 -0
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +74 -0
- data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
- data/lib/appsignal/event_formatter/net_http/request_formatter.rb +13 -0
- data/lib/appsignal/instrumentations/net_http.rb +6 -4
- data/lib/appsignal/integrations/resque.rb +2 -10
- data/lib/appsignal/integrations/sidekiq.rb +2 -2
- data/lib/appsignal/integrations/sinatra.rb +1 -0
- data/lib/appsignal/js_exception_transaction.rb +44 -28
- data/lib/appsignal/marker.rb +11 -13
- data/lib/appsignal/params_sanitizer.rb +5 -8
- data/lib/appsignal/rack/instrumentation.rb +2 -0
- data/lib/appsignal/rack/js_exception_catcher.rb +1 -0
- data/lib/appsignal/rack/listener.rb +1 -1
- data/lib/appsignal/rack/sinatra_instrumentation.rb +2 -12
- data/lib/appsignal/subscriber.rb +59 -0
- data/lib/appsignal/transaction.rb +117 -174
- data/lib/appsignal/transmitter.rb +8 -37
- data/lib/appsignal/version.rb +2 -1
- data/spec/lib/appsignal/config_spec.rb +25 -4
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +42 -0
- data/spec/lib/appsignal/{aggregator/middleware/active_record_sanitizer_spec.rb → event_formatter/active_record/sql_formatter_spec.rb} +61 -61
- data/spec/lib/appsignal/{event/moped_event_spec.rb → event_formatter/moped/query_formatter_spec.rb} +32 -78
- data/spec/lib/appsignal/event_formatter/net_http/request_formatter_spec.rb +26 -0
- data/spec/lib/appsignal/event_formatter_spec.rb +102 -0
- data/spec/lib/appsignal/extension_spec.rb +75 -0
- data/spec/lib/appsignal/instrumentations/net_http_spec.rb +20 -4
- data/spec/lib/appsignal/integrations/delayed_job_spec.rb +3 -2
- data/spec/lib/appsignal/integrations/rails_spec.rb +0 -7
- data/spec/lib/appsignal/integrations/resque_spec.rb +51 -55
- data/spec/lib/appsignal/integrations/sequel_spec.rb +8 -3
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -21
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -6
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +57 -60
- data/spec/lib/appsignal/params_sanitizer_spec.rb +11 -27
- data/spec/lib/appsignal/rack/listener_spec.rb +6 -6
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +2 -43
- data/spec/lib/appsignal/subscriber_spec.rb +162 -0
- data/spec/lib/appsignal/transaction_spec.rb +283 -615
- data/spec/lib/appsignal/transmitter_spec.rb +3 -32
- data/spec/lib/appsignal_spec.rb +41 -90
- data/spec/lib/generators/appsignal/appsignal_generator_spec.rb +0 -17
- data/spec/spec_helper.rb +18 -22
- data/spec/support/helpers/notification_helpers.rb +1 -1
- data/spec/support/helpers/time_helpers.rb +11 -0
- data/spec/support/helpers/transaction_helpers.rb +6 -18
- data/spec/support/project_fixture/config/appsignal.yml +1 -2
- metadata +68 -78
- checksums.yaml +0 -7
- data/gemfiles/padrino-0.13.gemfile +0 -7
- data/gemfiles/resque.gemfile +0 -5
- data/lib/appsignal/agent.rb +0 -217
- data/lib/appsignal/aggregator.rb +0 -67
- data/lib/appsignal/aggregator/middleware.rb +0 -4
- data/lib/appsignal/aggregator/middleware/action_view_sanitizer.rb +0 -23
- data/lib/appsignal/aggregator/middleware/active_record_sanitizer.rb +0 -65
- data/lib/appsignal/aggregator/middleware/chain.rb +0 -101
- data/lib/appsignal/aggregator/middleware/delete_blanks.rb +0 -16
- data/lib/appsignal/aggregator/post_processor.rb +0 -32
- data/lib/appsignal/event.rb +0 -20
- data/lib/appsignal/event/moped_event.rb +0 -90
- data/lib/appsignal/integrations/padrino.rb +0 -64
- data/lib/appsignal/integrations/passenger.rb +0 -13
- data/lib/appsignal/integrations/rake.rb +0 -29
- data/lib/appsignal/integrations/unicorn.rb +0 -25
- data/lib/appsignal/ipc.rb +0 -68
- data/lib/appsignal/transaction/formatter.rb +0 -85
- data/lib/appsignal/transaction/params_sanitizer.rb +0 -4
- data/lib/appsignal/zipped_payload.rb +0 -37
- data/spec/lib/appsignal/agent_spec.rb +0 -592
- data/spec/lib/appsignal/aggregator/middleware/action_view_sanitizer_spec.rb +0 -44
- data/spec/lib/appsignal/aggregator/middleware/chain_spec.rb +0 -168
- data/spec/lib/appsignal/aggregator/middleware/delete_blanks_spec.rb +0 -37
- data/spec/lib/appsignal/aggregator/post_processor_spec.rb +0 -99
- data/spec/lib/appsignal/aggregator_spec.rb +0 -186
- data/spec/lib/appsignal/event_spec.rb +0 -48
- data/spec/lib/appsignal/integrations/padrino_spec.rb +0 -171
- data/spec/lib/appsignal/integrations/passenger_spec.rb +0 -22
- data/spec/lib/appsignal/integrations/rake_spec.rb +0 -92
- data/spec/lib/appsignal/integrations/unicorn_spec.rb +0 -48
- data/spec/lib/appsignal/ipc_spec.rb +0 -128
- data/spec/lib/appsignal/transaction/formatter_spec.rb +0 -247
- data/spec/lib/appsignal/zipped_payload_spec.rb +0 -42
@@ -30,7 +30,7 @@ module Appsignal
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def uri
|
33
|
-
@uri ||= URI("#{config[:endpoint]}/#{action}").tap do |uri|
|
33
|
+
@uri ||= URI("#{config[:endpoint]}/1/#{action}").tap do |uri|
|
34
34
|
uri.query = ::Rack::Utils.build_query({
|
35
35
|
:api_key => config[:push_api_key],
|
36
36
|
:name => config[:name],
|
@@ -41,12 +41,7 @@ module Appsignal
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
# Accepts a string or `Appsignal::ZippedPayload`
|
45
|
-
# If no `Appsignal::ZippedPayload` is given, it will convert it to one.
|
46
44
|
def transmit(payload)
|
47
|
-
unless payload.is_a?(Appsignal::ZippedPayload)
|
48
|
-
payload = Appsignal::ZippedPayload.new(payload)
|
49
|
-
end
|
50
45
|
Appsignal.logger.debug "Transmitting payload to #{uri}"
|
51
46
|
http_client.request(http_post(payload)).code
|
52
47
|
end
|
@@ -57,45 +52,21 @@ module Appsignal
|
|
57
52
|
Net::HTTP::Post.new(uri.request_uri).tap do |request|
|
58
53
|
request['Content-Type'] = CONTENT_TYPE
|
59
54
|
request['Content-Encoding'] = CONTENT_ENCODING
|
60
|
-
request.body =
|
55
|
+
request.body = Zlib::Deflate.deflate(
|
56
|
+
JSON.generate(payload, :quirks_mode => true),
|
57
|
+
Zlib::BEST_SPEED
|
58
|
+
)
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
64
62
|
def http_client
|
65
|
-
|
66
|
-
Net::HTTP.new(uri.host, uri.port, proxy_addr, proxy_port)
|
67
|
-
else
|
68
|
-
Net::HTTP.new(uri.host, uri.port)
|
69
|
-
end
|
70
|
-
|
71
|
-
client.tap do |http|
|
63
|
+
Net::HTTP.new(uri.host, uri.port).tap do |http|
|
72
64
|
if uri.scheme == 'https'
|
73
|
-
http.use_ssl
|
74
|
-
http.ssl_version = :TLSv1
|
65
|
+
http.use_ssl = true
|
75
66
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
76
|
-
http.ca_file
|
67
|
+
http.ca_file = CA_FILE_PATH
|
77
68
|
end
|
78
69
|
end
|
79
70
|
end
|
80
|
-
|
81
|
-
def proxy_uri
|
82
|
-
@proxy_uri ||= URI.parse(config[:http_proxy])
|
83
|
-
end
|
84
|
-
|
85
|
-
def proxy_addr
|
86
|
-
if config[:http_proxy]
|
87
|
-
proxy_uri.host
|
88
|
-
else
|
89
|
-
nil
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def proxy_port
|
94
|
-
if config[:http_proxy]
|
95
|
-
proxy_uri.port
|
96
|
-
else
|
97
|
-
nil
|
98
|
-
end
|
99
|
-
end
|
100
71
|
end
|
101
72
|
end
|
data/lib/appsignal/version.rb
CHANGED
@@ -21,7 +21,7 @@ describe Appsignal::Config do
|
|
21
21
|
:instrument_net_http => true,
|
22
22
|
:skip_session_data => false,
|
23
23
|
:send_params => true,
|
24
|
-
:endpoint => 'https://push.appsignal.com
|
24
|
+
:endpoint => 'https://push.appsignal.com',
|
25
25
|
:slow_request_threshold => 200,
|
26
26
|
:push_api_key => 'abc',
|
27
27
|
:name => 'TestApp',
|
@@ -41,6 +41,24 @@ describe Appsignal::Config do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
describe "#write_to_environment" do
|
45
|
+
before do
|
46
|
+
subject.write_to_environment
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should write the current config to env vars" do
|
50
|
+
ENV['APPSIGNAL_ACTIVE'].should == 'true'
|
51
|
+
ENV['APPSIGNAL_APP_PATH'].should end_with('spec/support/project_fixture')
|
52
|
+
ENV['APPSIGNAL_AGENT_PATH'].should end_with('/ext')
|
53
|
+
ENV['APPSIGNAL_LOG_PATH'].should end_with('/log')
|
54
|
+
ENV['APPSIGNAL_PUSH_API_ENDPOINT'].should == 'https://push.appsignal.com'
|
55
|
+
ENV['APPSIGNAL_PUSH_API_KEY'].should == 'abc'
|
56
|
+
ENV['APPSIGNAL_APP_NAME'].should == 'TestApp'
|
57
|
+
ENV['APPSIGNAL_ENVIRONMENT'].should == 'production'
|
58
|
+
ENV['APPSIGNAL_AGENT_VERSION'].should == Appsignal::AGENT_VERSION
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
44
62
|
context "if the env is passed as a symbol" do
|
45
63
|
let(:config) { project_fixture_config(:production) }
|
46
64
|
|
@@ -63,7 +81,6 @@ describe Appsignal::Config do
|
|
63
81
|
it "should merge with the config" do
|
64
82
|
subject[:name].should == 'TestApp'
|
65
83
|
subject[:initial_key].should == 'value'
|
66
|
-
subject[:ignore_exceptions].should == []
|
67
84
|
end
|
68
85
|
end
|
69
86
|
|
@@ -91,6 +108,11 @@ describe Appsignal::Config do
|
|
91
108
|
end
|
92
109
|
|
93
110
|
context "when there is no config file" do
|
111
|
+
before do
|
112
|
+
ENV.keys.select { |key| key.start_with?('APPSIGNAL_') }.each do |key|
|
113
|
+
ENV[key] = nil
|
114
|
+
end
|
115
|
+
end
|
94
116
|
let(:initial_config) { {} }
|
95
117
|
let(:config) { Appsignal::Config.new('/nothing', 'production', initial_config) }
|
96
118
|
|
@@ -136,7 +158,7 @@ describe Appsignal::Config do
|
|
136
158
|
:send_params => true,
|
137
159
|
:instrument_net_http => true,
|
138
160
|
:skip_session_data => false,
|
139
|
-
:endpoint => 'https://push.appsignal.com
|
161
|
+
:endpoint => 'https://push.appsignal.com',
|
140
162
|
:slow_request_threshold => 200,
|
141
163
|
:active => true,
|
142
164
|
:enable_frontend_error_catching => false,
|
@@ -150,7 +172,6 @@ describe Appsignal::Config do
|
|
150
172
|
it "should merge with the config" do
|
151
173
|
Appsignal.logger.should_not_receive(:debug)
|
152
174
|
subject[:name].should == 'Initial Name'
|
153
|
-
subject[:ignore_exceptions].should == []
|
154
175
|
end
|
155
176
|
end
|
156
177
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
if rails_present?
|
4
|
+
require 'action_view'
|
5
|
+
|
6
|
+
describe Appsignal::EventFormatter::ActionView::RenderFormatter do
|
7
|
+
before { Rails.root.stub(:to_s => '/var/www/app/20130101') }
|
8
|
+
let(:klass) { Appsignal::EventFormatter::ActionView::RenderFormatter }
|
9
|
+
let(:formatter) { klass.new }
|
10
|
+
|
11
|
+
it "should register render_partial.action_view and render_template.action_view" do
|
12
|
+
Appsignal::EventFormatter.registered?('render_partial.action_view', klass).should be_true
|
13
|
+
Appsignal::EventFormatter.registered?('render_template.action_view', klass).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#root_path" do
|
17
|
+
its(:root_path) { should == '/var/www/app/20130101/' }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#format" do
|
21
|
+
subject { formatter.format(payload) }
|
22
|
+
|
23
|
+
context "with an identifier" do
|
24
|
+
let(:payload) { {:identifier => '/var/www/app/20130101/app/views/home/index/html.erb'} }
|
25
|
+
|
26
|
+
it { should == ['app/views/home/index/html.erb', nil] }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "with a frozen identifier" do
|
30
|
+
let(:payload) { {:identifier => '/var/www/app/20130101/app/views/home/index/html.erb'.freeze} }
|
31
|
+
|
32
|
+
it { should == ['app/views/home/index/html.erb', nil] }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "without an identifier" do
|
36
|
+
let(:payload) { {} }
|
37
|
+
|
38
|
+
it { should be_nil }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
if
|
3
|
+
if rails_present?
|
4
4
|
require 'active_record'
|
5
|
-
require 'appsignal/aggregator/middleware/active_record_sanitizer'
|
6
5
|
|
7
|
-
describe Appsignal::
|
8
|
-
let(:klass) { Appsignal::
|
9
|
-
let(:
|
6
|
+
describe Appsignal::EventFormatter::ActiveRecord::SqlFormatter do
|
7
|
+
let(:klass) { Appsignal::EventFormatter::ActiveRecord::SqlFormatter }
|
8
|
+
let(:formatter) { klass.new }
|
10
9
|
let(:connection_config) { {} }
|
11
10
|
before do
|
12
11
|
if ActiveRecord::Base.respond_to?(:connection_config)
|
@@ -23,80 +22,82 @@ if active_record_present?
|
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
:name => name,
|
34
|
-
:sql => sql,
|
35
|
-
:binds => binds,
|
36
|
-
:connection_id => 1111
|
37
|
-
)
|
38
|
-
)
|
25
|
+
pending "should register sql.activerecord" do
|
26
|
+
Appsignal::EventFormatter.registered?('sql.active_record', klass).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
context "if a connection cannot be established" do
|
30
|
+
before do
|
31
|
+
ActiveRecord::Base.stub(:connection_config).and_raise(ActiveRecord::ConnectionNotEstablished)
|
39
32
|
end
|
40
|
-
subject { event.payload[:sql] }
|
41
|
-
before { sql_event_sanitizer.call(event) { } }
|
42
33
|
|
43
|
-
|
44
|
-
|
45
|
-
|
34
|
+
it "should log the error and unregister the formatter" do
|
35
|
+
Appsignal.logger.should_receive(:error).with(
|
36
|
+
'Error while getting ActiveRecord connection info, unregistering sql.active_record event formatter'
|
37
|
+
)
|
38
|
+
|
39
|
+
lambda {
|
40
|
+
formatter
|
41
|
+
}.should_not raise_error
|
46
42
|
|
47
|
-
|
48
|
-
it { should_not have_key(:binds) }
|
43
|
+
Appsignal::EventFormatter.registered?('sql.active_record').should be_false
|
49
44
|
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#format" do
|
48
|
+
let(:name) { 'Model load' }
|
49
|
+
let(:payload) { {:sql => sql, :name => name} }
|
50
|
+
subject { formatter.format(payload) }
|
50
51
|
|
51
52
|
context "with backtick table names" do
|
52
|
-
before {
|
53
|
+
before { formatter.stub(:adapter_uses_double_quoted_table_names => false) }
|
53
54
|
|
54
55
|
context "single quoted data value" do
|
55
56
|
let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret'" }
|
56
57
|
|
57
|
-
it { should == "SELECT `table`.* FROM `table` WHERE `id` = ?" }
|
58
|
+
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ?"] }
|
58
59
|
|
59
60
|
context "with an escaped single quote" do
|
60
61
|
let(:sql) { "`id` = '\\'big\\' secret'" }
|
61
62
|
|
62
|
-
it { should == "`id` = ?" }
|
63
|
+
it { should == ['Model load', "`id` = ?"] }
|
63
64
|
end
|
64
65
|
|
65
66
|
context "with an escaped double quote" do
|
66
67
|
let(:sql) { "`id` = '\\\"big\\\" secret'" }
|
67
68
|
|
68
|
-
it { should == "`id` = ?" }
|
69
|
+
it { should == ['Model load', "`id` = ?"] }
|
69
70
|
end
|
70
71
|
end
|
71
72
|
|
72
73
|
context "double quoted data value" do
|
73
74
|
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = "secret"' }
|
74
75
|
|
75
|
-
it { should == 'SELECT `table`.* FROM `table` WHERE `id` = ?' }
|
76
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
76
77
|
|
77
78
|
context "with an escaped single quote" do
|
78
79
|
let(:sql) { '`id` = "\\\'big\\\' secret"' }
|
79
80
|
|
80
|
-
it { should == "`id` = ?" }
|
81
|
+
it { should == ['Model load', "`id` = ?"] }
|
81
82
|
end
|
82
83
|
|
83
84
|
context "with an escaped double quote" do
|
84
85
|
let(:sql) { '`id` = "\\"big\\" secret"' }
|
85
86
|
|
86
|
-
it { should == "`id` = ?" }
|
87
|
+
it { should == ['Model load', "`id` = ?"] }
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
90
91
|
context "numeric parameter" do
|
91
92
|
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = 1' }
|
92
93
|
|
93
|
-
it { should == 'SELECT `table`.* FROM `table` WHERE `id` = ?' }
|
94
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
94
95
|
end
|
95
96
|
|
96
97
|
context "parameter array" do
|
97
98
|
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (1, 2)' }
|
98
99
|
|
99
|
-
it { should == 'SELECT `table`.* FROM `table` WHERE `id` IN (?)' }
|
100
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (?)'] }
|
100
101
|
end
|
101
102
|
end
|
102
103
|
|
@@ -106,25 +107,25 @@ if active_record_present?
|
|
106
107
|
context "single quoted data value" do
|
107
108
|
let(:sql) { "SELECT \"table\".* FROM \"table\" WHERE \"id\" = 'secret'" }
|
108
109
|
|
109
|
-
it { should == "SELECT \"table\".* FROM \"table\" WHERE \"id\" = ?" }
|
110
|
+
it { should == ['Model load', "SELECT \"table\".* FROM \"table\" WHERE \"id\" = ?"] }
|
110
111
|
|
111
112
|
context "with an escaped single quote" do
|
112
113
|
let(:sql) { "\"id\" = '\\'big\\' secret'" }
|
113
114
|
|
114
|
-
it { should == "\"id\" = ?" }
|
115
|
+
it { should == ['Model load', "\"id\" = ?"] }
|
115
116
|
end
|
116
117
|
|
117
118
|
context "with an escaped double quote" do
|
118
119
|
let(:sql) { "\"id\" = '\\\"big\\\" secret'" }
|
119
120
|
|
120
|
-
it { should == "\"id\" = ?" }
|
121
|
+
it { should == ['Model load', "\"id\" = ?"] }
|
121
122
|
end
|
122
123
|
end
|
123
124
|
|
124
125
|
context "numeric parameter" do
|
125
126
|
let(:sql) { 'SELECT "table".* FROM "table" WHERE "id"=1' }
|
126
127
|
|
127
|
-
it { should == 'SELECT "table".* FROM "table" WHERE "id"=?' }
|
128
|
+
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "id"=?'] }
|
128
129
|
end
|
129
130
|
end
|
130
131
|
|
@@ -133,27 +134,26 @@ if active_record_present?
|
|
133
134
|
|
134
135
|
let(:sql) { 'SELECT "table".* FROM "table" WHERE "id"=$1' }
|
135
136
|
|
136
|
-
it { should == 'SELECT "table".* FROM "table" WHERE "id"=$1' }
|
137
|
+
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "id"=$1'] }
|
137
138
|
end
|
138
139
|
|
139
|
-
context "
|
140
|
+
context "return nil for schema queries" do
|
140
141
|
let(:name) { 'SCHEMA' }
|
141
142
|
let(:sql) { 'SET client_min_messages TO 22' }
|
142
143
|
|
143
|
-
it { should
|
144
|
+
it { should be_nil }
|
144
145
|
end
|
145
146
|
|
146
147
|
context "with a a frozen sql string" do
|
147
148
|
let(:sql) { "SELECT `table`.* FROM `table` WHERE `id` = 'secret'".freeze }
|
148
149
|
|
149
|
-
it { should == "SELECT `table`.* FROM `table` WHERE `id` = ?" }
|
150
|
+
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ?"] }
|
150
151
|
end
|
151
152
|
end
|
152
153
|
|
153
154
|
describe "#schema_query?" do
|
154
155
|
let(:payload) { {} }
|
155
|
-
|
156
|
-
subject { sql_event_sanitizer.schema_query?(event) }
|
156
|
+
subject { formatter.send(:schema_query?, payload) }
|
157
157
|
|
158
158
|
it { should be_false }
|
159
159
|
|
@@ -168,13 +168,13 @@ if active_record_present?
|
|
168
168
|
describe "#connection_config" do
|
169
169
|
let(:connection_config) { {:adapter => 'adapter'} }
|
170
170
|
|
171
|
-
subject {
|
171
|
+
subject { formatter.send(:connection_config) }
|
172
172
|
|
173
173
|
it { should == {:adapter => 'adapter'} }
|
174
174
|
end
|
175
175
|
|
176
|
-
describe "#adapter_uses_double_quoted_table_names
|
177
|
-
subject {
|
176
|
+
describe "#adapter_uses_double_quoted_table_names" do
|
177
|
+
subject { formatter.adapter_uses_double_quoted_table_names }
|
178
178
|
|
179
179
|
context "when using mysql" do
|
180
180
|
let(:connection_config) { {:adapter => 'mysql'} }
|
@@ -193,27 +193,27 @@ if active_record_present?
|
|
193
193
|
|
194
194
|
it { should be_true }
|
195
195
|
end
|
196
|
-
end
|
197
196
|
|
198
|
-
|
199
|
-
|
197
|
+
describe "adapter_uses_prepared_statements" do
|
198
|
+
subject { formatter.adapter_uses_prepared_statements }
|
200
199
|
|
201
|
-
|
202
|
-
|
200
|
+
context "when using mysql" do
|
201
|
+
let(:connection_config) { {:adapter => 'mysql'} }
|
203
202
|
|
204
|
-
|
205
|
-
|
203
|
+
it { should be_false }
|
204
|
+
end
|
206
205
|
|
207
|
-
|
208
|
-
|
206
|
+
context "when using postgresql" do
|
207
|
+
let(:connection_config) { {:adapter => 'postgresql'} }
|
209
208
|
|
210
|
-
|
211
|
-
|
209
|
+
it { should be_true }
|
210
|
+
end
|
212
211
|
|
213
|
-
|
214
|
-
|
212
|
+
context "when using postgresql and prepared statements is disabled" do
|
213
|
+
let(:connection_config) { {:adapter => 'postgresql', :prepared_statements => false} }
|
215
214
|
|
216
|
-
|
215
|
+
it { should be_false }
|
216
|
+
end
|
217
217
|
end
|
218
218
|
end
|
219
219
|
end
|
data/spec/lib/appsignal/{event/moped_event_spec.rb → event_formatter/moped/query_formatter_spec.rb}
RENAMED
@@ -1,23 +1,25 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Appsignal::
|
4
|
-
let(:
|
5
|
-
|
3
|
+
describe Appsignal::EventFormatter::Moped::QueryFormatter do
|
4
|
+
let(:klass) { Appsignal::EventFormatter::Moped::QueryFormatter }
|
5
|
+
let(:formatter) { klass.new }
|
6
|
+
|
7
|
+
it "should register query.moped" do
|
8
|
+
Appsignal::EventFormatter.registered?('query.moped', klass).should be_true
|
6
9
|
end
|
7
10
|
|
8
|
-
describe "#
|
9
|
-
|
11
|
+
describe "#format" do
|
12
|
+
let(:payload) { {:ops => [op]} }
|
13
|
+
subject { formatter.format(payload) }
|
14
|
+
|
15
|
+
context "without ops in the payload" do
|
16
|
+
let(:payload) { {} }
|
10
17
|
|
11
|
-
|
12
|
-
expect( event.transform_payload(:ops => [{}]) ).to eq(
|
13
|
-
:ops => [{'foo' => 'bar'}]
|
14
|
-
)
|
18
|
+
it { should be_nil }
|
15
19
|
end
|
16
|
-
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
let(:payload) do
|
21
|
+
context "Moped::Protocol::Command" do
|
22
|
+
let(:op) do
|
21
23
|
double(
|
22
24
|
:full_collection_name => 'database.collection',
|
23
25
|
:selector => {'_id' => 'abc'},
|
@@ -25,17 +27,11 @@ describe Appsignal::Event::MopedEvent do
|
|
25
27
|
)
|
26
28
|
end
|
27
29
|
|
28
|
-
it
|
29
|
-
expect( event.payload_from_op(payload) ).to eq(
|
30
|
-
:type => "Command",
|
31
|
-
:database => "database.collection",
|
32
|
-
:selector => {"_id" => "?"}
|
33
|
-
)
|
34
|
-
end
|
30
|
+
it { should == ['Command', '{:database=>"database.collection", :selector=>{"_id"=>"?"}}'] }
|
35
31
|
end
|
36
32
|
|
37
33
|
context "Moped::Protocol::Query" do
|
38
|
-
let(:
|
34
|
+
let(:op) do
|
39
35
|
double(
|
40
36
|
:full_collection_name => 'database.collection',
|
41
37
|
:selector => {'_id' => 'abc'},
|
@@ -47,21 +43,11 @@ describe Appsignal::Event::MopedEvent do
|
|
47
43
|
)
|
48
44
|
end
|
49
45
|
|
50
|
-
it
|
51
|
-
expect( event.payload_from_op(payload) ).to eq(
|
52
|
-
:type => "Query",
|
53
|
-
:database => "database.collection",
|
54
|
-
:selector => {"_id" => "?"},
|
55
|
-
:flags => [],
|
56
|
-
:limit => 0,
|
57
|
-
:skip => 0,
|
58
|
-
:fields => nil,
|
59
|
-
)
|
60
|
-
end
|
46
|
+
it { should == ['Query', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :flags=>[], :limit=>0, :skip=>0, :fields=>nil}'] }
|
61
47
|
end
|
62
48
|
|
63
49
|
context "Moped::Protocol::Delete" do
|
64
|
-
let(:
|
50
|
+
let(:op) do
|
65
51
|
double(
|
66
52
|
:full_collection_name => 'database.collection',
|
67
53
|
:selector => {'_id' => 'abc'},
|
@@ -70,18 +56,11 @@ describe Appsignal::Event::MopedEvent do
|
|
70
56
|
)
|
71
57
|
end
|
72
58
|
|
73
|
-
it
|
74
|
-
expect( event.payload_from_op(payload) ).to eq(
|
75
|
-
:type => "Delete",
|
76
|
-
:database => "database.collection",
|
77
|
-
:selector => {"_id" => "?"},
|
78
|
-
:flags => []
|
79
|
-
)
|
80
|
-
end
|
59
|
+
it { should == ['Delete', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :flags=>[]}'] }
|
81
60
|
end
|
82
61
|
|
83
62
|
context "Moped::Protocol::Insert" do
|
84
|
-
let(:
|
63
|
+
let(:op) do
|
85
64
|
double(
|
86
65
|
:full_collection_name => 'database.collection',
|
87
66
|
:flags => [],
|
@@ -90,18 +69,11 @@ describe Appsignal::Event::MopedEvent do
|
|
90
69
|
)
|
91
70
|
end
|
92
71
|
|
93
|
-
it
|
94
|
-
expect( event.payload_from_op(payload) ).to eq(
|
95
|
-
:type => "Insert",
|
96
|
-
:database => "database.collection",
|
97
|
-
:flags => [],
|
98
|
-
:documents => [{"_id" => "?"}, {"_id" => "?"}]
|
99
|
-
)
|
100
|
-
end
|
72
|
+
it { should == ['Insert', '{:database=>"database.collection", :documents=>[{"_id"=>"?"}, {"_id"=>"?"}], :flags=>[]}'] }
|
101
73
|
end
|
102
74
|
|
103
75
|
context "Moped::Protocol::Update" do
|
104
|
-
let(:
|
76
|
+
let(:op) do
|
105
77
|
double(
|
106
78
|
:full_collection_name => 'database.collection',
|
107
79
|
:selector => {'_id' => 'abc'},
|
@@ -111,47 +83,29 @@ describe Appsignal::Event::MopedEvent do
|
|
111
83
|
)
|
112
84
|
end
|
113
85
|
|
114
|
-
it
|
115
|
-
expect( event.payload_from_op(payload) ).to eq(
|
116
|
-
:type => "Update",
|
117
|
-
:database => "database.collection",
|
118
|
-
:selector => {"_id" => "?"},
|
119
|
-
:update => {"name" => "?"},
|
120
|
-
:flags => []
|
121
|
-
)
|
122
|
-
end
|
86
|
+
it { should == ['Update', '{:database=>"database.collection", :selector=>{"_id"=>"?"}, :update=>{"name"=>"?"}, :flags=>[]}'] }
|
123
87
|
end
|
124
88
|
|
125
89
|
context "Moped::Protocol::KillCursors" do
|
126
|
-
let(:
|
90
|
+
let(:op) do
|
127
91
|
double(
|
128
92
|
:number_of_cursor_ids => 2,
|
129
93
|
:class => double(:to_s => 'Moped::Protocol::KillCursors')
|
130
94
|
)
|
131
95
|
end
|
132
96
|
|
133
|
-
it
|
134
|
-
expect( event.payload_from_op(payload) ).to eq(
|
135
|
-
:type => "KillCursors",
|
136
|
-
:number_of_cursor_ids => 2
|
137
|
-
)
|
138
|
-
end
|
97
|
+
it { should == ['KillCursors', '{:number_of_cursor_ids=>2}'] }
|
139
98
|
end
|
140
99
|
|
141
100
|
context "Moped::Protocol::Other" do
|
142
|
-
let(:
|
101
|
+
let(:op) do
|
143
102
|
double(
|
144
103
|
:full_collection_name => 'database.collection',
|
145
104
|
:class => double(:to_s => 'Moped::Protocol::Other')
|
146
105
|
)
|
147
106
|
end
|
148
107
|
|
149
|
-
it
|
150
|
-
expect( event.payload_from_op(payload) ).to eq(
|
151
|
-
:type => "Other",
|
152
|
-
:database => "database.collection"
|
153
|
-
)
|
154
|
-
end
|
108
|
+
it { should == ['Other', '{:database=>"database.collection"}'] }
|
155
109
|
end
|
156
110
|
end
|
157
111
|
|
@@ -160,7 +114,7 @@ describe Appsignal::Event::MopedEvent do
|
|
160
114
|
let(:params) { {'foo' => 'bar'} }
|
161
115
|
|
162
116
|
it "should sanitize all hash values with a questionmark" do
|
163
|
-
expect(
|
117
|
+
expect( formatter.send(:sanitize, params) ).to eq('foo' => '?')
|
164
118
|
end
|
165
119
|
end
|
166
120
|
|
@@ -168,7 +122,7 @@ describe Appsignal::Event::MopedEvent do
|
|
168
122
|
let(:params) { [{'foo' => 'bar'}] }
|
169
123
|
|
170
124
|
it "should sanitize all hash values with a questionmark" do
|
171
|
-
expect(
|
125
|
+
expect( formatter.send(:sanitize, params) ).to eq([{'foo' => '?'}])
|
172
126
|
end
|
173
127
|
end
|
174
128
|
|
@@ -176,14 +130,14 @@ describe Appsignal::Event::MopedEvent do
|
|
176
130
|
let(:params) { ['foo', 'bar'] }
|
177
131
|
|
178
132
|
it "should sanitize all hash values with a single questionmark" do
|
179
|
-
expect(
|
133
|
+
expect( formatter.send(:sanitize, params) ).to eq(['?'])
|
180
134
|
end
|
181
135
|
end
|
182
136
|
context "when params is a string" do
|
183
137
|
let(:params) { 'bar'}
|
184
138
|
|
185
139
|
it "should sanitize all hash values with a questionmark" do
|
186
|
-
expect(
|
140
|
+
expect( formatter.send(:sanitize, params) ).to eq('?')
|
187
141
|
end
|
188
142
|
end
|
189
143
|
end
|