appsignal 2.9.2.alpha.1 → 2.9.18.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- data/.github/ISSUE_TEMPLATE/chore.md +14 -0
- data/.gitignore +1 -2
- data/.rubocop.yml +3 -0
- data/.travis.yml +25 -27
- data/CHANGELOG.md +632 -535
- data/README.md +8 -3
- data/Rakefile +118 -122
- data/SUPPORT.md +16 -0
- data/appsignal.gemspec +14 -4
- data/build_matrix.yml +16 -8
- data/ext/Rakefile +2 -3
- data/ext/agent.yml +40 -37
- data/ext/base.rb +37 -14
- data/ext/extconf.rb +3 -4
- data/gemfiles/capistrano2.gemfile +5 -0
- data/gemfiles/capistrano3.gemfile +5 -0
- data/gemfiles/grape.gemfile +5 -0
- data/gemfiles/no_dependencies.gemfile +5 -0
- data/gemfiles/padrino.gemfile +5 -0
- data/gemfiles/que.gemfile +5 -0
- data/gemfiles/que_beta.gemfile +10 -0
- data/gemfiles/rails-3.2.gemfile +5 -0
- data/gemfiles/rails-4.0.gemfile +5 -0
- data/gemfiles/rails-4.1.gemfile +5 -0
- data/gemfiles/rails-4.2.gemfile +5 -0
- data/gemfiles/rails-6.0.gemfile +1 -1
- data/gemfiles/resque.gemfile +5 -0
- data/lib/appsignal.rb +1 -4
- data/lib/appsignal/cli/demo.rb +5 -2
- data/lib/appsignal/cli/diagnose/utils.rb +2 -0
- data/lib/appsignal/cli/install.rb +34 -10
- data/lib/appsignal/cli/notify_of_deploy.rb +10 -0
- data/lib/appsignal/event_formatter/action_view/render_formatter.rb +10 -8
- data/lib/appsignal/helpers/instrumentation.rb +18 -9
- data/lib/appsignal/helpers/metrics.rb +0 -1
- data/lib/appsignal/hooks.rb +3 -1
- data/lib/appsignal/hooks/active_support_notifications.rb +2 -5
- data/lib/appsignal/hooks/puma.rb +15 -13
- data/lib/appsignal/hooks/sequel.rb +1 -1
- data/lib/appsignal/hooks/sidekiq.rb +33 -8
- data/lib/appsignal/integrations/que.rb +9 -8
- data/lib/appsignal/minutely.rb +38 -19
- data/lib/appsignal/transaction.rb +5 -0
- data/lib/appsignal/utils/rails_helper.rb +4 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/puma/plugin/appsignal.rb +26 -0
- data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +40 -0
- data/spec/lib/appsignal/cli/install_spec.rb +51 -7
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +10 -0
- data/spec/lib/appsignal/config_spec.rb +10 -8
- data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +38 -28
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +104 -25
- data/spec/lib/appsignal/hooks/puma_spec.rb +69 -39
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +65 -3
- data/spec/lib/appsignal/hooks_spec.rb +4 -0
- data/spec/lib/appsignal/minutely_spec.rb +150 -88
- data/spec/lib/appsignal/transaction_spec.rb +27 -4
- data/spec/lib/appsignal_spec.rb +62 -11
- data/spec/lib/puma/appsignal_spec.rb +91 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/application.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/appsignal.yml +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/development.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/production.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/config/environments/test.rb +0 -0
- data/spec/support/{project_fixture → fixtures/projects/valid}/log/.gitkeep +0 -0
- data/spec/support/helpers/config_helpers.rb +1 -1
- data/spec/support/helpers/wait_for_helper.rb +28 -0
- data/spec/support/mocks/mock_probe.rb +11 -0
- metadata +37 -30
- data/spec/support/fixtures/containers/cgroups/docker +0 -14
- data/spec/support/fixtures/containers/cgroups/docker_systemd +0 -8
- data/spec/support/fixtures/containers/cgroups/lxc +0 -10
- data/spec/support/fixtures/containers/cgroups/no_permission +0 -0
- data/spec/support/fixtures/containers/cgroups/none +0 -1
@@ -1,6 +1,46 @@
|
|
1
1
|
require "appsignal/cli/diagnose/utils"
|
2
2
|
|
3
3
|
describe Appsignal::CLI::Diagnose::Utils do
|
4
|
+
describe ".username_for_uid" do
|
5
|
+
subject { described_class.username_for_uid(uid) }
|
6
|
+
|
7
|
+
context "when user with id exists" do
|
8
|
+
let(:uid) { 0 }
|
9
|
+
|
10
|
+
it "returns username" do
|
11
|
+
is_expected.to be_kind_of(String)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when user with id does not exist" do
|
16
|
+
let(:uid) { -1 }
|
17
|
+
|
18
|
+
it "returns nil" do
|
19
|
+
is_expected.to be_nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".group_for_gid" do
|
25
|
+
subject { described_class.group_for_gid(uid) }
|
26
|
+
|
27
|
+
context "when group with id exists" do
|
28
|
+
let(:uid) { 0 }
|
29
|
+
|
30
|
+
it "returns group name" do
|
31
|
+
is_expected.to be_kind_of(String)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when group with id does not exist" do
|
36
|
+
let(:uid) { -3 }
|
37
|
+
|
38
|
+
it "returns nil" do
|
39
|
+
is_expected.to be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
4
44
|
describe ".read_file_content" do
|
5
45
|
let(:path) { File.join(spec_system_tmp_dir, "test_file.txt") }
|
6
46
|
let(:bytes_to_read) { 100 }
|
@@ -16,6 +16,10 @@ describe Appsignal::CLI::Install do
|
|
16
16
|
allow(described_class).to receive(:press_any_key)
|
17
17
|
allow(Appsignal::Demo).to receive(:transmit).and_return(true)
|
18
18
|
end
|
19
|
+
after do
|
20
|
+
FileUtils.rm_rf(tmp_dir)
|
21
|
+
FileUtils.mkdir_p(tmp_dir)
|
22
|
+
end
|
19
23
|
around do |example|
|
20
24
|
original_stdin = $stdin
|
21
25
|
$stdin = StringIO.new
|
@@ -157,16 +161,10 @@ describe Appsignal::CLI::Install do
|
|
157
161
|
shared_examples "capistrano install" do
|
158
162
|
let(:capfile) { File.join(tmp_dir, "Capfile") }
|
159
163
|
before do
|
160
|
-
FileUtils.mkdir_p(tmp_dir)
|
161
|
-
|
162
164
|
enter_app_name "foo"
|
163
165
|
add_cli_input "n"
|
164
166
|
choose_environment_config
|
165
167
|
end
|
166
|
-
after do
|
167
|
-
FileUtils.rm_rf(tmp_dir)
|
168
|
-
FileUtils.mkdir_p(tmp_dir)
|
169
|
-
end
|
170
168
|
|
171
169
|
context "without Capfile" do
|
172
170
|
it "does nothing" do
|
@@ -260,7 +258,6 @@ describe Appsignal::CLI::Install do
|
|
260
258
|
FileUtils.touch(File.join(environments_dir, "development.rb"))
|
261
259
|
FileUtils.touch(File.join(environments_dir, "staging.rb"))
|
262
260
|
FileUtils.touch(File.join(environments_dir, "production.rb"))
|
263
|
-
enter_app_name app_name
|
264
261
|
end
|
265
262
|
|
266
263
|
describe "environments" do
|
@@ -410,6 +407,53 @@ describe Appsignal::CLI::Install do
|
|
410
407
|
end
|
411
408
|
end
|
412
409
|
end
|
410
|
+
|
411
|
+
context "when there is no Rails application.rb file" do
|
412
|
+
before do
|
413
|
+
# Do not detect it as another framework for testing
|
414
|
+
allow(described_class).to receive(:framework_available?).and_call_original
|
415
|
+
allow(described_class).to receive(:framework_available?).with("sinatra").and_return(false)
|
416
|
+
|
417
|
+
File.delete(File.join(config_dir, "application.rb"))
|
418
|
+
expect(File.exist?(File.join(config_dir, "application.rb"))).to eql(false)
|
419
|
+
end
|
420
|
+
|
421
|
+
it "fails the installation" do
|
422
|
+
run
|
423
|
+
|
424
|
+
expect(output).to include("We could not detect which framework you are using.")
|
425
|
+
expect(output).to_not include("Installing for Ruby on Rails")
|
426
|
+
expect(output).to include_complete_install
|
427
|
+
|
428
|
+
expect(File.exist?(config_file_path)).to be(false)
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
context "when failed to load the Rails application.rb file" do
|
433
|
+
before do
|
434
|
+
File.open(File.join(config_dir, "application.rb"), "w") do |file|
|
435
|
+
file.write("I am invalid code")
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
it "prompts the user to fill in an app name" do
|
440
|
+
enter_app_name app_name
|
441
|
+
choose_config_file
|
442
|
+
run
|
443
|
+
|
444
|
+
expect(output).to include("Installing for Ruby on Rails")
|
445
|
+
expect(output).to include("Unable to automatically detect your Rails app's name.")
|
446
|
+
expect(output).to include("Choose your app's display name for AppSignal.com:")
|
447
|
+
expect(output).to include_file_config
|
448
|
+
expect(output).to include_complete_install
|
449
|
+
|
450
|
+
expect(config_file).to configure_app_name(app_name)
|
451
|
+
expect(config_file).to configure_push_api_key(push_api_key)
|
452
|
+
expect(config_file).to configure_environment("development")
|
453
|
+
expect(config_file).to configure_environment("staging")
|
454
|
+
expect(config_file).to configure_environment("production")
|
455
|
+
end
|
456
|
+
end
|
413
457
|
end
|
414
458
|
end
|
415
459
|
|
@@ -116,6 +116,9 @@ describe Appsignal::CLI::NotifyOfDeploy do
|
|
116
116
|
|
117
117
|
context "with required options" do
|
118
118
|
let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs" } }
|
119
|
+
let(:log_stream) { std_stream }
|
120
|
+
let(:log) { log_contents(log_stream) }
|
121
|
+
before { Appsignal.logger = test_logger(log_stream) }
|
119
122
|
|
120
123
|
it "notifies of a deploy" do
|
121
124
|
run
|
@@ -124,6 +127,13 @@ describe Appsignal::CLI::NotifyOfDeploy do
|
|
124
127
|
expect(output).to include_deploy_notification_with(options)
|
125
128
|
end
|
126
129
|
|
130
|
+
it "prints a deprecation message" do
|
131
|
+
run
|
132
|
+
deprecation_message = "This command (appsignal notify_of_deploy) has been deprecated"
|
133
|
+
expect(output).to include("appsignal WARNING: #{deprecation_message}")
|
134
|
+
expect(log).to contains_log :warn, deprecation_message
|
135
|
+
end
|
136
|
+
|
127
137
|
context "with no app name configured" do
|
128
138
|
before { ENV["APPSIGNAL_APP_NAME"] = "" }
|
129
139
|
|
@@ -202,14 +202,16 @@ describe Appsignal::Config do
|
|
202
202
|
context "with a config file" do
|
203
203
|
let(:config) { project_fixture_config("production") }
|
204
204
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
205
|
+
context "with valid config" do
|
206
|
+
it "is valid and active" do
|
207
|
+
expect(config.valid?).to be_truthy
|
208
|
+
expect(config.active?).to be_truthy
|
209
|
+
end
|
209
210
|
|
210
|
-
|
211
|
-
|
212
|
-
|
211
|
+
it "does not log an error" do
|
212
|
+
log = capture_logs { config }
|
213
|
+
expect(log).to_not contains_log(:error)
|
214
|
+
end
|
213
215
|
end
|
214
216
|
|
215
217
|
it "sets the file_config" do
|
@@ -477,7 +479,7 @@ describe Appsignal::Config do
|
|
477
479
|
|
478
480
|
it "writes the current config to environment variables" do
|
479
481
|
expect(ENV["_APPSIGNAL_ACTIVE"]).to eq "true"
|
480
|
-
expect(ENV["_APPSIGNAL_APP_PATH"]).to end_with("spec/support/
|
482
|
+
expect(ENV["_APPSIGNAL_APP_PATH"]).to end_with("spec/support/fixtures/projects/valid")
|
481
483
|
expect(ENV["_APPSIGNAL_AGENT_PATH"]).to end_with("/ext")
|
482
484
|
expect(ENV["_APPSIGNAL_DEBUG_LOGGING"]).to eq "false"
|
483
485
|
expect(ENV["_APPSIGNAL_LOG"]).to eq "stdout"
|
@@ -1,43 +1,53 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
describe Appsignal::EventFormatter::ActionView::RenderFormatter do
|
2
|
+
let(:klass) { Appsignal::EventFormatter::ActionView::RenderFormatter }
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
let(:klass) { Appsignal::EventFormatter::ActionView::RenderFormatter }
|
7
|
-
let(:formatter) { klass.new }
|
4
|
+
if DependencyHelper.rails_present?
|
5
|
+
require "action_view"
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
context "when in a Rails app" do
|
8
|
+
let(:formatter) { klass.new }
|
9
|
+
before { allow(Rails.root).to receive(:to_s).and_return("/var/www/app/20130101") }
|
10
|
+
|
11
|
+
it "registers render_partial.action_view and render_template.action_view" do
|
12
|
+
expect(Appsignal::EventFormatter.registered?("render_partial.action_view", klass)).to be_truthy
|
13
|
+
expect(Appsignal::EventFormatter.registered?("render_template.action_view", klass)).to be_truthy
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
+
describe "#root_path" do
|
17
|
+
subject { formatter.root_path }
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
+
it "returns Rails root path" do
|
20
|
+
is_expected.to eq "/var/www/app/20130101/"
|
21
|
+
end
|
19
22
|
end
|
20
|
-
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
+
describe "#format" do
|
25
|
+
subject { formatter.format(payload) }
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
+
context "with an identifier" do
|
28
|
+
let(:payload) { { :identifier => "/var/www/app/20130101/app/views/home/index/html.erb" } }
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
+
it { is_expected.to eq ["app/views/home/index/html.erb", nil] }
|
31
|
+
end
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
+
context "with a frozen identifier" do
|
34
|
+
let(:payload) { { :identifier => "/var/www/app/20130101/app/views/home/index/html.erb".freeze } }
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
+
it { is_expected.to eq ["app/views/home/index/html.erb", nil] }
|
37
|
+
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
+
context "without an identifier" do
|
40
|
+
let(:payload) { {} }
|
39
41
|
|
40
|
-
|
42
|
+
it { is_expected.to be_nil }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
else
|
47
|
+
context "when not in a Rails app" do
|
48
|
+
it "does not register the event formatter" do
|
49
|
+
expect(Appsignal::EventFormatter.registered?("render_partial.action_view", klass)).to be_falsy
|
50
|
+
expect(Appsignal::EventFormatter.registered?("render_template.action_view", klass)).to be_falsy
|
41
51
|
end
|
42
52
|
end
|
43
53
|
end
|
@@ -2,12 +2,14 @@ describe Appsignal::Hooks::ActiveSupportNotificationsHook do
|
|
2
2
|
if active_support_present?
|
3
3
|
let(:notifier) { ActiveSupport::Notifications::Fanout.new }
|
4
4
|
let(:as) { ActiveSupport::Notifications }
|
5
|
+
let!(:transaction) do
|
6
|
+
Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
|
7
|
+
end
|
5
8
|
before :context do
|
6
9
|
start_agent
|
7
10
|
end
|
8
11
|
before do
|
9
12
|
as.notifier = notifier
|
10
|
-
Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
|
11
13
|
end
|
12
14
|
|
13
15
|
describe "#dependencies_present?" do
|
@@ -17,27 +19,71 @@ describe Appsignal::Hooks::ActiveSupportNotificationsHook do
|
|
17
19
|
end
|
18
20
|
|
19
21
|
it "instruments an ActiveSupport::Notifications.instrument event" do
|
20
|
-
expect(Appsignal::Transaction.current).to receive(:start_event)
|
21
|
-
.at_least(:once)
|
22
|
-
expect(Appsignal::Transaction.current).to receive(:finish_event)
|
23
|
-
.at_least(:once)
|
24
|
-
.with("sql.active_record", nil, "SQL", 1)
|
25
|
-
|
26
22
|
return_value = as.instrument("sql.active_record", :sql => "SQL") do
|
27
23
|
"value"
|
28
24
|
end
|
29
25
|
|
30
26
|
expect(return_value).to eq "value"
|
27
|
+
expect(transaction.to_h["events"]).to match([
|
28
|
+
{
|
29
|
+
"allocation_count" => kind_of(Integer),
|
30
|
+
"body" => "SQL",
|
31
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
32
|
+
"child_allocation_count" => kind_of(Integer),
|
33
|
+
"child_duration" => kind_of(Float),
|
34
|
+
"child_gc_duration" => kind_of(Float),
|
35
|
+
"count" => 1,
|
36
|
+
"duration" => kind_of(Float),
|
37
|
+
"gc_duration" => kind_of(Float),
|
38
|
+
"name" => "sql.active_record",
|
39
|
+
"start" => kind_of(Float),
|
40
|
+
"title" => ""
|
41
|
+
}
|
42
|
+
])
|
31
43
|
end
|
32
44
|
|
33
|
-
it "
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
45
|
+
it "instruments an ActiveSupport::Notifications.instrument event with no registered formatter" do
|
46
|
+
return_value = as.instrument("no-registered.formatter", :key => "something") do
|
47
|
+
"value"
|
48
|
+
end
|
49
|
+
|
50
|
+
expect(return_value).to eq "value"
|
51
|
+
expect(transaction.to_h["events"]).to match([
|
52
|
+
{
|
53
|
+
"allocation_count" => kind_of(Integer),
|
54
|
+
"body" => "",
|
55
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
56
|
+
"child_allocation_count" => kind_of(Integer),
|
57
|
+
"child_duration" => kind_of(Float),
|
58
|
+
"child_gc_duration" => kind_of(Float),
|
59
|
+
"count" => 1,
|
60
|
+
"duration" => kind_of(Float),
|
61
|
+
"gc_duration" => kind_of(Float),
|
62
|
+
"name" => "no-registered.formatter",
|
63
|
+
"start" => kind_of(Float),
|
64
|
+
"title" => ""
|
65
|
+
}
|
66
|
+
])
|
67
|
+
end
|
39
68
|
|
69
|
+
it "converts non-string names to strings" do
|
40
70
|
as.instrument(:not_a_string) {}
|
71
|
+
expect(transaction.to_h["events"]).to match([
|
72
|
+
{
|
73
|
+
"allocation_count" => kind_of(Integer),
|
74
|
+
"body" => "",
|
75
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
76
|
+
"child_allocation_count" => kind_of(Integer),
|
77
|
+
"child_duration" => kind_of(Float),
|
78
|
+
"child_gc_duration" => kind_of(Float),
|
79
|
+
"count" => 1,
|
80
|
+
"duration" => kind_of(Float),
|
81
|
+
"gc_duration" => kind_of(Float),
|
82
|
+
"name" => "not_a_string",
|
83
|
+
"start" => kind_of(Float),
|
84
|
+
"title" => ""
|
85
|
+
}
|
86
|
+
])
|
41
87
|
end
|
42
88
|
|
43
89
|
it "does not instrument events whose name starts with a bang" do
|
@@ -53,33 +99,66 @@ describe Appsignal::Hooks::ActiveSupportNotificationsHook do
|
|
53
99
|
|
54
100
|
context "when an error is raised in an instrumented block" do
|
55
101
|
it "instruments an ActiveSupport::Notifications.instrument event" do
|
56
|
-
expect(Appsignal::Transaction.current).to receive(:start_event)
|
57
|
-
.at_least(:once)
|
58
|
-
expect(Appsignal::Transaction.current).to receive(:finish_event)
|
59
|
-
.at_least(:once)
|
60
|
-
.with("sql.active_record", nil, "SQL", 1)
|
61
|
-
|
62
102
|
expect do
|
63
103
|
as.instrument("sql.active_record", :sql => "SQL") do
|
64
104
|
raise ExampleException, "foo"
|
65
105
|
end
|
66
106
|
end.to raise_error(ExampleException, "foo")
|
107
|
+
|
108
|
+
expect(transaction.to_h["events"]).to match([
|
109
|
+
{
|
110
|
+
"allocation_count" => kind_of(Integer),
|
111
|
+
"body" => "SQL",
|
112
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
113
|
+
"child_allocation_count" => kind_of(Integer),
|
114
|
+
"child_duration" => kind_of(Float),
|
115
|
+
"child_gc_duration" => kind_of(Float),
|
116
|
+
"count" => 1,
|
117
|
+
"duration" => kind_of(Float),
|
118
|
+
"gc_duration" => kind_of(Float),
|
119
|
+
"name" => "sql.active_record",
|
120
|
+
"start" => kind_of(Float),
|
121
|
+
"title" => ""
|
122
|
+
}
|
123
|
+
])
|
67
124
|
end
|
68
125
|
end
|
69
126
|
|
70
127
|
context "when a message is thrown in an instrumented block" do
|
71
128
|
it "instruments an ActiveSupport::Notifications.instrument event" do
|
72
|
-
expect(Appsignal::Transaction.current).to receive(:start_event)
|
73
|
-
.at_least(:once)
|
74
|
-
expect(Appsignal::Transaction.current).to receive(:finish_event)
|
75
|
-
.at_least(:once)
|
76
|
-
.with("sql.active_record", nil, "SQL", 1)
|
77
|
-
|
78
129
|
expect do
|
79
130
|
as.instrument("sql.active_record", :sql => "SQL") do
|
80
131
|
throw :foo
|
81
132
|
end
|
82
133
|
end.to throw_symbol(:foo)
|
134
|
+
|
135
|
+
expect(transaction.to_h["events"]).to match([
|
136
|
+
{
|
137
|
+
"allocation_count" => kind_of(Integer),
|
138
|
+
"body" => "SQL",
|
139
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
140
|
+
"child_allocation_count" => kind_of(Integer),
|
141
|
+
"child_duration" => kind_of(Float),
|
142
|
+
"child_gc_duration" => kind_of(Float),
|
143
|
+
"count" => 1,
|
144
|
+
"duration" => kind_of(Float),
|
145
|
+
"gc_duration" => kind_of(Float),
|
146
|
+
"name" => "sql.active_record",
|
147
|
+
"start" => kind_of(Float),
|
148
|
+
"title" => ""
|
149
|
+
}
|
150
|
+
])
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "when a transaction is completed in an instrumented block" do
|
155
|
+
it "does not complete the ActiveSupport::Notifications.instrument event" do
|
156
|
+
expect(transaction).to receive(:complete)
|
157
|
+
as.instrument("sql.active_record", :sql => "SQL") do
|
158
|
+
Appsignal::Transaction.complete_current!
|
159
|
+
end
|
160
|
+
|
161
|
+
expect(transaction.to_h["events"]).to match([])
|
83
162
|
end
|
84
163
|
end
|
85
164
|
else
|