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.
@@ -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
@@ -63,6 +63,10 @@ module DependencyHelper
63
63
  Gem.loaded_specs["capistrano"].version >= Gem::Version.new("3.0")
64
64
  end
65
65
 
66
+ def que_present?
67
+ dependency_present? "que"
68
+ end
69
+
66
70
  def dependency_present?(dependency_file)
67
71
  Gem.loaded_specs.key? dependency_file
68
72
  end
@@ -1,15 +1,20 @@
1
1
  module LogHelpers
2
2
  def use_logger_with(log)
3
- Appsignal.logger = Logger.new(log)
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.0
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-10-31 00:00:00.000000000 Z
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