appsignal 2.11.0.beta.3-java → 2.11.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.semaphore/semaphore.yml +57 -1
- data/CHANGELOG.md +26 -0
- data/README.md +11 -5
- data/Rakefile +27 -9
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +2 -2
- data/ext/Rakefile +2 -0
- data/ext/agent.yml +17 -25
- data/ext/appsignal_extension.c +1 -1
- data/ext/base.rb +7 -0
- data/ext/extconf.rb +2 -0
- data/lib/appsignal.rb +1 -0
- data/lib/appsignal/auth_check.rb +4 -2
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/config.rb +82 -17
- data/lib/appsignal/extension.rb +6 -5
- data/lib/appsignal/extension/jruby.rb +6 -5
- data/lib/appsignal/hooks.rb +24 -0
- data/lib/appsignal/hooks/action_mailer.rb +22 -0
- data/lib/appsignal/hooks/active_job.rb +41 -12
- data/lib/appsignal/hooks/active_support_notifications.rb +72 -0
- data/lib/appsignal/hooks/puma.rb +0 -1
- data/lib/appsignal/hooks/sidekiq.rb +1 -2
- data/lib/appsignal/integrations/delayed_job_plugin.rb +1 -1
- data/lib/appsignal/probes.rb +7 -0
- data/lib/appsignal/probes/puma.rb +1 -1
- data/lib/appsignal/probes/sidekiq.rb +3 -1
- data/lib/appsignal/utils/deprecation_message.rb +1 -1
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/auth_check_spec.rb +23 -0
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/capistrano3_spec.rb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +42 -0
- data/spec/lib/appsignal/config_spec.rb +39 -1
- data/spec/lib/appsignal/extension/jruby_spec.rb +31 -28
- data/spec/lib/appsignal/extension_install_failure_spec.rb +23 -0
- data/spec/lib/appsignal/hooks/action_mailer_spec.rb +54 -0
- data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +35 -0
- data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +145 -0
- data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +69 -0
- data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +9 -137
- data/spec/lib/appsignal/hooks/activejob_spec.rb +82 -12
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +3 -14
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +7 -5
- data/spec/lib/appsignal/hooks_spec.rb +57 -0
- data/spec/lib/appsignal/marker_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/support/helpers/config_helpers.rb +3 -2
- data/spec/support/helpers/dependency_helper.rb +4 -0
- data/spec/support/helpers/transaction_helpers.rb +1 -1
- data/spec/support/testing.rb +19 -19
- metadata +21 -9
|
@@ -1,42 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
describe "JRuby extension", :jruby do
|
|
2
|
+
let(:extension) { Appsignal::Extension }
|
|
3
|
+
let(:jruby_module) { Appsignal::Extension::Jruby }
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
# Tests if the conversions between the conversions without breaking on
|
|
9
|
-
# NULL terminated strings in C.
|
|
10
|
-
string = "Merry Christmas! \u0000 🎄"
|
|
5
|
+
it "creates a JRuby extension module" do
|
|
6
|
+
expect(Appsignal::Extension::Jruby).to be_kind_of(Module)
|
|
7
|
+
end
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
describe "string conversions" do
|
|
10
|
+
it "keeps the same value during string type conversions" do
|
|
11
|
+
# UTF-8 string with NULL
|
|
12
|
+
# Tests if the conversions between the conversions without breaking on
|
|
13
|
+
# NULL terminated strings in C.
|
|
14
|
+
string = "Merry Christmas! \u0000 🎄"
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
end
|
|
16
|
+
appsignal_string = extension.make_appsignal_string(string)
|
|
17
|
+
ruby_string = extension.make_ruby_string(appsignal_string)
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
expect(described_class.ffi_libraries.map(&:name).first).to include "libappsignal"
|
|
19
|
+
expect(ruby_string).to eq("Merry Christmas! \u0000 🎄")
|
|
21
20
|
end
|
|
21
|
+
end
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
it "loads libappsignal with FFI" do
|
|
24
|
+
expect(jruby_module.ffi_libraries.map(&:name).first).to include "libappsignal"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe ".lib_extension" do
|
|
28
|
+
subject { jruby_module.lib_extension }
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
context "when on a darwin system" do
|
|
31
|
+
before { expect(Appsignal::System).to receive(:agent_platform).and_return("darwin") }
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
33
|
+
it "returns the extension for darwin" do
|
|
34
|
+
is_expected.to eq "dylib"
|
|
32
35
|
end
|
|
36
|
+
end
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
context "when on a linux system" do
|
|
39
|
+
before { expect(Appsignal::System).to receive(:agent_platform).and_return("linux") }
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
end
|
|
41
|
+
it "returns the lib extension for linux" do
|
|
42
|
+
is_expected.to eq "so"
|
|
40
43
|
end
|
|
41
44
|
end
|
|
42
45
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
describe Appsignal::Extension, :extension_installation_failure do
|
|
2
|
+
context "when the extension library cannot be loaded" do
|
|
3
|
+
# This test breaks the installation on purpose and is not run by default.
|
|
4
|
+
# See `rake test:failure`. If this test was run, run `rake
|
|
5
|
+
# extension:install` again to fix the extension installation.
|
|
6
|
+
it "prints and logs an error" do
|
|
7
|
+
# ENV var to make sure installation fails on purpurse
|
|
8
|
+
ENV["_TEST_APPSIGNAL_EXTENSION_FAILURE"] = "true"
|
|
9
|
+
`rake extension:install` # Run installation
|
|
10
|
+
|
|
11
|
+
require "open3"
|
|
12
|
+
_stdout, stderr, _status = Open3.capture3("bin/appsignal --version")
|
|
13
|
+
expect(stderr).to include("ERROR: AppSignal failed to load extension")
|
|
14
|
+
error_message =
|
|
15
|
+
if DependencyHelper.running_jruby?
|
|
16
|
+
"cannot open shared object file"
|
|
17
|
+
else
|
|
18
|
+
"LoadError: cannot load such file"
|
|
19
|
+
end
|
|
20
|
+
expect(stderr).to include(error_message)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
describe Appsignal::Hooks::ActionMailerHook do
|
|
2
|
+
if DependencyHelper.action_mailer_present? &&
|
|
3
|
+
DependencyHelper.rails_version >= Gem::Version.new("4.0.0")
|
|
4
|
+
context "with ActionMailer" do
|
|
5
|
+
require "action_mailer"
|
|
6
|
+
|
|
7
|
+
class UserMailer < ActionMailer::Base
|
|
8
|
+
default :from => "test@example.com"
|
|
9
|
+
|
|
10
|
+
def welcome
|
|
11
|
+
mail(:to => "test@example.com", :subject => "ActionMailer test", :content_type => "text/html") do |format|
|
|
12
|
+
format.html { render :html => "This is a test" }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
UserMailer.delivery_method = :test
|
|
17
|
+
|
|
18
|
+
describe ".dependencies_present?" do
|
|
19
|
+
subject { described_class.new.dependencies_present? }
|
|
20
|
+
|
|
21
|
+
it "returns true" do
|
|
22
|
+
is_expected.to be_truthy
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe ".install" do
|
|
27
|
+
before do
|
|
28
|
+
start_agent
|
|
29
|
+
expect(Appsignal.active?).to be_truthy
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "is subscribed to 'process.action_mailer' and processes instrumentation" do
|
|
33
|
+
expect(Appsignal).to receive(:increment_counter).with(
|
|
34
|
+
:action_mailer_process,
|
|
35
|
+
1,
|
|
36
|
+
:mailer => "UserMailer", :action => :welcome
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
UserMailer.welcome.deliver_now
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
context "without ActionMailer" do
|
|
45
|
+
describe ".dependencies_present?" do
|
|
46
|
+
subject { described_class.new.dependencies_present? }
|
|
47
|
+
|
|
48
|
+
it "returns false" do
|
|
49
|
+
is_expected.to be_falsy
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
shared_examples "activesupport finish_with_state override" do
|
|
2
|
+
let(:instrumenter) { as.instrumenter }
|
|
3
|
+
|
|
4
|
+
it "instruments an ActiveSupport::Notifications.start/finish event with payload on finish" do
|
|
5
|
+
listeners_state = instrumenter.start("sql.active_record", {})
|
|
6
|
+
instrumenter.finish_with_state(listeners_state, "sql.active_record", :sql => "SQL")
|
|
7
|
+
|
|
8
|
+
expect(transaction.to_h["events"]).to match([
|
|
9
|
+
{
|
|
10
|
+
"allocation_count" => kind_of(Integer),
|
|
11
|
+
"body" => "SQL",
|
|
12
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
|
13
|
+
"child_allocation_count" => kind_of(Integer),
|
|
14
|
+
"child_duration" => kind_of(Float),
|
|
15
|
+
"child_gc_duration" => kind_of(Float),
|
|
16
|
+
"count" => 1,
|
|
17
|
+
"duration" => kind_of(Float),
|
|
18
|
+
"gc_duration" => kind_of(Float),
|
|
19
|
+
"name" => "sql.active_record",
|
|
20
|
+
"start" => kind_of(Float),
|
|
21
|
+
"title" => ""
|
|
22
|
+
}
|
|
23
|
+
])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "does not instrument events whose name starts with a bang" do
|
|
27
|
+
expect(Appsignal::Transaction.current).not_to receive(:start_event)
|
|
28
|
+
expect(Appsignal::Transaction.current).not_to receive(:finish_event)
|
|
29
|
+
|
|
30
|
+
listeners_state = instrumenter.start("!sql.active_record", {})
|
|
31
|
+
instrumenter.finish_with_state(listeners_state, "!sql.active_record", :sql => "SQL")
|
|
32
|
+
|
|
33
|
+
expect(transaction.to_h["events"]).to be_empty
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
shared_examples "activesupport instrument override" do
|
|
2
|
+
it "instruments an ActiveSupport::Notifications.instrument event" do
|
|
3
|
+
return_value = as.instrument("sql.active_record", :sql => "SQL") do
|
|
4
|
+
"value"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
expect(return_value).to eq "value"
|
|
8
|
+
expect(transaction.to_h["events"]).to match([
|
|
9
|
+
{
|
|
10
|
+
"allocation_count" => kind_of(Integer),
|
|
11
|
+
"body" => "SQL",
|
|
12
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
|
13
|
+
"child_allocation_count" => kind_of(Integer),
|
|
14
|
+
"child_duration" => kind_of(Float),
|
|
15
|
+
"child_gc_duration" => kind_of(Float),
|
|
16
|
+
"count" => 1,
|
|
17
|
+
"duration" => kind_of(Float),
|
|
18
|
+
"gc_duration" => kind_of(Float),
|
|
19
|
+
"name" => "sql.active_record",
|
|
20
|
+
"start" => kind_of(Float),
|
|
21
|
+
"title" => ""
|
|
22
|
+
}
|
|
23
|
+
])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "instruments an ActiveSupport::Notifications.instrument event with no registered formatter" do
|
|
27
|
+
return_value = as.instrument("no-registered.formatter", :key => "something") do
|
|
28
|
+
"value"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
expect(return_value).to eq "value"
|
|
32
|
+
expect(transaction.to_h["events"]).to match([
|
|
33
|
+
{
|
|
34
|
+
"allocation_count" => kind_of(Integer),
|
|
35
|
+
"body" => "",
|
|
36
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
|
37
|
+
"child_allocation_count" => kind_of(Integer),
|
|
38
|
+
"child_duration" => kind_of(Float),
|
|
39
|
+
"child_gc_duration" => kind_of(Float),
|
|
40
|
+
"count" => 1,
|
|
41
|
+
"duration" => kind_of(Float),
|
|
42
|
+
"gc_duration" => kind_of(Float),
|
|
43
|
+
"name" => "no-registered.formatter",
|
|
44
|
+
"start" => kind_of(Float),
|
|
45
|
+
"title" => ""
|
|
46
|
+
}
|
|
47
|
+
])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "converts non-string names to strings" do
|
|
51
|
+
as.instrument(:not_a_string) {}
|
|
52
|
+
expect(transaction.to_h["events"]).to match([
|
|
53
|
+
{
|
|
54
|
+
"allocation_count" => kind_of(Integer),
|
|
55
|
+
"body" => "",
|
|
56
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
|
57
|
+
"child_allocation_count" => kind_of(Integer),
|
|
58
|
+
"child_duration" => kind_of(Float),
|
|
59
|
+
"child_gc_duration" => kind_of(Float),
|
|
60
|
+
"count" => 1,
|
|
61
|
+
"duration" => kind_of(Float),
|
|
62
|
+
"gc_duration" => kind_of(Float),
|
|
63
|
+
"name" => "not_a_string",
|
|
64
|
+
"start" => kind_of(Float),
|
|
65
|
+
"title" => ""
|
|
66
|
+
}
|
|
67
|
+
])
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "does not instrument events whose name starts with a bang" do
|
|
71
|
+
expect(Appsignal::Transaction.current).not_to receive(:start_event)
|
|
72
|
+
expect(Appsignal::Transaction.current).not_to receive(:finish_event)
|
|
73
|
+
|
|
74
|
+
return_value = as.instrument("!sql.active_record", :sql => "SQL") do
|
|
75
|
+
"value"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
expect(return_value).to eq "value"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context "when an error is raised in an instrumented block" do
|
|
82
|
+
it "instruments an ActiveSupport::Notifications.instrument event" do
|
|
83
|
+
expect do
|
|
84
|
+
as.instrument("sql.active_record", :sql => "SQL") do
|
|
85
|
+
raise ExampleException, "foo"
|
|
86
|
+
end
|
|
87
|
+
end.to raise_error(ExampleException, "foo")
|
|
88
|
+
|
|
89
|
+
expect(transaction.to_h["events"]).to match([
|
|
90
|
+
{
|
|
91
|
+
"allocation_count" => kind_of(Integer),
|
|
92
|
+
"body" => "SQL",
|
|
93
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
|
94
|
+
"child_allocation_count" => kind_of(Integer),
|
|
95
|
+
"child_duration" => kind_of(Float),
|
|
96
|
+
"child_gc_duration" => kind_of(Float),
|
|
97
|
+
"count" => 1,
|
|
98
|
+
"duration" => kind_of(Float),
|
|
99
|
+
"gc_duration" => kind_of(Float),
|
|
100
|
+
"name" => "sql.active_record",
|
|
101
|
+
"start" => kind_of(Float),
|
|
102
|
+
"title" => ""
|
|
103
|
+
}
|
|
104
|
+
])
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context "when a message is thrown in an instrumented block" do
|
|
109
|
+
it "instruments an ActiveSupport::Notifications.instrument event" do
|
|
110
|
+
expect do
|
|
111
|
+
as.instrument("sql.active_record", :sql => "SQL") do
|
|
112
|
+
throw :foo
|
|
113
|
+
end
|
|
114
|
+
end.to throw_symbol(:foo)
|
|
115
|
+
|
|
116
|
+
expect(transaction.to_h["events"]).to match([
|
|
117
|
+
{
|
|
118
|
+
"allocation_count" => kind_of(Integer),
|
|
119
|
+
"body" => "SQL",
|
|
120
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
|
121
|
+
"child_allocation_count" => kind_of(Integer),
|
|
122
|
+
"child_duration" => kind_of(Float),
|
|
123
|
+
"child_gc_duration" => kind_of(Float),
|
|
124
|
+
"count" => 1,
|
|
125
|
+
"duration" => kind_of(Float),
|
|
126
|
+
"gc_duration" => kind_of(Float),
|
|
127
|
+
"name" => "sql.active_record",
|
|
128
|
+
"start" => kind_of(Float),
|
|
129
|
+
"title" => ""
|
|
130
|
+
}
|
|
131
|
+
])
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
context "when a transaction is completed in an instrumented block" do
|
|
136
|
+
it "does not complete the ActiveSupport::Notifications.instrument event" do
|
|
137
|
+
expect(transaction).to receive(:complete)
|
|
138
|
+
as.instrument("sql.active_record", :sql => "SQL") do
|
|
139
|
+
Appsignal::Transaction.complete_current!
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
expect(transaction.to_h["events"]).to match([])
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
shared_examples "activesupport start finish override" do
|
|
2
|
+
let(:instrumenter) { as.instrumenter }
|
|
3
|
+
|
|
4
|
+
it "instruments an ActiveSupport::Notifications.start/finish event with payload on start ignores payload" do
|
|
5
|
+
instrumenter.start("sql.active_record", :sql => "SQL")
|
|
6
|
+
instrumenter.finish("sql.active_record", {})
|
|
7
|
+
|
|
8
|
+
expect(transaction.to_h["events"]).to match([
|
|
9
|
+
{
|
|
10
|
+
"allocation_count" => kind_of(Integer),
|
|
11
|
+
"body" => "",
|
|
12
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
|
13
|
+
"child_allocation_count" => kind_of(Integer),
|
|
14
|
+
"child_duration" => kind_of(Float),
|
|
15
|
+
"child_gc_duration" => kind_of(Float),
|
|
16
|
+
"count" => 1,
|
|
17
|
+
"duration" => kind_of(Float),
|
|
18
|
+
"gc_duration" => kind_of(Float),
|
|
19
|
+
"name" => "sql.active_record",
|
|
20
|
+
"start" => kind_of(Float),
|
|
21
|
+
"title" => ""
|
|
22
|
+
}
|
|
23
|
+
])
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "instruments an ActiveSupport::Notifications.start/finish event with payload on finish" do
|
|
27
|
+
instrumenter.start("sql.active_record", {})
|
|
28
|
+
instrumenter.finish("sql.active_record", :sql => "SQL")
|
|
29
|
+
|
|
30
|
+
expect(transaction.to_h["events"]).to match([
|
|
31
|
+
{
|
|
32
|
+
"allocation_count" => kind_of(Integer),
|
|
33
|
+
"body" => "SQL",
|
|
34
|
+
"body_format" => Appsignal::EventFormatter::SQL_BODY_FORMAT,
|
|
35
|
+
"child_allocation_count" => kind_of(Integer),
|
|
36
|
+
"child_duration" => kind_of(Float),
|
|
37
|
+
"child_gc_duration" => kind_of(Float),
|
|
38
|
+
"count" => 1,
|
|
39
|
+
"duration" => kind_of(Float),
|
|
40
|
+
"gc_duration" => kind_of(Float),
|
|
41
|
+
"name" => "sql.active_record",
|
|
42
|
+
"start" => kind_of(Float),
|
|
43
|
+
"title" => ""
|
|
44
|
+
}
|
|
45
|
+
])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "does not instrument events whose name starts with a bang" do
|
|
49
|
+
expect(Appsignal::Transaction.current).not_to receive(:start_event)
|
|
50
|
+
expect(Appsignal::Transaction.current).not_to receive(:finish_event)
|
|
51
|
+
|
|
52
|
+
instrumenter.start("!sql.active_record", {})
|
|
53
|
+
instrumenter.finish("!sql.active_record", {})
|
|
54
|
+
|
|
55
|
+
expect(transaction.to_h["events"]).to be_empty
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context "when a transaction is completed in an instrumented block" do
|
|
59
|
+
it "does not complete the ActiveSupport::Notifications.instrument event" do
|
|
60
|
+
expect(transaction).to receive(:complete)
|
|
61
|
+
|
|
62
|
+
instrumenter.start("sql.active_record", {})
|
|
63
|
+
Appsignal::Transaction.complete_current!
|
|
64
|
+
instrumenter.finish("sql.active_record", {})
|
|
65
|
+
|
|
66
|
+
expect(transaction.to_h["events"]).to match([])
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative "./active_support_notifications/instrument_shared_examples"
|
|
2
|
+
|
|
1
3
|
describe Appsignal::Hooks::ActiveSupportNotificationsHook do
|
|
2
4
|
if active_support_present?
|
|
3
5
|
let(:notifier) { ActiveSupport::Notifications::Fanout.new }
|
|
@@ -18,148 +20,18 @@ describe Appsignal::Hooks::ActiveSupportNotificationsHook do
|
|
|
18
20
|
it { is_expected.to be_truthy }
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
return_value = as.instrument("sql.active_record", :sql => "SQL") do
|
|
23
|
-
"value"
|
|
24
|
-
end
|
|
25
|
-
|
|
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
|
-
])
|
|
43
|
-
end
|
|
44
|
-
|
|
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
|
|
68
|
-
|
|
69
|
-
it "converts non-string names to strings" do
|
|
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
|
-
])
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "does not instrument events whose name starts with a bang" do
|
|
90
|
-
expect(Appsignal::Transaction.current).not_to receive(:start_event)
|
|
91
|
-
expect(Appsignal::Transaction.current).not_to receive(:finish_event)
|
|
92
|
-
|
|
93
|
-
return_value = as.instrument("!sql.active_record", :sql => "SQL") do
|
|
94
|
-
"value"
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
expect(return_value).to eq "value"
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
context "when an error is raised in an instrumented block" do
|
|
101
|
-
it "instruments an ActiveSupport::Notifications.instrument event" do
|
|
102
|
-
expect do
|
|
103
|
-
as.instrument("sql.active_record", :sql => "SQL") do
|
|
104
|
-
raise ExampleException, "foo"
|
|
105
|
-
end
|
|
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
|
-
])
|
|
124
|
-
end
|
|
125
|
-
end
|
|
23
|
+
it_behaves_like "activesupport instrument override"
|
|
126
24
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
expect do
|
|
130
|
-
as.instrument("sql.active_record", :sql => "SQL") do
|
|
131
|
-
throw :foo
|
|
132
|
-
end
|
|
133
|
-
end.to throw_symbol(:foo)
|
|
25
|
+
if ::ActiveSupport::Notifications::Instrumenter.method_defined?(:start)
|
|
26
|
+
require_relative "./active_support_notifications/start_finish_shared_examples"
|
|
134
27
|
|
|
135
|
-
|
|
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
|
|
28
|
+
it_behaves_like "activesupport start finish override"
|
|
152
29
|
end
|
|
153
30
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
expect(transaction).to receive(:complete)
|
|
157
|
-
as.instrument("sql.active_record", :sql => "SQL") do
|
|
158
|
-
Appsignal::Transaction.complete_current!
|
|
159
|
-
end
|
|
31
|
+
if ::ActiveSupport::Notifications::Instrumenter.method_defined?(:finish_with_state)
|
|
32
|
+
require_relative "./active_support_notifications/finish_with_state_shared_examples"
|
|
160
33
|
|
|
161
|
-
|
|
162
|
-
end
|
|
34
|
+
it_behaves_like "activesupport finish_with_state override"
|
|
163
35
|
end
|
|
164
36
|
else
|
|
165
37
|
describe "#dependencies_present?" do
|