appsignal 2.9.8 → 2.9.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8943e834f68be414db7b15bab1980a651190b084c6270422b78230c4d3428826
4
- data.tar.gz: 5f16b829fa9efd610b8040ee52103ccc31c5872cfe26d8f336548d312bc7d6b0
3
+ metadata.gz: e1d7fa0a46c7ba3c90ccbaca56b462644da1c3fc66efe545f86f0802351b2ee0
4
+ data.tar.gz: f0e5d4b31d892183aa162e0b1295e9422eed5a4d8d6f2a480b2ca376d194cd45
5
5
  SHA512:
6
- metadata.gz: b75337875c59626adbcf0df2df74a9f66f0dfe5a5dc807cfd189de3d2dc529dece0d18cc88f983bee41e3ddee475e1cbfcfedbf450d1adf8bd51c92ebb1ff467
7
- data.tar.gz: '09df480bcdab11e0d80e48d8872f519900d18913dabd656e56a4545132d8822cf1ba5e98394ffc10b8f739b4e01cab652602cd1483937881c6dbddfc9a56ec0c'
6
+ metadata.gz: d9baa71a5a0576d8244a3857232e6e25132297b52114e882f8ee01b86dbe18be2dc9232812cfd8720070b5f39fc57bd67350e53c3290ef349bd39bfa8e1d9531
7
+ data.tar.gz: cc6bf8d75938f2571ee8dbd5aec10ada0f87d8f7f8163e6bd200b5eb55401e3e9d79c3f3eff1cb35c8d9cfddd7716bd0041d1d73f492af5fea118ffd729b34e0
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve the project.
4
+ title: ''
5
+ labels: bug
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ If your bug is about how AppSignal works in your app specifically we recommend you contact us at support@appsignal.com with your bug report instead.
11
+
12
+ ---
13
+
14
+ ## Describe the bug
15
+
16
+ A clear and concise description of what the bug is including the code used and the exception backtrace, if any.
17
+
18
+ ## To Reproduce
19
+
20
+ Steps to reproduce the behavior:
21
+
22
+ - Using AppSignal for Ruby gem version 2.x.x
23
+ - In my app using framework/library/gem ... version x.x.x
24
+ - With this code:
25
+ ```
26
+ Optional: Any additional AppSignal instrumentation that was added.
27
+ ```
28
+ - In this code:
29
+ ```
30
+ Your app code in which the bug occurs.
31
+ ```
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: Chore
3
+ about: Create an issue for a task that needs to be performed.
4
+ title: ''
5
+ labels: chore
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ ## TODO
11
+
12
+ - [ ] Tasks that need to be performed
13
+ - [ ] In order
14
+ - [ ] To complete the chore
@@ -61,6 +61,9 @@ Style/TrailingUnderscoreVariable:
61
61
  Style/Encoding: # For Ruby 1.9 as it doesn't default to UTF-8
62
62
  Enabled: false
63
63
 
64
+ Style/Lambda:
65
+ EnforcedStyle: lambda
66
+
64
67
  Naming/FileName:
65
68
  Exclude:
66
69
  - "ext/Rakefile"
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.9.9
4
+ - Fix error in the ActiveSupport::Notifications integration when a transaction
5
+ gets completed during event instrumentation. PR #532
6
+ - Fix Redis constant load error. PR #543
7
+ - Deprecate notify_of_deploy command. PR #545
8
+ - Always call the block given to `Appsignal.monitor_transaction` and log errors
9
+ from the helper even when AppSignal is not active. PR #547
10
+
3
11
  ## 2.9.8
4
12
  - Fix Ruby 1.9 compatibility in extension installation. PR #531
5
13
 
data/Rakefile CHANGED
@@ -5,15 +5,15 @@ require "fileutils"
5
5
  VERSION_MANAGERS = {
6
6
  :chruby => {
7
7
  :env => "#!/bin/bash\nsource /usr/local/opt/chruby/share/chruby/chruby.sh",
8
- :switch_command => ->(version) { "chruby #{version}" }
8
+ :switch_command => lambda { |version| "chruby #{version}" }
9
9
  },
10
10
  :rbenv => {
11
11
  :env => "#!/bin/bash",
12
- :switch_command => ->(version) { "rbenv local #{version}" }
12
+ :switch_command => lambda { |version| "rbenv local #{version}" }
13
13
  },
14
14
  :rvm => {
15
15
  :env => "#!/bin/bash --login",
16
- :switch_command => ->(version) { "rvm use --default #{version}" }
16
+ :switch_command => lambda { |version| "rvm use --default #{version}" }
17
17
  }
18
18
  }.freeze
19
19
 
@@ -60,6 +60,8 @@ module Appsignal
60
60
  # Terminology: Deploy marker
61
61
  class NotifyOfDeploy
62
62
  class << self
63
+ include Appsignal::Utils::DeprecationMessage
64
+
63
65
  # @param options [Hash]
64
66
  # @option options :environment [String] environment to load
65
67
  # configuration for.
@@ -85,6 +87,14 @@ module Appsignal
85
87
  },
86
88
  config
87
89
  ).transmit
90
+
91
+ puts
92
+ message = "This command (appsignal notify_of_deploy) has been " \
93
+ "deprecated in favor of the `revision` config option. Please " \
94
+ "see our documentation for more information on the recommended " \
95
+ "method: " \
96
+ "https://docs.appsignal.com/application/markers/deploy-markers.html"
97
+ deprecation_message message, Appsignal.logger
88
98
  end
89
99
 
90
100
  private
@@ -57,8 +57,9 @@ module Appsignal
57
57
  # @return [Object] the value of the given block is returned.
58
58
  # @since 0.10.0
59
59
  def monitor_transaction(name, env = {})
60
- return yield unless active?
61
-
60
+ # Always verify input, even when Appsignal is not active.
61
+ # This makes it more likely invalid arguments get flagged in test/dev
62
+ # environments.
62
63
  if name.start_with?("perform_job".freeze)
63
64
  namespace = Appsignal::Transaction::BACKGROUND_JOB
64
65
  request = Appsignal::Transaction::GenericRequest.new(env)
@@ -66,9 +67,14 @@ module Appsignal
66
67
  namespace = Appsignal::Transaction::HTTP_REQUEST
67
68
  request = ::Rack::Request.new(env)
68
69
  else
69
- logger.error("Unrecognized name '#{name}'")
70
- return
70
+ logger.error "Unrecognized name '#{name}': names must start with " \
71
+ "either 'perform_job' (for jobs and tasks) or 'process_action' " \
72
+ "(for HTTP requests)"
73
+ return yield
71
74
  end
75
+
76
+ return yield unless active?
77
+
72
78
  transaction = Appsignal::Transaction.create(
73
79
  SecureRandom.uuid,
74
80
  namespace,
@@ -37,7 +37,9 @@ module Appsignal
37
37
  install
38
38
  @installed = true
39
39
  rescue => ex
40
- Appsignal.logger.error("Error while installing #{name} hook: #{ex}")
40
+ logger = Appsignal.logger
41
+ logger.error("Error while installing #{name} hook: #{ex}")
42
+ logger.debug ex.backtrace.join("\n")
41
43
  end
42
44
  end
43
45
 
@@ -30,16 +30,13 @@ module Appsignal
30
30
  # Events that start with a bang are internal to Rails
31
31
  instrument_this = name[0] != BANG
32
32
 
33
- if instrument_this
34
- transaction = Appsignal::Transaction.current
35
- transaction.start_event
36
- end
33
+ Appsignal::Transaction.current.start_event if instrument_this
37
34
 
38
35
  instrument_without_appsignal(name, payload, &block)
39
36
  ensure
40
37
  if instrument_this
41
38
  title, body, body_format = Appsignal::EventFormatter.format(name, payload)
42
- transaction.finish_event(
39
+ Appsignal::Transaction.current.finish_event(
43
40
  name.to_s,
44
41
  title,
45
42
  body,
@@ -26,7 +26,7 @@ module Appsignal
26
26
  attr_reader :config
27
27
 
28
28
  def self.dependencies_present?
29
- Gem::Version.new(Redis::VERSION) >= Gem::Version.new("3.3.5")
29
+ Gem::Version.new(::Redis::VERSION) >= Gem::Version.new("3.3.5")
30
30
  end
31
31
 
32
32
  def initialize(config = {})
@@ -176,20 +176,28 @@ module Appsignal
176
176
 
177
177
  def initialize_probes
178
178
  probes.each do |name, probe|
179
- if probe.respond_to? :new
180
- instance = probe.new
181
- klass = probe
182
- else
183
- instance = probe
184
- klass = instance.class
185
- end
186
- unless dependencies_present?(klass)
187
- Appsignal.logger.debug "Skipping '#{name}' probe, " \
188
- "#{klass}.dependency_present? returned falsy"
189
- next
190
- end
191
- probe_instances[name] = instance
179
+ initialize_probe(name, probe)
180
+ end
181
+ end
182
+
183
+ def initialize_probe(name, probe)
184
+ if probe.respond_to? :new
185
+ instance = probe.new
186
+ klass = probe
187
+ else
188
+ instance = probe
189
+ klass = instance.class
190
+ end
191
+ unless dependencies_present?(klass)
192
+ Appsignal.logger.debug "Skipping '#{name}' probe, " \
193
+ "#{klass}.dependency_present? returned falsy"
194
+ return
192
195
  end
196
+ probe_instances[name] = instance
197
+ rescue => error
198
+ logger = Appsignal.logger
199
+ logger.error "Error while initializing minutely probe '#{name}': #{error}"
200
+ logger.debug error.backtrace.join("\n")
193
201
  end
194
202
 
195
203
  def dependencies_present?(probe)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- VERSION = "2.9.8".freeze
4
+ VERSION = "2.9.9".freeze
5
5
  end
@@ -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
 
@@ -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,41 +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
45
  it "instruments an ActiveSupport::Notifications.instrument event with no registered formatter" do
34
- expect(Appsignal::Transaction.current).to receive(:start_event)
35
- .at_least(:once)
36
- expect(Appsignal::Transaction.current).to receive(:finish_event)
37
- .at_least(:once)
38
- .with("no-registered.formatter", nil, nil, nil)
39
-
40
46
  return_value = as.instrument("no-registered.formatter", :key => "something") do
41
47
  "value"
42
48
  end
43
49
 
44
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
+ ])
45
67
  end
46
68
 
47
- it "should convert non-string names to strings" do
48
- expect(Appsignal::Transaction.current).to receive(:start_event)
49
- .at_least(:once)
50
- expect(Appsignal::Transaction.current).to receive(:finish_event)
51
- .at_least(:once)
52
- .with("not_a_string", nil, nil, nil)
53
-
69
+ it "converts non-string names to strings" do
54
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
+ ])
55
87
  end
56
88
 
57
89
  it "does not instrument events whose name starts with a bang" do
@@ -67,33 +99,66 @@ describe Appsignal::Hooks::ActiveSupportNotificationsHook do
67
99
 
68
100
  context "when an error is raised in an instrumented block" do
69
101
  it "instruments an ActiveSupport::Notifications.instrument event" do
70
- expect(Appsignal::Transaction.current).to receive(:start_event)
71
- .at_least(:once)
72
- expect(Appsignal::Transaction.current).to receive(:finish_event)
73
- .at_least(:once)
74
- .with("sql.active_record", nil, "SQL", 1)
75
-
76
102
  expect do
77
103
  as.instrument("sql.active_record", :sql => "SQL") do
78
104
  raise ExampleException, "foo"
79
105
  end
80
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
+ ])
81
124
  end
82
125
  end
83
126
 
84
127
  context "when a message is thrown in an instrumented block" do
85
128
  it "instruments an ActiveSupport::Notifications.instrument event" do
86
- expect(Appsignal::Transaction.current).to receive(:start_event)
87
- .at_least(:once)
88
- expect(Appsignal::Transaction.current).to receive(:finish_event)
89
- .at_least(:once)
90
- .with("sql.active_record", nil, "SQL", 1)
91
-
92
129
  expect do
93
130
  as.instrument("sql.active_record", :sql => "SQL") do
94
131
  throw :foo
95
132
  end
96
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([])
97
162
  end
98
163
  end
99
164
  else
@@ -68,6 +68,10 @@ describe Appsignal::Hooks do
68
68
  expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
69
69
 
70
70
  expect(Appsignal.logger).to receive(:error).with("Error while installing mock_error_hook hook: error").once
71
+ expect(Appsignal.logger).to receive(:debug).once do |message|
72
+ # Start of the error backtrace as debug log
73
+ expect(message).to start_with(File.expand_path("../../../../", __FILE__))
74
+ end
71
75
 
72
76
  Appsignal::Hooks.load_hooks
73
77
 
@@ -38,6 +38,17 @@ describe Appsignal::Minutely do
38
38
  end
39
39
  end
40
40
 
41
+ class BrokenProbeOnInitialize < Probe
42
+ def initialize
43
+ super
44
+ raise "oh no initialize!"
45
+ end
46
+
47
+ def call
48
+ true
49
+ end
50
+ end
51
+
41
52
  let(:log_stream) { StringIO.new }
42
53
  let(:log) { log_contents(log_stream) }
43
54
  before do
@@ -109,12 +120,38 @@ describe Appsignal::Minutely do
109
120
  "ProbeWithMissingDependency.dependency_present? returned falsy"
110
121
  end
111
122
  end
123
+
124
+ context "when there is a problem initializing the probe" do
125
+ it "logs an error" do
126
+ # Working probe which we can use to wait for X ticks
127
+ working_probe = ProbeWithoutDependency
128
+ working_probe_instance = working_probe.new
129
+ expect(working_probe).to receive(:new).and_return(working_probe_instance)
130
+ Appsignal::Minutely.probes.register :probe_without_dep, working_probe
131
+
132
+ probe = BrokenProbeOnInitialize
133
+ Appsignal::Minutely.probes.register :broken_probe_on_initialize, probe
134
+ Appsignal::Minutely.start
135
+
136
+ wait_for("enough probe calls") { working_probe_instance.calls >= 2 }
137
+ # Only counts initialized probes
138
+ expect(log).to contains_log(:debug, "Gathering minutely metrics with 1 probe")
139
+ # Logs error
140
+ expect(log).to contains_log(
141
+ :error,
142
+ "Error while initializing minutely probe 'broken_probe_on_initialize': " \
143
+ "oh no initialize!"
144
+ )
145
+ # Start of the error backtrace as debug log
146
+ expect(log).to contains_log :debug, File.expand_path("../../../../", __FILE__)
147
+ end
148
+ end
112
149
  end
113
150
 
114
151
  context "with a lambda" do
115
152
  it "calls the lambda every <wait time>" do
116
153
  calls = 0
117
- probe = -> { calls += 1 }
154
+ probe = lambda { calls += 1 }
118
155
  Appsignal::Minutely.probes.register :my_probe, probe
119
156
  Appsignal::Minutely.start
120
157
 
@@ -184,7 +221,7 @@ describe Appsignal::Minutely do
184
221
  end
185
222
 
186
223
  it "clears the probe instances array" do
187
- Appsignal::Minutely.probes.register :my_probe, -> {}
224
+ Appsignal::Minutely.probes.register :my_probe, lambda {}
188
225
  Appsignal::Minutely.start
189
226
  thread = Appsignal::Minutely.class_variable_get(:@@thread)
190
227
  wait_for("probes initialized") do
@@ -232,17 +269,17 @@ describe Appsignal::Minutely do
232
269
  describe "#count" do
233
270
  it "returns how many probes are registered" do
234
271
  expect(collection.count).to eql(0)
235
- collection.register :my_probe_1, -> {}
272
+ collection.register :my_probe_1, lambda {}
236
273
  expect(collection.count).to eql(1)
237
- collection.register :my_probe_2, -> {}
274
+ collection.register :my_probe_2, lambda {}
238
275
  expect(collection.count).to eql(2)
239
276
  end
240
277
  end
241
278
 
242
279
  describe "#clear" do
243
280
  it "clears the list of probes" do
244
- collection.register :my_probe_1, -> {}
245
- collection.register :my_probe_2, -> {}
281
+ collection.register :my_probe_1, lambda {}
282
+ collection.register :my_probe_2, lambda {}
246
283
  expect(collection.count).to eql(2)
247
284
  collection.clear
248
285
  expect(collection.count).to eql(0)
@@ -251,7 +288,7 @@ describe Appsignal::Minutely do
251
288
 
252
289
  describe "#[]" do
253
290
  it "returns the probe for that name" do
254
- probe = -> {}
291
+ probe = lambda {}
255
292
  collection.register :my_probe, probe
256
293
  expect(collection[:my_probe]).to eql(probe)
257
294
  end
@@ -265,7 +302,7 @@ describe Appsignal::Minutely do
265
302
  before { Appsignal.logger = test_logger(log_stream) }
266
303
 
267
304
  it "adds the probe, but prints a deprecation warning" do
268
- probe = -> {}
305
+ probe = lambda {}
269
306
  capture_stdout(out_stream) { collection << probe }
270
307
  deprecation_message = "Deprecated " \
271
308
  "`Appsignal::Minute.probes <<` call. Please use " \
@@ -282,14 +319,14 @@ describe Appsignal::Minutely do
282
319
  before { Appsignal.logger = test_logger(log_stream) }
283
320
 
284
321
  it "adds the by key probe" do
285
- probe = -> {}
322
+ probe = lambda {}
286
323
  collection.register :my_probe, probe
287
324
  expect(collection[:my_probe]).to eql(probe)
288
325
  end
289
326
 
290
327
  context "when a probe is already registered with the same key" do
291
328
  it "logs a debug message" do
292
- probe = -> {}
329
+ probe = lambda {}
293
330
  collection.register :my_probe, probe
294
331
  collection.register :my_probe, probe
295
332
  expect(log).to contains_log :debug, "A probe with the name " \
@@ -302,7 +339,7 @@ describe Appsignal::Minutely do
302
339
 
303
340
  describe "#each" do
304
341
  it "loops over the registered probes" do
305
- probe = -> {}
342
+ probe = lambda {}
306
343
  collection.register :my_probe, probe
307
344
  list = []
308
345
  collection.each do |name, p|
@@ -240,6 +240,16 @@ describe Appsignal do
240
240
 
241
241
  context "not active" do
242
242
  describe ".monitor_transaction" do
243
+ let(:log_stream) { StringIO.new }
244
+ let(:log) { log_contents(log_stream) }
245
+ before do
246
+ Appsignal.config = project_fixture_config("not_active")
247
+ Appsignal.start
248
+ Appsignal.start_logger
249
+ Appsignal.logger = test_logger(log_stream)
250
+ end
251
+ after { Appsignal.logger = nil }
252
+
243
253
  it "should do nothing but still yield the block" do
244
254
  expect(Appsignal::Transaction).to_not receive(:create)
245
255
  expect(Appsignal).to_not receive(:instrument)
@@ -252,6 +262,23 @@ describe Appsignal do
252
262
  end).to eq 1
253
263
  end.to_not raise_error
254
264
  end
265
+
266
+ context "with an unknown event type" do
267
+ it "yields the given block" do
268
+ expect do |blk|
269
+ Appsignal.monitor_transaction("unknown.sidekiq", &blk)
270
+ end.to yield_control
271
+ end
272
+
273
+ it "logs an error" do
274
+ Appsignal.monitor_transaction("unknown.sidekiq") {}
275
+ expect(log).to contains_log(
276
+ :error,
277
+ "Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
278
+ "(for jobs and tasks) or 'process_action' (for HTTP requests)"
279
+ )
280
+ end
281
+ end
255
282
  end
256
283
 
257
284
  describe ".listen_for_error" do
@@ -299,10 +326,15 @@ describe Appsignal do
299
326
  end
300
327
 
301
328
  context "with config and started" do
329
+ let(:log_stream) { StringIO.new }
330
+ let(:log) { log_contents(log_stream) }
302
331
  before do
303
332
  Appsignal.config = project_fixture_config
304
333
  Appsignal.start
334
+ Appsignal.start_logger
335
+ Appsignal.logger = test_logger(log_stream)
305
336
  end
337
+ after { Appsignal.logger = nil }
306
338
 
307
339
  describe ".monitor_transaction" do
308
340
  context "with a successful call" do
@@ -359,6 +391,23 @@ describe Appsignal do
359
391
  end.to raise_error(error)
360
392
  end
361
393
  end
394
+
395
+ context "with an unknown event type" do
396
+ it "yields the given block" do
397
+ expect do |blk|
398
+ Appsignal.monitor_transaction("unknown.sidekiq", &blk)
399
+ end.to yield_control
400
+ end
401
+
402
+ it "logs an error" do
403
+ Appsignal.monitor_transaction("unknown.sidekiq") {}
404
+ expect(log).to contains_log(
405
+ :error,
406
+ "Unrecognized name 'unknown.sidekiq': names must start with either 'perform_job' " \
407
+ "(for jobs and tasks) or 'process_action' (for HTTP requests)"
408
+ )
409
+ end
410
+ end
362
411
  end
363
412
 
364
413
  describe ".monitor_single_transaction" do
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.9.8
4
+ version: 2.9.9
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: 2019-06-03 00:00:00.000000000 Z
12
+ date: 2019-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -132,6 +132,8 @@ extensions:
132
132
  - ext/extconf.rb
133
133
  extra_rdoc_files: []
134
134
  files:
135
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
136
+ - ".github/ISSUE_TEMPLATE/chore.md"
135
137
  - ".gitignore"
136
138
  - ".rspec"
137
139
  - ".rubocop.yml"