appsignal 2.11.8-java → 3.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -1
- data/.rubocop_todo.yml +1 -1
- data/.semaphore/semaphore.yml +88 -111
- data/CHANGELOG.md +24 -0
- data/appsignal.gemspec +1 -1
- data/build_matrix.yml +11 -15
- data/lib/appsignal.rb +2 -29
- data/lib/appsignal/auth_check.rb +2 -8
- data/lib/appsignal/cli.rb +1 -23
- data/lib/appsignal/config.rb +1 -25
- data/lib/appsignal/event_formatter.rb +0 -25
- data/lib/appsignal/helpers/instrumentation.rb +69 -5
- data/lib/appsignal/hooks.rb +6 -13
- data/lib/appsignal/hooks/action_cable.rb +3 -34
- data/lib/appsignal/hooks/active_support_notifications.rb +7 -86
- data/lib/appsignal/hooks/celluloid.rb +5 -9
- data/lib/appsignal/hooks/net_http.rb +2 -12
- data/lib/appsignal/hooks/puma.rb +3 -5
- data/lib/appsignal/hooks/que.rb +1 -1
- data/lib/appsignal/hooks/rake.rb +2 -24
- data/lib/appsignal/hooks/redis.rb +2 -13
- data/lib/appsignal/hooks/resque.rb +2 -43
- data/lib/appsignal/hooks/sidekiq.rb +6 -143
- data/lib/appsignal/hooks/unicorn.rb +3 -24
- data/lib/appsignal/hooks/webmachine.rb +1 -7
- data/lib/appsignal/integrations/action_cable.rb +34 -0
- data/lib/appsignal/integrations/active_support_notifications.rb +77 -0
- data/lib/appsignal/integrations/net_http.rb +16 -0
- data/lib/appsignal/integrations/object.rb +39 -4
- data/lib/appsignal/integrations/padrino.rb +5 -7
- data/lib/appsignal/integrations/que.rb +26 -33
- data/lib/appsignal/integrations/railtie.rb +1 -4
- data/lib/appsignal/integrations/rake.rb +26 -2
- data/lib/appsignal/integrations/redis.rb +17 -0
- data/lib/appsignal/integrations/resque.rb +39 -10
- data/lib/appsignal/integrations/sidekiq.rb +171 -0
- data/lib/appsignal/integrations/unicorn.rb +28 -0
- data/lib/appsignal/integrations/webmachine.rb +22 -24
- data/lib/appsignal/minutely.rb +0 -12
- data/lib/appsignal/version.rb +1 -1
- data/spec/lib/appsignal/auth_check_spec.rb +1 -24
- data/spec/lib/appsignal/cli_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +2 -66
- data/spec/lib/appsignal/event_formatter_spec.rb +0 -37
- data/spec/lib/appsignal/hooks/celluloid_spec.rb +6 -1
- data/spec/lib/appsignal/hooks/rake_spec.rb +1 -2
- data/spec/lib/appsignal/hooks/redis_spec.rb +50 -15
- data/spec/lib/appsignal/hooks/sidekiq_spec.rb +12 -464
- data/spec/lib/appsignal/hooks/unicorn_spec.rb +14 -3
- data/spec/lib/appsignal/hooks/webmachine_spec.rb +2 -13
- data/spec/lib/appsignal/hooks_spec.rb +6 -22
- data/spec/lib/appsignal/integrations/object_spec.rb +91 -8
- data/spec/lib/appsignal/integrations/padrino_spec.rb +2 -3
- data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -45
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +524 -0
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +26 -8
- data/spec/lib/appsignal/minutely_spec.rb +0 -19
- data/spec/lib/appsignal/transaction_spec.rb +1 -14
- data/spec/lib/appsignal/transmitter_spec.rb +1 -1
- data/spec/lib/appsignal_spec.rb +162 -116
- data/spec/spec_helper.rb +1 -15
- metadata +11 -21
- data/lib/appsignal/cli/notify_of_deploy.rb +0 -131
- data/lib/appsignal/integrations/object_ruby_19.rb +0 -37
- data/lib/appsignal/integrations/object_ruby_modern.rb +0 -64
- data/lib/appsignal/integrations/resque_active_job.rb +0 -19
- data/lib/appsignal/js_exception_transaction.rb +0 -56
- data/lib/appsignal/rack/js_exception_catcher.rb +0 -80
- data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +0 -180
- data/spec/lib/appsignal/integrations/object_19_spec.rb +0 -266
- data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +0 -28
- data/spec/lib/appsignal/integrations/resque_spec.rb +0 -28
- data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -128
- data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +0 -170
@@ -0,0 +1,171 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "yaml"
|
4
|
+
|
5
|
+
module Appsignal
|
6
|
+
module Integrations
|
7
|
+
# Error handler for Sidekiq to report errors from jobs and internal Sidekiq
|
8
|
+
# errors.
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class SidekiqErrorHandler
|
12
|
+
def call(exception, sidekiq_context)
|
13
|
+
transaction = Appsignal::Transaction.current
|
14
|
+
|
15
|
+
if transaction.nil_transaction?
|
16
|
+
# Sidekiq error outside of the middleware scope.
|
17
|
+
# Can be a job JSON parse error or some other error happening in
|
18
|
+
# Sidekiq.
|
19
|
+
transaction = Appsignal::Transaction.create(
|
20
|
+
SecureRandom.uuid, # Newly generated job id
|
21
|
+
Appsignal::Transaction::BACKGROUND_JOB,
|
22
|
+
Appsignal::Transaction::GenericRequest.new({})
|
23
|
+
)
|
24
|
+
transaction.set_action_if_nil("SidekiqInternal")
|
25
|
+
transaction.set_metadata("sidekiq_error", sidekiq_context[:context])
|
26
|
+
transaction.params = { :jobstr => sidekiq_context[:jobstr] }
|
27
|
+
end
|
28
|
+
|
29
|
+
transaction.set_error(exception)
|
30
|
+
Appsignal::Transaction.complete_current!
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @api private
|
35
|
+
class SidekiqMiddleware # rubocop:disable Metrics/ClassLength
|
36
|
+
include Appsignal::Hooks::Helpers
|
37
|
+
|
38
|
+
EXCLUDED_JOB_KEYS = %w[
|
39
|
+
args backtrace class created_at enqueued_at error_backtrace error_class
|
40
|
+
error_message failed_at jid retried_at retry wrapped
|
41
|
+
].freeze
|
42
|
+
|
43
|
+
def call(_worker, item, _queue)
|
44
|
+
job_status = nil
|
45
|
+
transaction = Appsignal::Transaction.create(
|
46
|
+
item["jid"],
|
47
|
+
Appsignal::Transaction::BACKGROUND_JOB,
|
48
|
+
Appsignal::Transaction::GenericRequest.new(
|
49
|
+
:queue_start => item["enqueued_at"]
|
50
|
+
)
|
51
|
+
)
|
52
|
+
|
53
|
+
Appsignal.instrument "perform_job.sidekiq" do
|
54
|
+
yield
|
55
|
+
end
|
56
|
+
rescue Exception => exception # rubocop:disable Lint/RescueException
|
57
|
+
job_status = :failed
|
58
|
+
raise exception
|
59
|
+
ensure
|
60
|
+
if transaction
|
61
|
+
transaction.set_action_if_nil(formatted_action_name(item))
|
62
|
+
|
63
|
+
params = filtered_arguments(item)
|
64
|
+
transaction.params = params if params
|
65
|
+
|
66
|
+
formatted_metadata(item).each do |key, value|
|
67
|
+
transaction.set_metadata key, value
|
68
|
+
end
|
69
|
+
transaction.set_http_or_background_queue_start
|
70
|
+
Appsignal::Transaction.complete_current! unless exception
|
71
|
+
|
72
|
+
queue = item["queue"] || "unknown"
|
73
|
+
if job_status
|
74
|
+
increment_counter "queue_job_count", 1,
|
75
|
+
:queue => queue,
|
76
|
+
:status => job_status
|
77
|
+
end
|
78
|
+
increment_counter "queue_job_count", 1,
|
79
|
+
:queue => queue,
|
80
|
+
:status => :processed
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def increment_counter(key, value, tags = {})
|
87
|
+
Appsignal.increment_counter "sidekiq_#{key}", value, tags
|
88
|
+
end
|
89
|
+
|
90
|
+
def formatted_action_name(job)
|
91
|
+
sidekiq_action_name = parse_action_name(job)
|
92
|
+
return unless sidekiq_action_name
|
93
|
+
|
94
|
+
complete_action = sidekiq_action_name =~ /\.|#/
|
95
|
+
return sidekiq_action_name if complete_action
|
96
|
+
|
97
|
+
"#{sidekiq_action_name}#perform"
|
98
|
+
end
|
99
|
+
|
100
|
+
def filtered_arguments(job)
|
101
|
+
arguments = parse_arguments(job)
|
102
|
+
return unless arguments
|
103
|
+
|
104
|
+
Appsignal::Utils::HashSanitizer.sanitize(
|
105
|
+
arguments,
|
106
|
+
Appsignal.config[:filter_parameters]
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
def formatted_metadata(item)
|
111
|
+
{}.tap do |hash|
|
112
|
+
(item || {}).each do |key, value|
|
113
|
+
next if EXCLUDED_JOB_KEYS.include?(key)
|
114
|
+
|
115
|
+
hash[key] = truncate(string_or_inspect(value))
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Based on: https://github.com/mperham/sidekiq/blob/63ee43353bd3b753beb0233f64865e658abeb1c3/lib/sidekiq/api.rb#L316-L334
|
121
|
+
def parse_action_name(job)
|
122
|
+
args = job.fetch("args", [])
|
123
|
+
job_class = job["class"]
|
124
|
+
case job_class
|
125
|
+
when "Sidekiq::Extensions::DelayedModel"
|
126
|
+
safe_load(args[0], job_class) do |target, method, _|
|
127
|
+
"#{target.class}##{method}"
|
128
|
+
end
|
129
|
+
when /\ASidekiq::Extensions::Delayed/
|
130
|
+
safe_load(args[0], job_class) do |target, method, _|
|
131
|
+
"#{target}.#{method}"
|
132
|
+
end
|
133
|
+
else
|
134
|
+
job_class
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Based on: https://github.com/mperham/sidekiq/blob/63ee43353bd3b753beb0233f64865e658abeb1c3/lib/sidekiq/api.rb#L336-L358
|
139
|
+
def parse_arguments(job)
|
140
|
+
args = job.fetch("args", [])
|
141
|
+
case job["class"]
|
142
|
+
when /\ASidekiq::Extensions::Delayed/
|
143
|
+
safe_load(args[0], args) do |_, _, arg|
|
144
|
+
arg
|
145
|
+
end
|
146
|
+
when "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
147
|
+
nil # Set in the ActiveJob integration
|
148
|
+
else
|
149
|
+
# Sidekiq Enterprise argument encryption.
|
150
|
+
# More information: https://github.com/mperham/sidekiq/wiki/Ent-Encryption
|
151
|
+
if job["encrypt".freeze]
|
152
|
+
# No point in showing 150+ bytes of random garbage
|
153
|
+
args[-1] = "[encrypted data]".freeze
|
154
|
+
end
|
155
|
+
args
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Based on: https://github.com/mperham/sidekiq/blob/63ee43353bd3b753beb0233f64865e658abeb1c3/lib/sidekiq/api.rb#L403-L412
|
160
|
+
def safe_load(content, default)
|
161
|
+
yield(*YAML.load(content))
|
162
|
+
rescue => error
|
163
|
+
# Sidekiq issue #1761: in dev mode, it's possible to have jobs enqueued
|
164
|
+
# which haven't been loaded into memory yet so the YAML can't be
|
165
|
+
# loaded.
|
166
|
+
Appsignal.logger.warn "Unable to load YAML: #{error.message}"
|
167
|
+
default
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appsignal
|
4
|
+
module Integrations
|
5
|
+
module UnicornIntegration
|
6
|
+
# Make sure that appsignal is started and the last transaction
|
7
|
+
# in a worker gets flushed.
|
8
|
+
#
|
9
|
+
# We'd love to be able to hook this into Unicorn in a less
|
10
|
+
# intrusive way, but this is the best we can do given the
|
11
|
+
# options we have.
|
12
|
+
|
13
|
+
module Server
|
14
|
+
def worker_loop(worker)
|
15
|
+
Appsignal.forked
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Worker
|
21
|
+
def close
|
22
|
+
Appsignal.stop("unicorn")
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -3,35 +3,33 @@
|
|
3
3
|
module Appsignal
|
4
4
|
module Integrations
|
5
5
|
# @api private
|
6
|
-
module
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
)
|
6
|
+
module WebmachineIntegration
|
7
|
+
def run
|
8
|
+
transaction = Appsignal::Transaction.create(
|
9
|
+
SecureRandom.uuid,
|
10
|
+
Appsignal::Transaction::HTTP_REQUEST,
|
11
|
+
request,
|
12
|
+
:params_method => :query
|
13
|
+
)
|
15
14
|
|
16
|
-
|
15
|
+
transaction.set_action_if_nil("#{resource.class.name}##{request.method}")
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
Appsignal::Transaction.complete_current!
|
17
|
+
Appsignal.instrument("process_action.webmachine") do
|
18
|
+
super
|
23
19
|
end
|
24
20
|
|
25
|
-
|
21
|
+
Appsignal::Transaction.complete_current!
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
26
|
+
def handle_exceptions
|
27
|
+
super do
|
28
|
+
begin
|
29
|
+
yield
|
30
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
31
|
+
Appsignal.set_error(e)
|
32
|
+
raise e
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
data/lib/appsignal/minutely.rb
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
module Appsignal
|
4
4
|
class Minutely
|
5
5
|
class ProbeCollection
|
6
|
-
include Appsignal::Utils::DeprecationMessage
|
7
|
-
|
8
6
|
def initialize
|
9
7
|
@probes = {}
|
10
8
|
end
|
@@ -27,16 +25,6 @@ module Appsignal
|
|
27
25
|
probes[key]
|
28
26
|
end
|
29
27
|
|
30
|
-
# @param probe [Object] Any object that listens to the `call` method will
|
31
|
-
# be used as a probe.
|
32
|
-
# @deprecated Use {#register} instead.
|
33
|
-
# @return [void]
|
34
|
-
def <<(probe)
|
35
|
-
deprecation_message "Deprecated `Appsignal::Minute.probes <<` " \
|
36
|
-
"call. Please use `Appsignal::Minutely.probes.register` instead."
|
37
|
-
register probe.object_id, probe
|
38
|
-
end
|
39
|
-
|
40
28
|
# Register a new minutely probe.
|
41
29
|
#
|
42
30
|
# Supported probe types are:
|
data/lib/appsignal/version.rb
CHANGED
@@ -28,29 +28,6 @@ describe Appsignal::AuthCheck do
|
|
28
28
|
end.join("&")
|
29
29
|
end
|
30
30
|
|
31
|
-
describe ".new" do
|
32
|
-
describe "with logger argument" do
|
33
|
-
let(:err_stream) { std_stream }
|
34
|
-
let(:stderr) { err_stream.read }
|
35
|
-
let(:log_stream) { std_stream }
|
36
|
-
let(:log) { log_contents(log_stream) }
|
37
|
-
|
38
|
-
it "logs and prints a deprecation message" do
|
39
|
-
Appsignal.logger = test_logger(log_stream)
|
40
|
-
|
41
|
-
capture_std_streams(std_stream, err_stream) do
|
42
|
-
Appsignal::AuthCheck.new(config, Appsignal.logger)
|
43
|
-
end
|
44
|
-
|
45
|
-
deprecation_message =
|
46
|
-
"`Appsignal::AuthCheck.new`'s `logger` argument " \
|
47
|
-
"will be removed in the next major version."
|
48
|
-
expect(stderr).to include "appsignal WARNING: #{deprecation_message}"
|
49
|
-
expect(log).to contains_log :warn, deprecation_message
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
31
|
describe "#perform" do
|
55
32
|
subject { auth_check.perform }
|
56
33
|
|
@@ -62,7 +39,7 @@ describe Appsignal::AuthCheck do
|
|
62
39
|
end
|
63
40
|
end
|
64
41
|
|
65
|
-
context "when encountering an exception"
|
42
|
+
context "when encountering an exception" do
|
66
43
|
before { stubbed_request.to_timeout }
|
67
44
|
|
68
45
|
it "raises an error" do
|
@@ -168,8 +168,6 @@ describe Appsignal::Config do
|
|
168
168
|
:push_api_key => "abc",
|
169
169
|
:name => "TestApp",
|
170
170
|
:active => true,
|
171
|
-
:enable_frontend_error_catching => false,
|
172
|
-
:frontend_error_catching_path => "/appsignal_error_catcher",
|
173
171
|
:enable_allocation_tracking => true,
|
174
172
|
:enable_gc_instrumentation => false,
|
175
173
|
:enable_host_metrics => true,
|
@@ -357,70 +355,6 @@ describe Appsignal::Config do
|
|
357
355
|
config
|
358
356
|
end
|
359
357
|
end
|
360
|
-
|
361
|
-
describe "support for old config keys" do
|
362
|
-
let(:err_stream) { std_stream }
|
363
|
-
let(:stderr) { err_stream.read }
|
364
|
-
let(:config) { project_fixture_config(env, {}, test_logger(log)) }
|
365
|
-
let(:log) { StringIO.new }
|
366
|
-
before { capture_std_streams(std_stream, err_stream) { config } }
|
367
|
-
|
368
|
-
describe ":api_key" do
|
369
|
-
context "without :push_api_key" do
|
370
|
-
let(:env) { "old_config" }
|
371
|
-
|
372
|
-
it "sets the :push_api_key with the old :api_key value" do
|
373
|
-
expect(config[:push_api_key]).to eq "def"
|
374
|
-
expect(config.config_hash).to_not have_key :api_key
|
375
|
-
|
376
|
-
message = "Old configuration key found. Please update the 'api_key' to 'push_api_key'"
|
377
|
-
expect(stderr).to include "appsignal WARNING: #{message}"
|
378
|
-
expect(log_contents(log)).to contains_log :warn, message
|
379
|
-
end
|
380
|
-
end
|
381
|
-
|
382
|
-
context "with :push_api_key" do
|
383
|
-
let(:env) { "old_config_mixed_with_new_config" }
|
384
|
-
|
385
|
-
it "ignores the :api_key config and deletes it" do
|
386
|
-
expect(config[:push_api_key]).to eq "ghi"
|
387
|
-
expect(config.config_hash).to_not have_key :api_key
|
388
|
-
|
389
|
-
message = "Old configuration key found. Please update the 'api_key' to 'push_api_key'"
|
390
|
-
expect(stderr).to include "appsignal WARNING: #{message}"
|
391
|
-
expect(log_contents(log)).to contains_log :warn, message
|
392
|
-
end
|
393
|
-
end
|
394
|
-
end
|
395
|
-
|
396
|
-
describe ":ignore_exceptions" do
|
397
|
-
context "without :ignore_errors" do
|
398
|
-
let(:env) { "old_config" }
|
399
|
-
|
400
|
-
it "sets :ignore_errors with the old :ignore_exceptions value" do
|
401
|
-
expect(config[:ignore_errors]).to eq ["StandardError"]
|
402
|
-
expect(config.config_hash).to_not have_key :ignore_exceptions
|
403
|
-
|
404
|
-
message = "Old configuration key found. Please update the 'ignore_exceptions' to 'ignore_errors'"
|
405
|
-
expect(stderr).to include "appsignal WARNING: #{message}"
|
406
|
-
expect(log_contents(log)).to contains_log :warn, message
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
context "with :ignore_errors" do
|
411
|
-
let(:env) { "old_config_mixed_with_new_config" }
|
412
|
-
|
413
|
-
it "ignores the :ignore_exceptions config" do
|
414
|
-
expect(config[:ignore_errors]).to eq ["NoMethodError"]
|
415
|
-
expect(config.config_hash).to_not have_key :ignore_exceptions
|
416
|
-
|
417
|
-
message = "Old configuration key found. Please update the 'ignore_exceptions' to 'ignore_errors'"
|
418
|
-
expect(stderr).to include "appsignal WARNING: #{message}"
|
419
|
-
expect(log_contents(log)).to contains_log :warn, message
|
420
|
-
end
|
421
|
-
end
|
422
|
-
end
|
423
|
-
end
|
424
358
|
end
|
425
359
|
|
426
360
|
context "with config in the environment" do
|
@@ -440,6 +374,7 @@ describe Appsignal::Config do
|
|
440
374
|
:active => true,
|
441
375
|
:name => "App name",
|
442
376
|
:debug => true,
|
377
|
+
:dns_servers => ["8.8.8.8", "8.8.4.4"],
|
443
378
|
:ignore_actions => %w[action1 action2],
|
444
379
|
:ignore_errors => %w[ExampleStandardError AnotherError],
|
445
380
|
:ignore_namespaces => %w[admin private_namespace],
|
@@ -459,6 +394,7 @@ describe Appsignal::Config do
|
|
459
394
|
ENV["APPSIGNAL_ACTIVE"] = "true"
|
460
395
|
ENV["APPSIGNAL_APP_NAME"] = "App name"
|
461
396
|
ENV["APPSIGNAL_DEBUG"] = "true"
|
397
|
+
ENV["APPSIGNAL_DNS_SERVERS"] = "8.8.8.8,8.8.4.4"
|
462
398
|
ENV["APPSIGNAL_IGNORE_ACTIONS"] = "action1,action2"
|
463
399
|
ENV["APPSIGNAL_IGNORE_ERRORS"] = "ExampleStandardError,AnotherError"
|
464
400
|
ENV["APPSIGNAL_IGNORE_NAMESPACES"] = "admin,private_namespace"
|
@@ -114,43 +114,6 @@ describe Appsignal::EventFormatter do
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
117
|
-
|
118
|
-
context "when registering deprecated formatters" do
|
119
|
-
let(:err_stream) { std_stream }
|
120
|
-
let(:stderr) { err_stream.read }
|
121
|
-
let(:deprecated_formatter) do
|
122
|
-
Class.new(Appsignal::EventFormatter) do
|
123
|
-
register "mock.deprecated"
|
124
|
-
|
125
|
-
def format(_payload)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
it "registers deprecated formatters and logs & prints a warning" do
|
131
|
-
message = "Formatter for 'mock.deprecated' is using a deprecated registration method. " \
|
132
|
-
"This event formatter will not be loaded. " \
|
133
|
-
"Please update the formatter according to the documentation at: " \
|
134
|
-
"https://docs.appsignal.com/ruby/instrumentation/event-formatters.html"
|
135
|
-
|
136
|
-
logs = capture_logs do
|
137
|
-
capture_std_streams(std_stream, err_stream) { deprecated_formatter }
|
138
|
-
end
|
139
|
-
expect(logs).to contains_log :warn, message
|
140
|
-
expect(stderr).to include "appsignal WARNING: #{message}"
|
141
|
-
|
142
|
-
expect(klass.deprecated_formatter_classes.keys).to include("mock.deprecated")
|
143
|
-
end
|
144
|
-
|
145
|
-
it "initializes deprecated formatters" do
|
146
|
-
capture_std_streams(std_stream, err_stream) { deprecated_formatter }
|
147
|
-
klass.initialize_deprecated_formatters
|
148
|
-
|
149
|
-
expect(klass.registered?("mock.deprecated")).to be_truthy
|
150
|
-
expect(klass.formatters["mock.deprecated"]).to be_instance_of(deprecated_formatter)
|
151
|
-
expect(klass.deprecated_formatter_classes["mock.deprecated"]).to eq(deprecated_formatter)
|
152
|
-
end
|
153
|
-
end
|
154
117
|
end
|
155
118
|
|
156
119
|
describe ".registered?" do
|