appsignal 0.12.beta.31 → 0.12.beta.32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/Rakefile +1 -0
- data/benchmark.rake +20 -20
- data/ext/appsignal_extension.c +31 -23
- data/gemfiles/padrino.gemfile +7 -0
- data/lib/appsignal.rb +50 -27
- data/lib/appsignal/capistrano.rb +2 -1
- data/lib/appsignal/config.rb +94 -39
- data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +12 -17
- data/lib/appsignal/integrations/padrino.rb +65 -0
- data/lib/appsignal/integrations/rails.rb +4 -2
- data/lib/appsignal/integrations/rake.rb +30 -0
- data/lib/appsignal/integrations/sidekiq.rb +2 -2
- data/lib/appsignal/integrations/sinatra.rb +0 -1
- data/lib/appsignal/js_exception_transaction.rb +4 -9
- data/lib/appsignal/params_sanitizer.rb +8 -5
- data/lib/appsignal/rack/rails_instrumentation.rb +41 -0
- data/lib/appsignal/rack/sinatra_instrumentation.rb +31 -24
- data/lib/appsignal/subscriber.rb +2 -9
- data/lib/appsignal/transaction.rb +86 -75
- data/lib/appsignal/transmitter.rb +30 -3
- data/lib/appsignal/version.rb +2 -2
- data/spec/lib/appsignal/cli_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +38 -131
- data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +27 -29
- data/spec/lib/appsignal/extension_spec.rb +11 -29
- data/spec/lib/appsignal/integrations/padrino_spec.rb +191 -0
- data/spec/lib/appsignal/integrations/rails_spec.rb +3 -4
- data/spec/lib/appsignal/integrations/rake_spec.rb +78 -0
- data/spec/lib/appsignal/integrations/resque_spec.rb +2 -2
- data/spec/lib/appsignal/integrations/sequel_spec.rb +2 -3
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +22 -5
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -6
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +4 -6
- data/spec/lib/appsignal/params_sanitizer_spec.rb +27 -11
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +79 -0
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +71 -71
- data/spec/lib/appsignal/subscriber_spec.rb +3 -37
- data/spec/lib/appsignal/transaction_spec.rb +290 -155
- data/spec/lib/appsignal/transmitter_spec.rb +10 -0
- data/spec/lib/appsignal_spec.rb +80 -47
- data/spec/spec_helper.rb +21 -2
- data/spec/support/helpers/env_helpers.rb +31 -0
- data/spec/support/helpers/notification_helpers.rb +1 -30
- data/spec/support/helpers/transaction_helpers.rb +7 -7
- data/spec/support/project_fixture/config/appsignal.yml +2 -0
- metadata +14 -8
- data/lib/appsignal/rack/instrumentation.rb +0 -32
- data/lib/appsignal/rack/listener.rb +0 -32
- data/spec/lib/appsignal/rack/instrumentation_spec.rb +0 -72
- data/spec/lib/appsignal/rack/listener_spec.rb +0 -104
@@ -60,13 +60,40 @@ module Appsignal
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def http_client
|
63
|
-
|
63
|
+
client = if config[:http_proxy]
|
64
|
+
Net::HTTP.new(uri.host, uri.port, proxy_addr, proxy_port)
|
65
|
+
else
|
66
|
+
Net::HTTP.new(uri.host, uri.port)
|
67
|
+
end
|
68
|
+
|
69
|
+
client.tap do |http|
|
64
70
|
if uri.scheme == 'https'
|
65
|
-
http.use_ssl
|
71
|
+
http.use_ssl = true
|
72
|
+
http.ssl_version = :TLSv1
|
66
73
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
67
|
-
http.ca_file
|
74
|
+
http.ca_file = CA_FILE_PATH
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|
78
|
+
|
79
|
+
def proxy_uri
|
80
|
+
@proxy_uri ||= URI.parse(config[:http_proxy])
|
81
|
+
end
|
82
|
+
|
83
|
+
def proxy_addr
|
84
|
+
if config[:http_proxy]
|
85
|
+
proxy_uri.host
|
86
|
+
else
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def proxy_port
|
92
|
+
if config[:http_proxy]
|
93
|
+
proxy_uri.port
|
94
|
+
else
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
end
|
71
98
|
end
|
72
99
|
end
|
data/lib/appsignal/version.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Appsignal::Config do
|
4
4
|
subject { config }
|
5
5
|
|
6
|
-
describe "
|
6
|
+
describe "with a config file" do
|
7
7
|
let(:config) { project_fixture_config('production') }
|
8
8
|
|
9
9
|
it "should not log an error" do
|
@@ -11,13 +11,13 @@ describe Appsignal::Config do
|
|
11
11
|
subject
|
12
12
|
end
|
13
13
|
|
14
|
-
its(:
|
14
|
+
its(:valid?) { should be_true }
|
15
15
|
its(:active?) { should be_true }
|
16
16
|
|
17
17
|
it "should merge with the default config and fill the config hash" do
|
18
18
|
subject.config_hash.should == {
|
19
19
|
:debug => false,
|
20
|
-
:
|
20
|
+
:ignore_errors => [],
|
21
21
|
:ignore_actions => [],
|
22
22
|
:instrument_net_http => true,
|
23
23
|
:skip_session_data => false,
|
@@ -43,6 +43,8 @@ describe Appsignal::Config do
|
|
43
43
|
|
44
44
|
describe "#write_to_environment" do
|
45
45
|
before do
|
46
|
+
subject.config_hash[:http_proxy] = 'http://localhost'
|
47
|
+
subject.config_hash[:ignore_actions] = ['action1', 'action2']
|
46
48
|
subject.write_to_environment
|
47
49
|
end
|
48
50
|
|
@@ -57,6 +59,8 @@ describe Appsignal::Config do
|
|
57
59
|
ENV['APPSIGNAL_APP_NAME'].should == 'TestApp'
|
58
60
|
ENV['APPSIGNAL_ENVIRONMENT'].should == 'production'
|
59
61
|
ENV['APPSIGNAL_AGENT_VERSION'].should == Appsignal::AGENT_VERSION
|
62
|
+
ENV['APPSIGNAL_HTTP_PROXY'].should == 'http://localhost'
|
63
|
+
ENV['APPSIGNAL_IGNORE_ACTIONS'].should == 'action1,action2'
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
@@ -66,14 +70,19 @@ describe Appsignal::Config do
|
|
66
70
|
its(:active?) { should be_true }
|
67
71
|
end
|
68
72
|
|
69
|
-
context "and there's
|
73
|
+
context "and there's config in the environment" do
|
70
74
|
before do
|
71
75
|
ENV['APPSIGNAL_PUSH_API_KEY'] = 'push_api_key'
|
76
|
+
ENV['APPSIGNAL_DEBUG'] = 'true'
|
72
77
|
end
|
73
78
|
|
74
|
-
it "should ignore the
|
79
|
+
it "should ignore env vars that are present in the config file" do
|
75
80
|
subject[:push_api_key].should == 'abc'
|
76
81
|
end
|
82
|
+
|
83
|
+
it "should use env vars that are not present in the config file" do
|
84
|
+
subject[:debug].should == true
|
85
|
+
end
|
77
86
|
end
|
78
87
|
|
79
88
|
context "and there is an initial config" do
|
@@ -85,12 +94,16 @@ describe Appsignal::Config do
|
|
85
94
|
end
|
86
95
|
end
|
87
96
|
|
88
|
-
context "and there is an old-style
|
97
|
+
context "and there is an old-style config" do
|
89
98
|
let(:config) { project_fixture_config('old_api_key') }
|
90
99
|
|
91
100
|
it "should fill the push_api_key with the old style key" do
|
92
101
|
subject[:push_api_key].should == 'def'
|
93
102
|
end
|
103
|
+
|
104
|
+
it "should fill ignore_errors with the old style ignore exceptions" do
|
105
|
+
subject[:ignore_errors].should == ['StandardError']
|
106
|
+
end
|
94
107
|
end
|
95
108
|
end
|
96
109
|
|
@@ -99,148 +112,42 @@ describe Appsignal::Config do
|
|
99
112
|
|
100
113
|
it "should log an error" do
|
101
114
|
Appsignal::Config.any_instance.should_receive(:carefully_log_error).with(
|
102
|
-
"Not loading: config for 'nonsense' not found"
|
103
|
-
)
|
115
|
+
"Not loading from config file: config for 'nonsense' not found"
|
116
|
+
).once
|
117
|
+
Appsignal::Config.any_instance.should_receive(:carefully_log_error).with(
|
118
|
+
"Push api key not set after loading config"
|
119
|
+
).once
|
104
120
|
subject
|
105
121
|
end
|
106
122
|
|
107
|
-
its(:
|
123
|
+
its(:valid?) { should be_false }
|
108
124
|
its(:active?) { should be_false }
|
109
125
|
end
|
110
126
|
|
111
127
|
context "when there is no config file" do
|
112
|
-
before do
|
113
|
-
ENV.keys.select { |key| key.start_with?('APPSIGNAL_') }.each do |key|
|
114
|
-
ENV[key] = nil
|
115
|
-
end
|
116
|
-
end
|
117
128
|
let(:initial_config) { {} }
|
118
129
|
let(:config) { Appsignal::Config.new('/nothing', 'production', initial_config) }
|
119
130
|
|
120
|
-
|
121
|
-
Appsignal::Config.any_instance.should_receive(:carefully_log_error).with(
|
122
|
-
"Not loading: No config file found at '/nothing/config/appsignal.yml' " \
|
123
|
-
"and no APPSIGNAL_PUSH_API_KEY env var present"
|
124
|
-
)
|
125
|
-
subject
|
126
|
-
end
|
127
|
-
|
128
|
-
its(:loaded?) { should be_false }
|
131
|
+
its(:valid?) { should be_false }
|
129
132
|
its(:active?) { should be_false }
|
130
133
|
|
131
|
-
|
132
|
-
it "should return nil" do
|
133
|
-
subject[:endpoint].should be_nil
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context "and an env var is present" do
|
134
|
+
context "with valid config in the environment" do
|
138
135
|
before do
|
139
|
-
ENV['APPSIGNAL_PUSH_API_KEY']
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
subject
|
136
|
+
ENV['APPSIGNAL_PUSH_API_KEY'] = 'aaa-bbb-ccc'
|
137
|
+
ENV['APPSIGNAL_ACTIVE'] = 'true'
|
138
|
+
ENV['APPSIGNAL_APP_NAME'] = 'App name'
|
139
|
+
ENV['APPSIGNAL_DEBUG'] = 'true'
|
140
|
+
ENV['APPSIGNAL_IGNORE_ACTIONS'] = 'action1,action2'
|
145
141
|
end
|
146
142
|
|
147
|
-
its(:
|
143
|
+
its(:valid?) { should be_true }
|
148
144
|
its(:active?) { should be_true }
|
149
145
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
subject.config_hash.should == {
|
156
|
-
:debug => false,
|
157
|
-
:push_api_key => 'push_api_key',
|
158
|
-
:ignore_exceptions => [],
|
159
|
-
:ignore_actions => [],
|
160
|
-
:send_params => true,
|
161
|
-
:instrument_net_http => true,
|
162
|
-
:skip_session_data => false,
|
163
|
-
:endpoint => 'https://push.appsignal.com',
|
164
|
-
:active => true,
|
165
|
-
:enable_frontend_error_catching => false,
|
166
|
-
:frontend_error_catching_path => '/appsignal_error_catcher'
|
167
|
-
}
|
168
|
-
end
|
169
|
-
|
170
|
-
context "and an initial config with a name is present" do
|
171
|
-
let(:initial_config) { {:name => 'Initial Name'} }
|
172
|
-
|
173
|
-
it "should merge with the config" do
|
174
|
-
Appsignal.logger.should_not_receive(:debug)
|
175
|
-
subject[:name].should == 'Initial Name'
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
context "more config in environment" do
|
180
|
-
context "APPSIGNAL_APP_NAME is set" do
|
181
|
-
before do
|
182
|
-
ENV['APPSIGNAL_APP_NAME'] = 'Name from env'
|
183
|
-
end
|
184
|
-
|
185
|
-
it "should set the name" do
|
186
|
-
Appsignal.logger.should_not_receive(:debug)
|
187
|
-
subject[:name].should == 'Name from env'
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
context "APPSIGNAL_ACTIVE" do
|
192
|
-
context "not present" do
|
193
|
-
before do
|
194
|
-
ENV.delete('APPSIGNAL_ACTIVE')
|
195
|
-
end
|
196
|
-
|
197
|
-
it "should still set active to true" do
|
198
|
-
subject[:active].should be_true
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
context "true" do
|
203
|
-
before do
|
204
|
-
ENV['APPSIGNAL_ACTIVE'] = 'true'
|
205
|
-
end
|
206
|
-
|
207
|
-
it "should set active to true" do
|
208
|
-
subject[:active].should be_true
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
context "false" do
|
213
|
-
before do
|
214
|
-
ENV['APPSIGNAL_ACTIVE'] = 'false'
|
215
|
-
end
|
216
|
-
|
217
|
-
it "should set active to false" do
|
218
|
-
subject[:active].should be_false
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
context "with only APPSIGNAL_API_KEY" do
|
225
|
-
before do
|
226
|
-
ENV.delete('APPSIGNAL_PUSH_API_KEY')
|
227
|
-
ENV['APPSIGNAL_API_KEY'] = 'old_style_api_key'
|
228
|
-
end
|
229
|
-
|
230
|
-
it "should use the old style api key" do
|
231
|
-
subject[:push_api_key].should == 'old_style_api_key'
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
context "with both APPSIGNAL_PUSH_API_KEY and APPSIGNAL_API_KEY" do
|
236
|
-
before do
|
237
|
-
ENV['APPSIGNAL_API_KEY'] = 'old_style_api_key'
|
238
|
-
end
|
239
|
-
|
240
|
-
it "should use the new style push api key" do
|
241
|
-
subject[:push_api_key].should == 'push_api_key'
|
242
|
-
end
|
243
|
-
end
|
146
|
+
its([:push_api_key]) { should == 'aaa-bbb-ccc' }
|
147
|
+
its([:active]) { should == true }
|
148
|
+
its([:name]) { should == 'App name' }
|
149
|
+
its([:debug]) { should == true }
|
150
|
+
its([:ignore_actions]) { should == ['action1', 'action2'] }
|
244
151
|
end
|
245
152
|
end
|
246
153
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
if
|
3
|
+
if active_record_present?
|
4
4
|
require 'active_record'
|
5
5
|
|
6
6
|
describe Appsignal::EventFormatter::ActiveRecord::SqlFormatter do
|
@@ -57,14 +57,8 @@ if rails_present?
|
|
57
57
|
|
58
58
|
it { should == ['Model load', "SELECT `table`.* FROM `table` WHERE `id` = ?"] }
|
59
59
|
|
60
|
-
context "with
|
61
|
-
let(:sql) { "`id` = '
|
62
|
-
|
63
|
-
it { should == ['Model load', "`id` = ?"] }
|
64
|
-
end
|
65
|
-
|
66
|
-
context "with an escaped double quote" do
|
67
|
-
let(:sql) { "`id` = '\\\"big\\\" secret'" }
|
60
|
+
context "with escaped single quotes in the string" do
|
61
|
+
let(:sql) { "`id` = 'this is a \'big\' secret'" }
|
68
62
|
|
69
63
|
it { should == ['Model load', "`id` = ?"] }
|
70
64
|
end
|
@@ -75,34 +69,36 @@ if rails_present?
|
|
75
69
|
|
76
70
|
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
77
71
|
|
78
|
-
context "with
|
79
|
-
let(:sql) { '`id` = "
|
72
|
+
context "with escaped double quotes in the string" do
|
73
|
+
let(:sql) { '`id` = "this is a \"big\" secret"' }
|
80
74
|
|
81
75
|
it { should == ['Model load', "`id` = ?"] }
|
82
76
|
end
|
77
|
+
end
|
83
78
|
|
84
|
-
|
85
|
-
|
79
|
+
context "numeric parameter" do
|
80
|
+
context "integer" do
|
81
|
+
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` = 1' }
|
86
82
|
|
87
|
-
it { should == ['Model load',
|
83
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` = ?'] }
|
88
84
|
end
|
89
|
-
end
|
90
85
|
|
91
|
-
|
92
|
-
|
86
|
+
context "float" do
|
87
|
+
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `value` = 10.0' }
|
93
88
|
|
94
|
-
|
89
|
+
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `value` = ?'] }
|
90
|
+
end
|
95
91
|
end
|
96
92
|
|
97
|
-
context "
|
93
|
+
context "in operator with params" do
|
98
94
|
let(:sql) { 'SELECT `table`.* FROM `table` WHERE `id` IN (1, 2)' }
|
99
95
|
|
100
96
|
it { should == ['Model load', 'SELECT `table`.* FROM `table` WHERE `id` IN (?)'] }
|
101
97
|
end
|
102
98
|
end
|
103
99
|
|
104
|
-
context "with double quote style table names
|
105
|
-
let(:connection_config) { {:adapter => 'postgresql'
|
100
|
+
context "with double quote style table names" do
|
101
|
+
let(:connection_config) { {:adapter => 'postgresql'} }
|
106
102
|
|
107
103
|
context "single quoted data value" do
|
108
104
|
let(:sql) { "SELECT \"table\".* FROM \"table\" WHERE \"id\" = 'secret'" }
|
@@ -110,22 +106,24 @@ if rails_present?
|
|
110
106
|
it { should == ['Model load', "SELECT \"table\".* FROM \"table\" WHERE \"id\" = ?"] }
|
111
107
|
|
112
108
|
context "with an escaped single quote" do
|
113
|
-
let(:sql) { "\"id\" = '
|
109
|
+
let(:sql) { "\"id\" = 'this is a \'big\' secret'" }
|
114
110
|
|
115
111
|
it { should == ['Model load', "\"id\" = ?"] }
|
116
112
|
end
|
113
|
+
end
|
117
114
|
|
118
|
-
|
119
|
-
|
115
|
+
context "numeric parameter" do
|
116
|
+
context "integer" do
|
117
|
+
let(:sql) { 'SELECT "table".* FROM "table" WHERE "id"=1' }
|
120
118
|
|
121
|
-
it { should == ['Model load', "
|
119
|
+
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "id"=?'] }
|
122
120
|
end
|
123
|
-
end
|
124
121
|
|
125
|
-
|
126
|
-
|
122
|
+
context "float" do
|
123
|
+
let(:sql) { 'SELECT "table".* FROM "table" WHERE "value"=10.0' }
|
127
124
|
|
128
|
-
|
125
|
+
it { should == ['Model load', 'SELECT "table".* FROM "table" WHERE "value"=?'] }
|
126
|
+
end
|
129
127
|
end
|
130
128
|
end
|
131
129
|
|
@@ -18,7 +18,7 @@ describe Appsignal::Extension do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should have a start_transaction method" do
|
21
|
-
subject.start_transaction('request_id')
|
21
|
+
subject.start_transaction('request_id', 'http_request')
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should have a start_event method" do
|
@@ -26,45 +26,27 @@ describe Appsignal::Extension do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should have a finish_event method" do
|
29
|
-
subject.finish_event(
|
30
|
-
1,
|
31
|
-
'name',
|
32
|
-
'title',
|
33
|
-
'body'
|
34
|
-
)
|
29
|
+
subject.finish_event(1, 'name', 'title', 'body')
|
35
30
|
end
|
36
31
|
|
37
32
|
it "should have a set_transaction_error method" do
|
38
|
-
subject.set_transaction_error(
|
39
|
-
1,
|
40
|
-
'name',
|
41
|
-
'message'
|
42
|
-
)
|
33
|
+
subject.set_transaction_error(1, 'name', 'message')
|
43
34
|
end
|
44
35
|
|
45
36
|
it "should have a set_transaction_error_data method" do
|
46
|
-
subject.set_transaction_error_data(
|
47
|
-
1,
|
48
|
-
'params',
|
49
|
-
'{}'
|
50
|
-
)
|
37
|
+
subject.set_transaction_error_data(1, 'params', '{}')
|
51
38
|
end
|
52
39
|
|
53
|
-
it "should have a
|
54
|
-
subject.
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
)
|
40
|
+
it "should have a set_transaction_action method" do
|
41
|
+
subject.set_transaction_action(1, 'value')
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should have a set_transaction_queue_start method" do
|
45
|
+
subject.set_transaction_queue_start(1, 10)
|
60
46
|
end
|
61
47
|
|
62
48
|
it "should have a set_transaction_metadata method" do
|
63
|
-
subject.set_transaction_metadata(
|
64
|
-
1,
|
65
|
-
'key',
|
66
|
-
'value'
|
67
|
-
)
|
49
|
+
subject.set_transaction_metadata(1, 'key', 'value')
|
68
50
|
end
|
69
51
|
|
70
52
|
it "should have a finish_transaction method" do
|