appsignal 2.4.0 → 2.4.1
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/.gitignore +1 -0
- data/.rubocop_todo.yml +1 -1
- data/.travis.yml +1 -0
- data/CHANGELOG.md +8 -0
- data/Rakefile +1 -0
- data/ext/extconf.rb +10 -9
- data/gemfiles/que.gemfile +5 -0
- data/lib/appsignal/cli/diagnose.rb +3 -1
- data/lib/appsignal/hooks.rb +1 -0
- data/lib/appsignal/hooks/que.rb +21 -0
- data/lib/appsignal/hooks/sidekiq.rb +119 -39
- data/lib/appsignal/integrations/que.rb +43 -0
- data/lib/appsignal/system.rb +54 -0
- data/lib/appsignal/transaction.rb +7 -0
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +2 -0
- data/spec/lib/appsignal/hooks/que_spec.rb +19 -0
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +336 -176
- data/spec/lib/appsignal/integrations/que_spec.rb +174 -0
- data/spec/lib/appsignal/system_spec.rb +111 -0
- data/spec/support/helpers/dependency_helper.rb +4 -0
- data/spec/support/helpers/log_helpers.rb +11 -6
- data/spec/support/helpers/transaction_helpers.rb +6 -0
- metadata +9 -2
@@ -0,0 +1,174 @@
|
|
1
|
+
if DependencyHelper.que_present?
|
2
|
+
require "appsignal/integrations/que"
|
3
|
+
|
4
|
+
describe Appsignal::Integrations::QuePlugin do
|
5
|
+
describe "#_run" do
|
6
|
+
let(:job_attrs) do
|
7
|
+
{
|
8
|
+
:job_id => 123,
|
9
|
+
:queue => "dfl",
|
10
|
+
:job_class => "MyQueJob",
|
11
|
+
:priority => 100,
|
12
|
+
:args => %w(1 birds),
|
13
|
+
:run_at => fixed_time,
|
14
|
+
:error_count => 0
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:env) do
|
19
|
+
{
|
20
|
+
:class => "MyQueJob",
|
21
|
+
:method => "run",
|
22
|
+
:metadata => {
|
23
|
+
:id => 123,
|
24
|
+
:queue => "dfl",
|
25
|
+
:priority => 100,
|
26
|
+
:run_at => fixed_time.to_s,
|
27
|
+
:attempts => 0
|
28
|
+
},
|
29
|
+
:params => %w(1 birds)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:job) do
|
34
|
+
Class.new(::Que::Job) do
|
35
|
+
def run(*args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
let(:instance) { job.new(job_attrs) }
|
40
|
+
let(:transaction) do
|
41
|
+
Appsignal::Transaction.new(
|
42
|
+
SecureRandom.uuid,
|
43
|
+
Appsignal::Transaction::BACKGROUND_JOB,
|
44
|
+
Appsignal::Transaction::GenericRequest.new(env)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
before do
|
49
|
+
allow(Que).to receive(:execute)
|
50
|
+
|
51
|
+
start_agent
|
52
|
+
expect(Appsignal.active?).to be_truthy
|
53
|
+
transaction
|
54
|
+
|
55
|
+
expect(Appsignal::Transaction).to receive(:create)
|
56
|
+
.with(
|
57
|
+
kind_of(String),
|
58
|
+
Appsignal::Transaction::BACKGROUND_JOB,
|
59
|
+
kind_of(Appsignal::Transaction::GenericRequest)
|
60
|
+
).and_return(transaction)
|
61
|
+
allow(Appsignal::Transaction).to receive(:current).and_return(transaction)
|
62
|
+
expect(transaction.ext).to receive(:finish).and_return(true)
|
63
|
+
expect(transaction.ext).to receive(:complete)
|
64
|
+
end
|
65
|
+
|
66
|
+
subject { transaction.to_h }
|
67
|
+
|
68
|
+
context "success" do
|
69
|
+
it "creates a transaction for a job" do
|
70
|
+
expect do
|
71
|
+
instance._run
|
72
|
+
end.to_not raise_exception
|
73
|
+
|
74
|
+
expect(subject).to include(
|
75
|
+
"action" => "MyQueJob#run",
|
76
|
+
"id" => instance_of(String),
|
77
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB
|
78
|
+
)
|
79
|
+
expect(subject["error"]).to be_nil
|
80
|
+
expect(subject["events"].first).to include(
|
81
|
+
"allocation_count" => kind_of(Integer),
|
82
|
+
"body" => "",
|
83
|
+
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
84
|
+
"child_allocation_count" => kind_of(Integer),
|
85
|
+
"child_duration" => kind_of(Float),
|
86
|
+
"child_gc_duration" => kind_of(Float),
|
87
|
+
"count" => 1,
|
88
|
+
"gc_duration" => kind_of(Float),
|
89
|
+
"start" => kind_of(Float),
|
90
|
+
"duration" => kind_of(Float),
|
91
|
+
"name" => "perform_job.que",
|
92
|
+
"title" => ""
|
93
|
+
)
|
94
|
+
expect(subject["sample_data"]).to include(
|
95
|
+
"params" => %w(1 birds),
|
96
|
+
"metadata" => {
|
97
|
+
"attempts" => 0,
|
98
|
+
"id" => 123,
|
99
|
+
"priority" => 100,
|
100
|
+
"queue" => "dfl",
|
101
|
+
"run_at" => fixed_time.to_s
|
102
|
+
}
|
103
|
+
)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "with exception" do
|
108
|
+
let(:error) { ExampleException.new("oh no!") }
|
109
|
+
|
110
|
+
it "should report exceptions and re-raise them" do
|
111
|
+
allow(instance).to receive(:run).and_raise(error)
|
112
|
+
|
113
|
+
expect do
|
114
|
+
instance._run
|
115
|
+
end.to raise_error(ExampleException)
|
116
|
+
|
117
|
+
expect(subject).to include(
|
118
|
+
"action" => "MyQueJob#run",
|
119
|
+
"id" => instance_of(String),
|
120
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB
|
121
|
+
)
|
122
|
+
expect(subject["error"]).to include(
|
123
|
+
"backtrace" => kind_of(String),
|
124
|
+
"name" => error.class.name,
|
125
|
+
"message" => error.message
|
126
|
+
)
|
127
|
+
expect(subject["sample_data"]).to include(
|
128
|
+
"params" => %w(1 birds),
|
129
|
+
"metadata" => {
|
130
|
+
"attempts" => 0,
|
131
|
+
"id" => 123,
|
132
|
+
"priority" => 100,
|
133
|
+
"queue" => "dfl",
|
134
|
+
"run_at" => fixed_time.to_s
|
135
|
+
}
|
136
|
+
)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "with error" do
|
141
|
+
let(:error) { ExampleStandardError.new("oh no!") }
|
142
|
+
|
143
|
+
it "should report errors and not re-raise them" do
|
144
|
+
allow(instance).to receive(:run).and_raise(error)
|
145
|
+
|
146
|
+
expect do
|
147
|
+
instance._run
|
148
|
+
end.to_not raise_error
|
149
|
+
|
150
|
+
expect(subject).to include(
|
151
|
+
"action" => "MyQueJob#run",
|
152
|
+
"id" => instance_of(String),
|
153
|
+
"namespace" => Appsignal::Transaction::BACKGROUND_JOB
|
154
|
+
)
|
155
|
+
expect(subject["error"]).to include(
|
156
|
+
"backtrace" => kind_of(String),
|
157
|
+
"name" => error.class.name,
|
158
|
+
"message" => error.message
|
159
|
+
)
|
160
|
+
expect(subject["sample_data"]).to include(
|
161
|
+
"params" => %w(1 birds),
|
162
|
+
"metadata" => {
|
163
|
+
"attempts" => 0,
|
164
|
+
"id" => 123,
|
165
|
+
"priority" => 100,
|
166
|
+
"queue" => "dfl",
|
167
|
+
"run_at" => fixed_time.to_s
|
168
|
+
}
|
169
|
+
)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "appsignal/system"
|
2
|
+
|
1
3
|
describe Appsignal::System do
|
2
4
|
describe ".heroku?" do
|
3
5
|
subject { described_class.heroku? }
|
@@ -16,4 +18,113 @@ describe Appsignal::System do
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
21
|
+
|
22
|
+
describe ".installed_agent_platform" do
|
23
|
+
let(:const_name) { "GEM_EXT_PATH".freeze }
|
24
|
+
let(:tmp_ext_dir) { File.join(tmp_dir, "ext") }
|
25
|
+
let(:platform_file) { File.join(Appsignal::System::GEM_EXT_PATH, "appsignal.platform") }
|
26
|
+
around do |example|
|
27
|
+
original_gem_ext_path = Appsignal::System.const_get(const_name)
|
28
|
+
Appsignal::System.send(:remove_const, const_name)
|
29
|
+
Appsignal::System.const_set(const_name, tmp_ext_dir)
|
30
|
+
example.run
|
31
|
+
Appsignal::System.send(:remove_const, const_name)
|
32
|
+
Appsignal::System.const_set(const_name, original_gem_ext_path)
|
33
|
+
end
|
34
|
+
after { FileUtils.rm_rf(tmp_ext_dir) }
|
35
|
+
subject { described_class.installed_agent_platform }
|
36
|
+
|
37
|
+
context "with an ext/appsignal.platform file" do
|
38
|
+
before do
|
39
|
+
FileUtils.mkdir_p(Appsignal::System::GEM_EXT_PATH)
|
40
|
+
File.open(platform_file, "w") do |file|
|
41
|
+
file.write "foo"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns the contents of the file" do
|
46
|
+
expect(subject).to eq("foo")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "without an ext/appsignal.platform file" do
|
51
|
+
it "returns nil" do
|
52
|
+
expect(subject).to be_nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe ".agent_platform" do
|
58
|
+
let(:os) { "linux" }
|
59
|
+
let(:ldd_output) { "" }
|
60
|
+
before do
|
61
|
+
allow(described_class).to receive(:ldd_version_output).and_return(ldd_output)
|
62
|
+
allow(Gem::Platform.local).to receive(:os).and_return(os)
|
63
|
+
end
|
64
|
+
subject { described_class.agent_platform }
|
65
|
+
|
66
|
+
context "when the system detection doesn't work" do
|
67
|
+
it "returns the libc build" do
|
68
|
+
is_expected.to eq("linux")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when using the APPSIGNAL_BUILD_FOR_MUSL env var" do
|
73
|
+
it "returns the musl build" do
|
74
|
+
ENV["APPSIGNAL_BUILD_FOR_MUSL"] = "1"
|
75
|
+
is_expected.to eq("linux-musl")
|
76
|
+
ENV.delete("APPSIGNAL_BUILD_FOR_MUSL")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when on a musl system" do
|
81
|
+
let(:ldd_output) { "musl libc (x86_64)\nVersion 1.1.16" }
|
82
|
+
|
83
|
+
it "returns the musl build" do
|
84
|
+
is_expected.to eq("linux-musl")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when on a libc system" do
|
89
|
+
let(:ldd_output) { "ldd (Debian GLIBC 2.15-18+deb8u7) 2.15" }
|
90
|
+
|
91
|
+
it "returns the libc build" do
|
92
|
+
is_expected.to eq("linux")
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when on an old libc system" do
|
96
|
+
let(:ldd_output) { "ldd (Debian GLIBC 2.14-18+deb8u7) 2.14" }
|
97
|
+
|
98
|
+
it "returns the musl build" do
|
99
|
+
is_expected.to eq("linux-musl")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "when on a very old libc system" do
|
104
|
+
let(:ldd_output) { "ldd (Debian GLIBC 2.5-18+deb8u7) 2.5" }
|
105
|
+
|
106
|
+
it "returns the musl build" do
|
107
|
+
is_expected.to eq("linux-musl")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when on macOS" do
|
113
|
+
let(:os) { "darwin" }
|
114
|
+
let(:ldd_output) { "ldd: command not found" }
|
115
|
+
|
116
|
+
it "returns the darwin build" do
|
117
|
+
is_expected.to eq("darwin")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when on FreeBSD" do
|
122
|
+
let(:os) { "freebsd" }
|
123
|
+
let(:ldd_output) { "ldd: illegal option -- -" }
|
124
|
+
|
125
|
+
it "returns the darwin build" do
|
126
|
+
is_expected.to eq("freebsd")
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
19
130
|
end
|
@@ -1,15 +1,20 @@
|
|
1
1
|
module LogHelpers
|
2
2
|
def use_logger_with(log)
|
3
|
-
Appsignal.logger =
|
4
|
-
Appsignal.logger.formatter =
|
5
|
-
proc do |severity, _datetime, _progname, msg|
|
6
|
-
# This format is used in the `contains_log` matcher.
|
7
|
-
"[#{severity}] #{msg}\n"
|
8
|
-
end
|
3
|
+
Appsignal.logger = test_logger(log)
|
9
4
|
yield
|
10
5
|
Appsignal.logger = nil
|
11
6
|
end
|
12
7
|
|
8
|
+
def test_logger(log)
|
9
|
+
Logger.new(log).tap do |logger|
|
10
|
+
logger.formatter =
|
11
|
+
proc do |severity, _datetime, _progname, msg|
|
12
|
+
# This format is used in the `contains_log` matcher.
|
13
|
+
"[#{severity}] #{msg}\n"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
13
18
|
def log_contents(log)
|
14
19
|
log.rewind
|
15
20
|
log.read
|
@@ -28,4 +28,10 @@ module TransactionHelpers
|
|
28
28
|
}.merge(args))
|
29
29
|
)
|
30
30
|
end
|
31
|
+
|
32
|
+
# Use when {Appsignal::Transaction.clear_current_transaction!} is stubbed to
|
33
|
+
# clear the current transaction on the current thread.
|
34
|
+
def clear_current_transaction!
|
35
|
+
Thread.current[:appsignal_transaction] = nil
|
36
|
+
end
|
31
37
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appsignal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-11-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- gemfiles/grape.gemfile
|
155
155
|
- gemfiles/no_dependencies.gemfile
|
156
156
|
- gemfiles/padrino.gemfile
|
157
|
+
- gemfiles/que.gemfile
|
157
158
|
- gemfiles/rails-3.2.gemfile
|
158
159
|
- gemfiles/rails-4.0.gemfile
|
159
160
|
- gemfiles/rails-4.1.gemfile
|
@@ -196,6 +197,7 @@ files:
|
|
196
197
|
- lib/appsignal/hooks/net_http.rb
|
197
198
|
- lib/appsignal/hooks/passenger.rb
|
198
199
|
- lib/appsignal/hooks/puma.rb
|
200
|
+
- lib/appsignal/hooks/que.rb
|
199
201
|
- lib/appsignal/hooks/rake.rb
|
200
202
|
- lib/appsignal/hooks/redis.rb
|
201
203
|
- lib/appsignal/hooks/sequel.rb
|
@@ -211,6 +213,7 @@ files:
|
|
211
213
|
- lib/appsignal/integrations/mongo_ruby_driver.rb
|
212
214
|
- lib/appsignal/integrations/object.rb
|
213
215
|
- lib/appsignal/integrations/padrino.rb
|
216
|
+
- lib/appsignal/integrations/que.rb
|
214
217
|
- lib/appsignal/integrations/railtie.rb
|
215
218
|
- lib/appsignal/integrations/rake.rb
|
216
219
|
- lib/appsignal/integrations/resque.rb
|
@@ -266,6 +269,7 @@ files:
|
|
266
269
|
- spec/lib/appsignal/hooks/net_http_spec.rb
|
267
270
|
- spec/lib/appsignal/hooks/passenger_spec.rb
|
268
271
|
- spec/lib/appsignal/hooks/puma_spec.rb
|
272
|
+
- spec/lib/appsignal/hooks/que_spec.rb
|
269
273
|
- spec/lib/appsignal/hooks/rake_spec.rb
|
270
274
|
- spec/lib/appsignal/hooks/redis_spec.rb
|
271
275
|
- spec/lib/appsignal/hooks/sequel_spec.rb
|
@@ -279,6 +283,7 @@ files:
|
|
279
283
|
- spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb
|
280
284
|
- spec/lib/appsignal/integrations/object_spec.rb
|
281
285
|
- spec/lib/appsignal/integrations/padrino_spec.rb
|
286
|
+
- spec/lib/appsignal/integrations/que_spec.rb
|
282
287
|
- spec/lib/appsignal/integrations/railtie_spec.rb
|
283
288
|
- spec/lib/appsignal/integrations/resque_active_job_spec.rb
|
284
289
|
- spec/lib/appsignal/integrations/resque_spec.rb
|
@@ -389,6 +394,7 @@ test_files:
|
|
389
394
|
- spec/lib/appsignal/hooks/net_http_spec.rb
|
390
395
|
- spec/lib/appsignal/hooks/passenger_spec.rb
|
391
396
|
- spec/lib/appsignal/hooks/puma_spec.rb
|
397
|
+
- spec/lib/appsignal/hooks/que_spec.rb
|
392
398
|
- spec/lib/appsignal/hooks/rake_spec.rb
|
393
399
|
- spec/lib/appsignal/hooks/redis_spec.rb
|
394
400
|
- spec/lib/appsignal/hooks/sequel_spec.rb
|
@@ -402,6 +408,7 @@ test_files:
|
|
402
408
|
- spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb
|
403
409
|
- spec/lib/appsignal/integrations/object_spec.rb
|
404
410
|
- spec/lib/appsignal/integrations/padrino_spec.rb
|
411
|
+
- spec/lib/appsignal/integrations/que_spec.rb
|
405
412
|
- spec/lib/appsignal/integrations/railtie_spec.rb
|
406
413
|
- spec/lib/appsignal/integrations/resque_active_job_spec.rb
|
407
414
|
- spec/lib/appsignal/integrations/resque_spec.rb
|