appsignal 3.10.0 → 3.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +197 -0
- data/Gemfile +1 -0
- data/Rakefile +1 -1
- data/benchmark.rake +99 -42
- data/lib/appsignal/cli/demo.rb +0 -1
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +204 -130
- data/lib/appsignal/demo.rb +16 -26
- data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
- data/lib/appsignal/event_formatter.rb +3 -2
- data/lib/appsignal/helpers/instrumentation.rb +331 -19
- data/lib/appsignal/hooks/action_cable.rb +21 -16
- data/lib/appsignal/hooks/active_job.rb +14 -8
- data/lib/appsignal/hooks/delayed_job.rb +1 -1
- data/lib/appsignal/hooks/shoryuken.rb +3 -63
- data/lib/appsignal/integrations/action_cable.rb +5 -7
- data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
- data/lib/appsignal/integrations/data_mapper.rb +1 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
- data/lib/appsignal/integrations/dry_monitor.rb +1 -0
- data/lib/appsignal/integrations/excon.rb +1 -0
- data/lib/appsignal/integrations/grape.rb +7 -0
- data/lib/appsignal/integrations/hanami.rb +8 -43
- data/lib/appsignal/integrations/http.rb +1 -0
- data/lib/appsignal/integrations/net_http.rb +1 -0
- data/lib/appsignal/integrations/object.rb +6 -0
- data/lib/appsignal/integrations/padrino.rb +8 -73
- data/lib/appsignal/integrations/que.rb +13 -20
- data/lib/appsignal/integrations/railtie.rb +36 -14
- data/lib/appsignal/integrations/rake.rb +1 -5
- data/lib/appsignal/integrations/redis.rb +1 -0
- data/lib/appsignal/integrations/redis_client.rb +1 -0
- data/lib/appsignal/integrations/resque.rb +2 -5
- data/lib/appsignal/integrations/shoryuken.rb +75 -0
- data/lib/appsignal/integrations/sidekiq.rb +7 -15
- data/lib/appsignal/integrations/sinatra.rb +8 -19
- data/lib/appsignal/integrations/unicorn.rb +1 -0
- data/lib/appsignal/integrations/webmachine.rb +2 -5
- data/lib/appsignal/loaders/grape.rb +13 -0
- data/lib/appsignal/loaders/hanami.rb +40 -0
- data/lib/appsignal/loaders/padrino.rb +68 -0
- data/lib/appsignal/loaders/sinatra.rb +24 -0
- data/lib/appsignal/loaders.rb +92 -0
- data/lib/appsignal/logger.rb +7 -3
- data/lib/appsignal/probes/helpers.rb +1 -0
- data/lib/appsignal/probes/mri.rb +1 -0
- data/lib/appsignal/probes/sidekiq.rb +1 -0
- data/lib/appsignal/probes.rb +3 -0
- data/lib/appsignal/rack/abstract_middleware.rb +20 -13
- data/lib/appsignal/rack/event_handler.rb +44 -13
- data/lib/appsignal/rack/generic_instrumentation.rb +1 -0
- data/lib/appsignal/rack/grape_middleware.rb +2 -1
- data/lib/appsignal/rack/streaming_listener.rb +1 -0
- data/lib/appsignal/rack.rb +35 -0
- data/lib/appsignal/span.rb +1 -0
- data/lib/appsignal/transaction.rb +308 -101
- data/lib/appsignal/utils/data.rb +0 -1
- data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
- data/lib/appsignal/utils/integration_logger.rb +0 -13
- data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
- data/lib/appsignal/utils/json.rb +0 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
- data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
- data/lib/appsignal/utils.rb +6 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +169 -14
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/cli/demo_spec.rb +0 -1
- data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1
- data/spec/lib/appsignal/config_spec.rb +291 -44
- data/spec/lib/appsignal/demo_spec.rb +1 -2
- data/spec/lib/appsignal/environment_spec.rb +4 -2
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/activejob_spec.rb +12 -3
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
- data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +4 -7
- data/spec/lib/appsignal/hooks/excon_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/gvl_spec.rb +2 -2
- data/spec/lib/appsignal/hooks/http_spec.rb +1 -3
- data/spec/lib/appsignal/hooks/net_http_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -8
- data/spec/lib/appsignal/hooks/redis_spec.rb +3 -6
- data/spec/lib/appsignal/hooks/resque_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/sequel_spec.rb +3 -5
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +1 -1
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
- data/spec/lib/appsignal/integrations/grape_spec.rb +36 -0
- data/spec/lib/appsignal/integrations/hanami_spec.rb +9 -178
- data/spec/lib/appsignal/integrations/http_spec.rb +1 -5
- data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +4 -2
- data/spec/lib/appsignal/integrations/net_http_spec.rb +1 -1
- data/spec/lib/appsignal/integrations/object_spec.rb +1 -3
- data/spec/lib/appsignal/integrations/padrino_spec.rb +8 -330
- data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
- data/spec/lib/appsignal/integrations/railtie_spec.rb +275 -191
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +15 -13
- data/spec/lib/appsignal/integrations/sinatra_spec.rb +9 -104
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +13 -1
- data/spec/lib/appsignal/loaders/grape_spec.rb +12 -0
- data/spec/lib/appsignal/loaders/hanami_spec.rb +95 -0
- data/spec/lib/appsignal/loaders/padrino_spec.rb +277 -0
- data/spec/lib/appsignal/loaders/sinatra_spec.rb +47 -0
- data/spec/lib/appsignal/loaders_spec.rb +137 -0
- data/spec/lib/appsignal/probes/sidekiq_spec.rb +1 -1
- data/spec/lib/appsignal/probes_spec.rb +6 -5
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +51 -5
- data/spec/lib/appsignal/rack/event_handler_spec.rb +114 -10
- data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +1 -1
- data/spec/lib/appsignal/rack/grape_middleware_spec.rb +2 -35
- data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +1 -1
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
- data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +3 -3
- data/spec/lib/appsignal/rack_spec.rb +63 -0
- data/spec/lib/appsignal/span_spec.rb +1 -3
- data/spec/lib/appsignal/transaction_spec.rb +1640 -1075
- data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
- data/spec/lib/appsignal_spec.rb +601 -36
- data/spec/lib/puma/appsignal_spec.rb +0 -3
- data/spec/spec_helper.rb +5 -4
- data/spec/support/helpers/config_helpers.rb +2 -1
- data/spec/support/helpers/loader_helper.rb +21 -0
- data/spec/support/helpers/transaction_helpers.rb +44 -20
- data/spec/support/matchers/transaction.rb +15 -1
- data/spec/support/stubs/appsignal/loaders/loader_stub.rb +7 -0
- data/spec/support/testing.rb +47 -1
- metadata +19 -2
data/spec/lib/appsignal_spec.rb
CHANGED
@@ -2,22 +2,226 @@ describe Appsignal do
|
|
2
2
|
include EnvironmentMetadataHelper
|
3
3
|
around { |example| keep_transactions { example.run } }
|
4
4
|
|
5
|
-
before do
|
6
|
-
# Make sure we have a clean state because we want to test
|
7
|
-
# initialization here.
|
8
|
-
Appsignal.config = nil
|
9
|
-
end
|
10
|
-
|
11
5
|
let(:transaction) { http_request_transaction }
|
12
6
|
|
13
7
|
describe ".config=" do
|
14
|
-
it "
|
8
|
+
it "sets the config" do
|
15
9
|
config = project_fixture_config
|
16
10
|
expect(Appsignal.internal_logger).to_not receive(:level=)
|
17
11
|
|
18
|
-
Appsignal.config = config
|
12
|
+
silence { Appsignal.config = config }
|
19
13
|
expect(Appsignal.config).to eq config
|
20
14
|
end
|
15
|
+
|
16
|
+
it "prints a deprecation warning" do
|
17
|
+
err_stream = std_stream
|
18
|
+
capture_std_streams(std_stream, err_stream) do
|
19
|
+
Appsignal.config = project_fixture_config
|
20
|
+
end
|
21
|
+
expect(err_stream.read).to include(
|
22
|
+
"appsignal WARNING: Configuring AppSignal with `Appsignal.config=` is deprecated."
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "logs a deprecation warning" do
|
27
|
+
logs = capture_logs { silence { Appsignal.config = project_fixture_config } }
|
28
|
+
expect(logs).to contains_log(
|
29
|
+
:warn,
|
30
|
+
"Configuring AppSignal with `Appsignal.config=` is deprecated."
|
31
|
+
)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".configure" do
|
36
|
+
context "when active" do
|
37
|
+
it "doesn't update the config" do
|
38
|
+
start_agent
|
39
|
+
Appsignal::Testing.store[:config_called] = false
|
40
|
+
expect do
|
41
|
+
Appsignal.configure do |_config|
|
42
|
+
Appsignal::Testing.store[:config_called] = true
|
43
|
+
end
|
44
|
+
end.to_not(change { [Appsignal.config, Appsignal.active?] })
|
45
|
+
expect(Appsignal::Testing.store[:config_called]).to be(false)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "logs a warning" do
|
49
|
+
start_agent
|
50
|
+
logs =
|
51
|
+
capture_logs do
|
52
|
+
Appsignal.configure do |_config|
|
53
|
+
# Do something
|
54
|
+
end
|
55
|
+
end
|
56
|
+
expect(logs).to contains_log(
|
57
|
+
:warn,
|
58
|
+
"AppSignal is already started. Ignoring `Appsignal.configure` call."
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with config but not started" do
|
64
|
+
it "reuses the already loaded config if the env is the same" do
|
65
|
+
Appsignal._config = Appsignal::Config.new(
|
66
|
+
project_fixture_path,
|
67
|
+
:my_env,
|
68
|
+
:ignore_actions => ["My action"]
|
69
|
+
)
|
70
|
+
|
71
|
+
Appsignal.configure(:my_env) do |config|
|
72
|
+
expect(config.ignore_actions).to eq(["My action"])
|
73
|
+
config.active = true
|
74
|
+
config.name = "My app"
|
75
|
+
config.push_api_key = "key"
|
76
|
+
end
|
77
|
+
expect(Appsignal.config.valid?).to be(true)
|
78
|
+
expect(Appsignal.config.env).to eq("my_env")
|
79
|
+
expect(Appsignal.config[:active]).to be(true)
|
80
|
+
expect(Appsignal.config[:name]).to eq("My app")
|
81
|
+
expect(Appsignal.config[:push_api_key]).to eq("key")
|
82
|
+
end
|
83
|
+
|
84
|
+
it "loads a new config if the env is not the same" do
|
85
|
+
Appsignal._config = Appsignal::Config.new(
|
86
|
+
project_fixture_path,
|
87
|
+
:my_env,
|
88
|
+
:name => "Some name",
|
89
|
+
:push_api_key => "Some key",
|
90
|
+
:ignore_actions => ["My action"]
|
91
|
+
)
|
92
|
+
|
93
|
+
Appsignal.configure(:my_env2) do |config|
|
94
|
+
expect(config.ignore_actions).to be_empty
|
95
|
+
config.active = true
|
96
|
+
config.name = "My app"
|
97
|
+
config.push_api_key = "key"
|
98
|
+
end
|
99
|
+
expect(Appsignal.config.valid?).to be(true)
|
100
|
+
expect(Appsignal.config.env).to eq("my_env2")
|
101
|
+
expect(Appsignal.config[:active]).to be(true)
|
102
|
+
expect(Appsignal.config[:name]).to eq("My app")
|
103
|
+
expect(Appsignal.config[:push_api_key]).to eq("key")
|
104
|
+
end
|
105
|
+
|
106
|
+
it "calls configure if not started yet" do
|
107
|
+
Appsignal.configure(:my_env) do |config|
|
108
|
+
config.active = false
|
109
|
+
config.name = "Some name"
|
110
|
+
end
|
111
|
+
Appsignal.start
|
112
|
+
expect(Appsignal.started?).to be_falsy
|
113
|
+
|
114
|
+
Appsignal.configure(:my_env) do |config|
|
115
|
+
expect(config.ignore_actions).to be_empty
|
116
|
+
config.active = true
|
117
|
+
config.name = "My app"
|
118
|
+
config.push_api_key = "key"
|
119
|
+
end
|
120
|
+
expect(Appsignal.config.valid?).to be(true)
|
121
|
+
expect(Appsignal.config.env).to eq("my_env")
|
122
|
+
expect(Appsignal.config[:active]).to be(true)
|
123
|
+
expect(Appsignal.config[:name]).to eq("My app")
|
124
|
+
expect(Appsignal.config[:push_api_key]).to eq("key")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context "when not active" do
|
129
|
+
it "starts with the configured config" do
|
130
|
+
Appsignal.configure(:test) do |config|
|
131
|
+
config.push_api_key = "key"
|
132
|
+
end
|
133
|
+
|
134
|
+
Appsignal.start
|
135
|
+
expect(Appsignal.config[:push_api_key]).to eq("key")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "uses the given env" do
|
139
|
+
ENV["APPSIGNAL_APP_ENV"] = "env_env"
|
140
|
+
Appsignal.configure(:env_arg)
|
141
|
+
|
142
|
+
Appsignal.start
|
143
|
+
expect(Appsignal.config.env).to eq("env_arg")
|
144
|
+
end
|
145
|
+
|
146
|
+
it "loads the config without a block being given" do
|
147
|
+
Dir.chdir project_fixture_path do
|
148
|
+
Appsignal.configure(:test)
|
149
|
+
end
|
150
|
+
|
151
|
+
expect(Appsignal.config.env).to eq("test")
|
152
|
+
expect(Appsignal.config[:push_api_key]).to eq("abc")
|
153
|
+
end
|
154
|
+
|
155
|
+
it "allows customization of config in the block" do
|
156
|
+
Appsignal.configure(:test) do |config|
|
157
|
+
config.push_api_key = "key"
|
158
|
+
end
|
159
|
+
|
160
|
+
expect(Appsignal.config.valid?).to be(true)
|
161
|
+
expect(Appsignal.config.env).to eq("test")
|
162
|
+
expect(Appsignal.config[:push_api_key]).to eq("key")
|
163
|
+
end
|
164
|
+
|
165
|
+
it "loads the default config" do
|
166
|
+
Appsignal.configure do |config|
|
167
|
+
Appsignal::Config::DEFAULT_CONFIG.each do |option, value|
|
168
|
+
expect(config.send(option)).to eq(value)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
it "loads the config from the YAML file" do
|
174
|
+
Dir.chdir project_fixture_path do
|
175
|
+
Appsignal.configure(:test) do |config|
|
176
|
+
expect(config.name).to eq("TestApp")
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
it "recognizes valid config" do
|
182
|
+
Appsignal.configure(:my_env) do |config|
|
183
|
+
config.push_api_key = "key"
|
184
|
+
end
|
185
|
+
|
186
|
+
expect(Appsignal.config.valid?).to be(true)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "recognizes invalid config" do
|
190
|
+
Appsignal.configure(:my_env) do |config|
|
191
|
+
config.push_api_key = ""
|
192
|
+
end
|
193
|
+
|
194
|
+
expect(Appsignal.config.valid?).to be(false)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "sets the environment when given as an argument" do
|
198
|
+
Appsignal.configure(:my_env)
|
199
|
+
|
200
|
+
expect(Appsignal.config.env).to eq("my_env")
|
201
|
+
end
|
202
|
+
|
203
|
+
it "reads the environment from the environment" do
|
204
|
+
ENV["APPSIGNAL_APP_ENV"] = "env_env"
|
205
|
+
Appsignal.configure do |config|
|
206
|
+
expect(config.env).to eq("env_env")
|
207
|
+
end
|
208
|
+
|
209
|
+
expect(Appsignal.config.env).to eq("env_env")
|
210
|
+
end
|
211
|
+
|
212
|
+
it "allows modification of previously unset config options" do
|
213
|
+
expect do
|
214
|
+
Appsignal.configure do |config|
|
215
|
+
config.ignore_actions << "My action"
|
216
|
+
config.request_headers << "My allowed header"
|
217
|
+
end
|
218
|
+
end.to_not(change { Appsignal::Config::DEFAULT_CONFIG })
|
219
|
+
|
220
|
+
expect(Appsignal.config[:ignore_actions]).to eq(["My action"])
|
221
|
+
expect(Appsignal.config[:request_headers])
|
222
|
+
.to eq(Appsignal::Config::DEFAULT_CONFIG[:request_headers] + ["My allowed header"])
|
223
|
+
end
|
224
|
+
end
|
21
225
|
end
|
22
226
|
|
23
227
|
describe ".start" do
|
@@ -50,7 +254,7 @@ describe Appsignal do
|
|
50
254
|
end
|
51
255
|
|
52
256
|
context "when config is loaded" do
|
53
|
-
before { Appsignal.
|
257
|
+
before { Appsignal._config = project_fixture_config }
|
54
258
|
|
55
259
|
it "should initialize logging" do
|
56
260
|
Appsignal.start
|
@@ -113,6 +317,27 @@ describe Appsignal do
|
|
113
317
|
end
|
114
318
|
end
|
115
319
|
|
320
|
+
describe "loaders" do
|
321
|
+
it "starts loaded loaders" do
|
322
|
+
Appsignal::Testing.store[:loader_loaded] = 0
|
323
|
+
Appsignal::Testing.store[:loader_started] = 0
|
324
|
+
define_loader(:start_loader) do
|
325
|
+
def on_load
|
326
|
+
Appsignal::Testing.store[:loader_loaded] += 1
|
327
|
+
end
|
328
|
+
|
329
|
+
def on_start
|
330
|
+
Appsignal::Testing.store[:loader_started] += 1
|
331
|
+
end
|
332
|
+
end
|
333
|
+
Appsignal::Loaders.load(:start_loader)
|
334
|
+
Appsignal::Loaders.start
|
335
|
+
|
336
|
+
expect(Appsignal::Testing.store[:loader_loaded]).to eq(1)
|
337
|
+
expect(Appsignal::Testing.store[:loader_started]).to eq(1)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
116
341
|
describe "environment metadata" do
|
117
342
|
before { capture_environment_metadata_report_calls }
|
118
343
|
|
@@ -128,7 +353,7 @@ describe Appsignal do
|
|
128
353
|
end
|
129
354
|
|
130
355
|
context "with debug logging" do
|
131
|
-
before { Appsignal.
|
356
|
+
before { Appsignal._config = project_fixture_config("test") }
|
132
357
|
|
133
358
|
it "should change the log level" do
|
134
359
|
Appsignal.start
|
@@ -137,6 +362,22 @@ describe Appsignal do
|
|
137
362
|
end
|
138
363
|
end
|
139
364
|
|
365
|
+
describe ".load" do
|
366
|
+
before do
|
367
|
+
TestLoader = define_loader(:appsignal_loader)
|
368
|
+
end
|
369
|
+
after do
|
370
|
+
Object.send(:remove_const, :TestLoader)
|
371
|
+
end
|
372
|
+
|
373
|
+
it "loads a loader" do
|
374
|
+
expect(Appsignal::Loaders.instances).to be_empty
|
375
|
+
Appsignal.load(:appsignal_loader)
|
376
|
+
expect(Appsignal::Loaders.instances)
|
377
|
+
.to include(:appsignal_loader => instance_of(TestLoader))
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
140
381
|
describe ".forked" do
|
141
382
|
context "when not active" do
|
142
383
|
it "does nothing" do
|
@@ -148,7 +389,7 @@ describe Appsignal do
|
|
148
389
|
|
149
390
|
context "when active" do
|
150
391
|
before do
|
151
|
-
Appsignal.
|
392
|
+
Appsignal._config = project_fixture_config
|
152
393
|
end
|
153
394
|
|
154
395
|
it "starts the logger and extension" do
|
@@ -162,7 +403,7 @@ describe Appsignal do
|
|
162
403
|
|
163
404
|
describe ".stop" do
|
164
405
|
it "calls stop on the extension" do
|
165
|
-
expect(Appsignal.internal_logger).to receive(:debug).with("Stopping
|
406
|
+
expect(Appsignal.internal_logger).to receive(:debug).with("Stopping AppSignal")
|
166
407
|
expect(Appsignal::Extension).to receive(:stop)
|
167
408
|
Appsignal.stop
|
168
409
|
expect(Appsignal.active?).to be_falsy
|
@@ -177,7 +418,7 @@ describe Appsignal do
|
|
177
418
|
|
178
419
|
context "with context specified" do
|
179
420
|
it "should log the context" do
|
180
|
-
expect(Appsignal.internal_logger).to receive(:debug).with("Stopping
|
421
|
+
expect(Appsignal.internal_logger).to receive(:debug).with("Stopping AppSignal (something)")
|
181
422
|
expect(Appsignal::Extension).to receive(:stop)
|
182
423
|
Appsignal.stop("something")
|
183
424
|
expect(Appsignal.active?).to be_falsy
|
@@ -185,20 +426,34 @@ describe Appsignal do
|
|
185
426
|
end
|
186
427
|
end
|
187
428
|
|
188
|
-
describe ".
|
189
|
-
subject { Appsignal.
|
429
|
+
describe ".started?" do
|
430
|
+
subject { Appsignal.started? }
|
190
431
|
|
191
|
-
context "
|
432
|
+
context "when started with active config" do
|
433
|
+
before { start_agent }
|
434
|
+
|
435
|
+
it { is_expected.to be_truthy }
|
436
|
+
end
|
437
|
+
|
438
|
+
context "when started with inactive config" do
|
192
439
|
before do
|
193
|
-
Appsignal.
|
440
|
+
Appsignal._config = project_fixture_config("nonsense")
|
194
441
|
end
|
195
442
|
|
196
443
|
it { is_expected.to be_falsy }
|
197
444
|
end
|
445
|
+
end
|
446
|
+
|
447
|
+
describe ".active?" do
|
448
|
+
subject { Appsignal.active? }
|
449
|
+
|
450
|
+
context "without config" do
|
451
|
+
it { is_expected.to be_falsy }
|
452
|
+
end
|
198
453
|
|
199
454
|
context "with inactive config" do
|
200
455
|
before do
|
201
|
-
Appsignal.
|
456
|
+
Appsignal._config = project_fixture_config("nonsense")
|
202
457
|
end
|
203
458
|
|
204
459
|
it { is_expected.to be_falsy }
|
@@ -206,7 +461,7 @@ describe Appsignal do
|
|
206
461
|
|
207
462
|
context "with active config" do
|
208
463
|
before do
|
209
|
-
Appsignal.
|
464
|
+
Appsignal._config = project_fixture_config
|
210
465
|
end
|
211
466
|
|
212
467
|
it { is_expected.to be_truthy }
|
@@ -232,7 +487,7 @@ describe Appsignal do
|
|
232
487
|
end
|
233
488
|
|
234
489
|
context "not active" do
|
235
|
-
before { Appsignal.
|
490
|
+
before { Appsignal._config = project_fixture_config("not_active") }
|
236
491
|
|
237
492
|
describe ".monitor_transaction" do
|
238
493
|
it "does not create a transaction" do
|
@@ -358,7 +613,178 @@ describe Appsignal do
|
|
358
613
|
before { start_agent }
|
359
614
|
around { |example| keep_transactions { example.run } }
|
360
615
|
|
616
|
+
describe ".monitor" do
|
617
|
+
it "creates a transaction" do
|
618
|
+
expect do
|
619
|
+
Appsignal.monitor(:action => "MyAction")
|
620
|
+
end.to(change { created_transactions.count }.by(1))
|
621
|
+
|
622
|
+
transaction = last_transaction
|
623
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
624
|
+
expect(transaction).to have_action("MyAction")
|
625
|
+
expect(transaction).to_not have_error
|
626
|
+
expect(transaction).to_not include_events
|
627
|
+
expect(transaction).to_not have_queue_start
|
628
|
+
expect(transaction).to be_completed
|
629
|
+
end
|
630
|
+
|
631
|
+
it "returns the block's return value" do
|
632
|
+
expect(Appsignal.monitor(:action => nil) { :return_value }).to eq(:return_value)
|
633
|
+
end
|
634
|
+
|
635
|
+
it "sets a custom namespace via the namespace argument" do
|
636
|
+
Appsignal.monitor(:namespace => "custom", :action => nil)
|
637
|
+
|
638
|
+
expect(last_transaction).to have_namespace("custom")
|
639
|
+
end
|
640
|
+
|
641
|
+
it "doesn't overwrite custom namespace set in the block" do
|
642
|
+
Appsignal.monitor(:namespace => "custom", :action => nil) do
|
643
|
+
Appsignal.set_namespace("more custom")
|
644
|
+
end
|
645
|
+
|
646
|
+
expect(last_transaction).to have_namespace("more custom")
|
647
|
+
end
|
648
|
+
|
649
|
+
it "sets the action via the action argument using a string" do
|
650
|
+
Appsignal.monitor(:action => "custom")
|
651
|
+
|
652
|
+
expect(last_transaction).to have_action("custom")
|
653
|
+
end
|
654
|
+
|
655
|
+
it "sets the action via the action argument using a symbol" do
|
656
|
+
Appsignal.monitor(:action => :custom)
|
657
|
+
|
658
|
+
expect(last_transaction).to have_action("custom")
|
659
|
+
end
|
660
|
+
|
661
|
+
it "doesn't overwrite custom action set in the block" do
|
662
|
+
Appsignal.monitor(:action => "custom") do
|
663
|
+
Appsignal.set_action("more custom")
|
664
|
+
end
|
665
|
+
|
666
|
+
expect(last_transaction).to have_action("more custom")
|
667
|
+
end
|
668
|
+
|
669
|
+
it "doesn't set the action when value is nil" do
|
670
|
+
Appsignal.monitor(:action => nil)
|
671
|
+
|
672
|
+
expect(last_transaction).to_not have_action
|
673
|
+
end
|
674
|
+
|
675
|
+
it "doesn't set the action when value is :set_later" do
|
676
|
+
Appsignal.monitor(:action => :set_later)
|
677
|
+
|
678
|
+
expect(last_transaction).to_not have_action
|
679
|
+
end
|
680
|
+
|
681
|
+
it "reports exceptions that occur in the block" do
|
682
|
+
expect do
|
683
|
+
Appsignal.monitor :action => nil do
|
684
|
+
raise ExampleException, "error message"
|
685
|
+
end
|
686
|
+
end.to raise_error(ExampleException, "error message")
|
687
|
+
|
688
|
+
expect(last_transaction).to have_error("ExampleException", "error message")
|
689
|
+
end
|
690
|
+
|
691
|
+
context "with already active transction" do
|
692
|
+
let(:err_stream) { std_stream }
|
693
|
+
let(:stderr) { err_stream.read }
|
694
|
+
let(:transaction) { http_request_transaction }
|
695
|
+
before do
|
696
|
+
set_current_transaction(transaction)
|
697
|
+
transaction.set_action("My action")
|
698
|
+
end
|
699
|
+
|
700
|
+
it "doesn't create a new transaction" do
|
701
|
+
logs = nil
|
702
|
+
expect do
|
703
|
+
logs =
|
704
|
+
capture_logs do
|
705
|
+
capture_std_streams(std_stream, err_stream) do
|
706
|
+
Appsignal.monitor(:action => nil)
|
707
|
+
end
|
708
|
+
end
|
709
|
+
end.to_not(change { created_transactions.count })
|
710
|
+
|
711
|
+
warning = "An active transaction around this 'Appsignal.monitor' call."
|
712
|
+
expect(logs).to contains_log(:warn, warning)
|
713
|
+
expect(stderr).to include("appsignal WARNING: #{warning}")
|
714
|
+
end
|
715
|
+
|
716
|
+
it "does not overwrite the parent transaction's namespace" do
|
717
|
+
silence { Appsignal.monitor(:namespace => "custom", :action => nil) }
|
718
|
+
|
719
|
+
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
720
|
+
end
|
721
|
+
|
722
|
+
it "does not overwrite the parent transaction's action" do
|
723
|
+
silence { Appsignal.monitor(:action => "custom") }
|
724
|
+
|
725
|
+
expect(transaction).to have_action("My action")
|
726
|
+
end
|
727
|
+
|
728
|
+
it "doesn't complete the parent transaction" do
|
729
|
+
silence { Appsignal.monitor(:action => nil) }
|
730
|
+
|
731
|
+
expect(transaction).to_not be_completed
|
732
|
+
end
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
describe ".monitor_and_stop" do
|
737
|
+
it "calls Appsignal.stop after the block" do
|
738
|
+
allow(Appsignal).to receive(:stop)
|
739
|
+
Appsignal.monitor_and_stop(:namespace => "custom", :action => "My Action")
|
740
|
+
|
741
|
+
transaction = last_transaction
|
742
|
+
expect(transaction).to have_namespace("custom")
|
743
|
+
expect(transaction).to have_action("My Action")
|
744
|
+
expect(transaction).to be_completed
|
745
|
+
|
746
|
+
expect(Appsignal).to have_received(:stop).with("monitor_and_stop")
|
747
|
+
end
|
748
|
+
end
|
749
|
+
|
361
750
|
describe ".monitor_transaction" do
|
751
|
+
it "prints a deprecation warning" do
|
752
|
+
err_stream = std_stream
|
753
|
+
capture_std_streams(std_stream, err_stream) do
|
754
|
+
Appsignal.monitor_transaction(
|
755
|
+
"perform_job.something",
|
756
|
+
:class => "BackgroundJob",
|
757
|
+
:method => "perform"
|
758
|
+
) do
|
759
|
+
:return_value
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
expect(err_stream.read).to include(
|
764
|
+
"appsignal WARNING: The `Appsignal.monitor_transaction` helper is deprecated."
|
765
|
+
)
|
766
|
+
end
|
767
|
+
|
768
|
+
it "logs a deprecation warning" do
|
769
|
+
logs =
|
770
|
+
capture_logs do
|
771
|
+
silence do
|
772
|
+
Appsignal.monitor_transaction(
|
773
|
+
"perform_job.something",
|
774
|
+
:class => "BackgroundJob",
|
775
|
+
:method => "perform"
|
776
|
+
) do
|
777
|
+
:return_value
|
778
|
+
end
|
779
|
+
end
|
780
|
+
end
|
781
|
+
|
782
|
+
expect(logs).to contains_log(
|
783
|
+
:warn,
|
784
|
+
"The `Appsignal.monitor_transaction` helper is deprecated."
|
785
|
+
)
|
786
|
+
end
|
787
|
+
|
362
788
|
context "with a successful call" do
|
363
789
|
it "instruments and completes for a background job" do
|
364
790
|
return_value = nil
|
@@ -368,7 +794,8 @@ describe Appsignal do
|
|
368
794
|
"perform_job.something",
|
369
795
|
{
|
370
796
|
:class => "BackgroundJob",
|
371
|
-
:method => "perform"
|
797
|
+
:method => "perform",
|
798
|
+
:queue_start => fixed_time.to_i
|
372
799
|
}
|
373
800
|
) do
|
374
801
|
:return_value
|
@@ -380,6 +807,7 @@ describe Appsignal do
|
|
380
807
|
expect(transaction).to have_namespace(Appsignal::Transaction::BACKGROUND_JOB)
|
381
808
|
expect(transaction).to have_action("BackgroundJob#perform")
|
382
809
|
expect(transaction).to include_event("name" => "perform_job.something")
|
810
|
+
expect(transaction).to have_queue_start(1_389_783_600_000)
|
383
811
|
expect(transaction).to be_completed
|
384
812
|
end
|
385
813
|
|
@@ -391,7 +819,8 @@ describe Appsignal do
|
|
391
819
|
"process_action.something",
|
392
820
|
{
|
393
821
|
:controller => "BlogPostsController",
|
394
|
-
:action => "show"
|
822
|
+
:action => "show",
|
823
|
+
"HTTP_X_REQUEST_START" => "t=#{fixed_time.to_i * 1000}"
|
395
824
|
}
|
396
825
|
) do
|
397
826
|
:return_value
|
@@ -403,6 +832,7 @@ describe Appsignal do
|
|
403
832
|
expect(transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
|
404
833
|
expect(transaction).to have_action("BlogPostsController#show")
|
405
834
|
expect(transaction).to include_event("name" => "process_action.something")
|
835
|
+
expect(transaction).to have_queue_start(1_389_783_600_000)
|
406
836
|
expect(transaction).to be_completed
|
407
837
|
end
|
408
838
|
end
|
@@ -444,6 +874,43 @@ describe Appsignal do
|
|
444
874
|
end
|
445
875
|
|
446
876
|
describe ".monitor_single_transaction" do
|
877
|
+
it "prints a deprecation warning" do
|
878
|
+
err_stream = std_stream
|
879
|
+
capture_std_streams(std_stream, err_stream) do
|
880
|
+
Appsignal.monitor_single_transaction(
|
881
|
+
"perform_job.something",
|
882
|
+
:class => "BackgroundJob",
|
883
|
+
:method => "perform"
|
884
|
+
) do
|
885
|
+
:return_value
|
886
|
+
end
|
887
|
+
end
|
888
|
+
|
889
|
+
expect(err_stream.read).to include(
|
890
|
+
"appsignal WARNING: The `Appsignal.monitor_single_transaction` helper is deprecated."
|
891
|
+
)
|
892
|
+
end
|
893
|
+
|
894
|
+
it "logs a deprecation warning" do
|
895
|
+
logs =
|
896
|
+
capture_logs do
|
897
|
+
silence do
|
898
|
+
Appsignal.monitor_single_transaction(
|
899
|
+
"perform_job.something",
|
900
|
+
:class => "BackgroundJob",
|
901
|
+
:method => "perform"
|
902
|
+
) do
|
903
|
+
:return_value
|
904
|
+
end
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
expect(logs).to contains_log(
|
909
|
+
:warn,
|
910
|
+
"The `Appsignal.monitor_single_transaction` helper is deprecated."
|
911
|
+
)
|
912
|
+
end
|
913
|
+
|
447
914
|
context "with a successful call" do
|
448
915
|
it "calls monitor_transaction and Appsignal.stop" do
|
449
916
|
expect(Appsignal).to receive(:stop)
|
@@ -521,9 +988,7 @@ describe Appsignal do
|
|
521
988
|
end
|
522
989
|
|
523
990
|
describe ".set_params" do
|
524
|
-
before
|
525
|
-
start_agent
|
526
|
-
end
|
991
|
+
before { start_agent }
|
527
992
|
|
528
993
|
context "with transaction" do
|
529
994
|
let(:transaction) { http_request_transaction }
|
@@ -561,6 +1026,84 @@ describe Appsignal do
|
|
561
1026
|
end
|
562
1027
|
end
|
563
1028
|
|
1029
|
+
describe ".set_session_data" do
|
1030
|
+
before { start_agent }
|
1031
|
+
|
1032
|
+
context "with transaction" do
|
1033
|
+
let(:transaction) { http_request_transaction }
|
1034
|
+
before { set_current_transaction(transaction) }
|
1035
|
+
|
1036
|
+
it "sets session data on the transaction" do
|
1037
|
+
Appsignal.set_session_data("data" => "value1")
|
1038
|
+
|
1039
|
+
transaction._sample
|
1040
|
+
expect(transaction).to include_session_data("data" => "value1")
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
it "overwrites the session data if called multiple times" do
|
1044
|
+
Appsignal.set_session_data("data" => "value1")
|
1045
|
+
Appsignal.set_session_data("data" => "value2")
|
1046
|
+
|
1047
|
+
transaction._sample
|
1048
|
+
expect(transaction).to include_session_data("data" => "value2")
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
it "sets session data with a block on the transaction" do
|
1052
|
+
Appsignal.set_session_data { { "data" => "value1" } }
|
1053
|
+
|
1054
|
+
transaction._sample
|
1055
|
+
expect(transaction).to include_session_data("data" => "value1")
|
1056
|
+
end
|
1057
|
+
end
|
1058
|
+
|
1059
|
+
context "without transaction" do
|
1060
|
+
it "does not set session data on the transaction" do
|
1061
|
+
Appsignal.set_session_data("a" => "b")
|
1062
|
+
|
1063
|
+
expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_session_data)
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
describe ".set_headers" do
|
1069
|
+
before { start_agent }
|
1070
|
+
|
1071
|
+
context "with transaction" do
|
1072
|
+
let(:transaction) { http_request_transaction }
|
1073
|
+
before { set_current_transaction(transaction) }
|
1074
|
+
|
1075
|
+
it "sets request headers on the transaction" do
|
1076
|
+
Appsignal.set_headers("PATH_INFO" => "/some-path")
|
1077
|
+
|
1078
|
+
transaction._sample
|
1079
|
+
expect(transaction).to include_environment("PATH_INFO" => "/some-path")
|
1080
|
+
end
|
1081
|
+
|
1082
|
+
it "overwrites the request headers if called multiple times" do
|
1083
|
+
Appsignal.set_headers("PATH_INFO" => "/some-path1")
|
1084
|
+
Appsignal.set_headers("PATH_INFO" => "/some-path2")
|
1085
|
+
|
1086
|
+
transaction._sample
|
1087
|
+
expect(transaction).to include_environment("PATH_INFO" => "/some-path2")
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
it "sets request headers with a block on the transaction" do
|
1091
|
+
Appsignal.set_headers { { "PATH_INFO" => "/some-path" } }
|
1092
|
+
|
1093
|
+
transaction._sample
|
1094
|
+
expect(transaction).to include_environment("PATH_INFO" => "/some-path")
|
1095
|
+
end
|
1096
|
+
end
|
1097
|
+
|
1098
|
+
context "without transaction" do
|
1099
|
+
it "does not set request headers on the transaction" do
|
1100
|
+
Appsignal.set_headers("PATH_INFO" => "/some-path")
|
1101
|
+
|
1102
|
+
expect_any_instance_of(Appsignal::Transaction).to_not receive(:set_headers)
|
1103
|
+
end
|
1104
|
+
end
|
1105
|
+
end
|
1106
|
+
|
564
1107
|
describe ".set_custom_data" do
|
565
1108
|
before { start_agent }
|
566
1109
|
|
@@ -595,13 +1138,11 @@ describe Appsignal do
|
|
595
1138
|
end
|
596
1139
|
|
597
1140
|
describe ".add_breadcrumb" do
|
598
|
-
|
599
|
-
start_agent
|
600
|
-
with_current_transaction(transaction) { example.run }
|
601
|
-
end
|
1141
|
+
before { start_agent }
|
602
1142
|
|
603
1143
|
context "with transaction" do
|
604
1144
|
let(:transaction) { http_request_transaction }
|
1145
|
+
before { set_current_transaction(transaction) }
|
605
1146
|
|
606
1147
|
it "adds the breadcrumb to the transaction" do
|
607
1148
|
Appsignal.add_breadcrumb(
|
@@ -1269,7 +1810,7 @@ describe Appsignal do
|
|
1269
1810
|
end
|
1270
1811
|
end
|
1271
1812
|
|
1272
|
-
describe ".
|
1813
|
+
describe ".ignore_instrumentation_events" do
|
1273
1814
|
around { |example| keep_transactions { example.run } }
|
1274
1815
|
let(:transaction) { http_request_transaction }
|
1275
1816
|
|
@@ -1281,20 +1822,44 @@ describe Appsignal do
|
|
1281
1822
|
expect(transaction).to receive(:resume!).and_call_original
|
1282
1823
|
|
1283
1824
|
Appsignal.instrument("register.this.event") { :do_nothing }
|
1284
|
-
Appsignal.
|
1825
|
+
Appsignal.ignore_instrumentation_events do
|
1285
1826
|
Appsignal.instrument("dont.register.this.event") { :do_nothing }
|
1286
1827
|
end
|
1287
1828
|
|
1288
1829
|
expect(transaction).to include_event("name" => "register.this.event")
|
1289
1830
|
expect(transaction).to_not include_event("name" => "dont.register.this.event")
|
1290
1831
|
end
|
1832
|
+
|
1833
|
+
it "has a without_instrumentation alias that prints a deprecation warning" do
|
1834
|
+
Appsignal.instrument("register.this.event") { :do_nothing }
|
1835
|
+
err_stream = std_stream
|
1836
|
+
logs =
|
1837
|
+
capture_logs do
|
1838
|
+
capture_std_streams(std_stream, err_stream) do
|
1839
|
+
Appsignal.without_instrumentation do
|
1840
|
+
Appsignal.instrument("dont.register.this.event") { :do_nothing }
|
1841
|
+
end
|
1842
|
+
end
|
1843
|
+
end
|
1844
|
+
|
1845
|
+
expect(transaction).to include_event("name" => "register.this.event")
|
1846
|
+
expect(transaction).to_not include_event("name" => "dont.register.this.event")
|
1847
|
+
|
1848
|
+
expect(logs).to contains_log(
|
1849
|
+
:warn,
|
1850
|
+
"The `Appsignal.without_instrumentation` helper is deprecated."
|
1851
|
+
)
|
1852
|
+
expect(err_stream.read).to include(
|
1853
|
+
"appsignal WARNING: The `Appsignal.without_instrumentation` helper is deprecated."
|
1854
|
+
)
|
1855
|
+
end
|
1291
1856
|
end
|
1292
1857
|
|
1293
1858
|
context "without current transaction" do
|
1294
1859
|
let(:transaction) { nil }
|
1295
1860
|
|
1296
1861
|
it "does not crash" do
|
1297
|
-
Appsignal.
|
1862
|
+
Appsignal.ignore_instrumentation_events { :do_nothing }
|
1298
1863
|
end
|
1299
1864
|
end
|
1300
1865
|
end
|
@@ -1312,8 +1877,9 @@ describe Appsignal do
|
|
1312
1877
|
Appsignal.start_logger
|
1313
1878
|
end
|
1314
1879
|
end
|
1315
|
-
expect(stderr)
|
1316
|
-
|
1880
|
+
expect(stderr)
|
1881
|
+
.to include("appsignal WARNING: Calling 'Appsignal.start_logger' is deprecated.")
|
1882
|
+
expect(log).to contains_log(:warn, "Calling 'Appsignal.start_logger' is deprecated.")
|
1317
1883
|
end
|
1318
1884
|
end
|
1319
1885
|
|
@@ -1335,7 +1901,7 @@ describe Appsignal do
|
|
1335
1901
|
after { FileUtils.rm_rf(log_path) }
|
1336
1902
|
|
1337
1903
|
def initialize_config
|
1338
|
-
Appsignal.
|
1904
|
+
Appsignal._config = project_fixture_config(
|
1339
1905
|
"production",
|
1340
1906
|
:log_path => log_path,
|
1341
1907
|
:log_level => log_level
|
@@ -1482,7 +2048,6 @@ describe Appsignal do
|
|
1482
2048
|
|
1483
2049
|
context "when there is no config" do
|
1484
2050
|
before do
|
1485
|
-
Appsignal.config = nil
|
1486
2051
|
capture_stdout(out_stream) do
|
1487
2052
|
Appsignal._start_logger
|
1488
2053
|
end
|