appsignal 2.4.0 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|