appsignal 3.5.4-java → 3.5.6-java

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.semaphore/semaphore.yml +147 -9
  3. data/CHANGELOG.md +23 -0
  4. data/README.md +2 -0
  5. data/build_matrix.yml +5 -9
  6. data/ext/Rakefile +7 -1
  7. data/ext/agent.rb +27 -27
  8. data/gemfiles/redis-4.gemfile +5 -0
  9. data/gemfiles/redis-5.gemfile +6 -0
  10. data/lib/appsignal/cli/diagnose.rb +1 -1
  11. data/lib/appsignal/config.rb +10 -5
  12. data/lib/appsignal/demo.rb +1 -1
  13. data/lib/appsignal/environment.rb +24 -13
  14. data/lib/appsignal/event_formatter.rb +1 -1
  15. data/lib/appsignal/extension/jruby.rb +4 -3
  16. data/lib/appsignal/extension.rb +1 -1
  17. data/lib/appsignal/helpers/instrumentation.rb +7 -7
  18. data/lib/appsignal/helpers/metrics.rb +3 -3
  19. data/lib/appsignal/hooks/redis.rb +1 -0
  20. data/lib/appsignal/hooks/redis_client.rb +27 -0
  21. data/lib/appsignal/hooks.rb +3 -2
  22. data/lib/appsignal/integrations/hanami.rb +1 -1
  23. data/lib/appsignal/integrations/padrino.rb +1 -1
  24. data/lib/appsignal/integrations/railtie.rb +1 -1
  25. data/lib/appsignal/integrations/redis_client.rb +20 -0
  26. data/lib/appsignal/integrations/sidekiq.rb +1 -1
  27. data/lib/appsignal/integrations/sinatra.rb +1 -1
  28. data/lib/appsignal/minutely.rb +4 -4
  29. data/lib/appsignal/probes/gvl.rb +1 -1
  30. data/lib/appsignal/probes/helpers.rb +1 -1
  31. data/lib/appsignal/probes/mri.rb +1 -1
  32. data/lib/appsignal/probes/sidekiq.rb +5 -5
  33. data/lib/appsignal/rack/generic_instrumentation.rb +1 -1
  34. data/lib/appsignal/rack/rails_instrumentation.rb +2 -2
  35. data/lib/appsignal/rack/sinatra_instrumentation.rb +2 -2
  36. data/lib/appsignal/rack/streaming_listener.rb +1 -1
  37. data/lib/appsignal/span.rb +2 -2
  38. data/lib/appsignal/transaction.rb +11 -11
  39. data/lib/appsignal/utils/deprecation_message.rb +2 -2
  40. data/lib/appsignal/version.rb +1 -1
  41. data/lib/appsignal.rb +37 -31
  42. data/spec/lib/appsignal/config_spec.rb +2 -2
  43. data/spec/lib/appsignal/hooks/activejob_spec.rb +1 -1
  44. data/spec/lib/appsignal/hooks/redis_client_spec.rb +222 -0
  45. data/spec/lib/appsignal/hooks/redis_spec.rb +98 -76
  46. data/spec/lib/appsignal/hooks_spec.rb +4 -4
  47. data/spec/lib/appsignal/integrations/railtie_spec.rb +2 -2
  48. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +3 -3
  49. data/spec/lib/appsignal/integrations/sinatra_spec.rb +2 -2
  50. data/spec/lib/appsignal/minutely_spec.rb +2 -2
  51. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +1 -1
  52. data/spec/lib/appsignal/transaction_spec.rb +4 -4
  53. data/spec/lib/appsignal_spec.rb +34 -32
  54. data/spec/spec_helper.rb +1 -1
  55. data/spec/support/fixtures/projects/valid/config/appsignal.yml +3 -3
  56. data/spec/support/helpers/config_helpers.rb +6 -2
  57. data/spec/support/helpers/dependency_helper.rb +9 -1
  58. data/spec/support/helpers/log_helpers.rb +2 -2
  59. metadata +8 -3
data/lib/appsignal.rb CHANGED
@@ -46,7 +46,11 @@ module Appsignal
46
46
  # @see extension_loaded?
47
47
  attr_accessor :extension_loaded
48
48
  # @!attribute [rw] logger
49
- # Accessor for the AppSignal logger.
49
+ # Accessor for the internal AppSignal logger.
50
+ #
51
+ # Not to be confused with our logging feature.
52
+ # This is part of our private internal API. Do not call this method
53
+ # directly.
50
54
  #
51
55
  # If no logger has been set, it will return a "in memory logger", using
52
56
  # `in_memory_log`. Once AppSignal is started (using {.start}) the
@@ -57,7 +61,7 @@ module Appsignal
57
61
  # @api private
58
62
  # @return [Logger]
59
63
  # @see start_logger
60
- attr_writer :logger
64
+ attr_writer :internal_logger
61
65
 
62
66
  # @api private
63
67
  def testing?
@@ -91,11 +95,11 @@ module Appsignal
91
95
  # @since 0.7.0
92
96
  def start
93
97
  unless extension_loaded?
94
- logger.info("Not starting appsignal, extension is not loaded")
98
+ internal_logger.info("Not starting appsignal, extension is not loaded")
95
99
  return
96
100
  end
97
101
 
98
- logger.debug("Starting appsignal")
102
+ internal_logger.debug("Starting appsignal")
99
103
 
100
104
  @config ||= Config.new(
101
105
  Dir.pwd,
@@ -103,9 +107,9 @@ module Appsignal
103
107
  )
104
108
 
105
109
  if config.valid?
106
- logger.level = config.log_level
110
+ internal_logger.level = config.log_level
107
111
  if config.active?
108
- logger.info "Starting AppSignal #{Appsignal::VERSION} " \
112
+ internal_logger.info "Starting AppSignal #{Appsignal::VERSION} " \
109
113
  "(#{$PROGRAM_NAME}, Ruby #{RUBY_VERSION}, #{RUBY_PLATFORM})"
110
114
  config.write_to_environment
111
115
  Appsignal::Extension.start
@@ -120,10 +124,10 @@ module Appsignal
120
124
 
121
125
  collect_environment_metadata
122
126
  else
123
- logger.info("Not starting, not active for #{config.env}")
127
+ internal_logger.info("Not starting, not active for #{config.env}")
124
128
  end
125
129
  else
126
- logger.error("Not starting, no valid config for this environment")
130
+ internal_logger.error("Not starting, no valid config for this environment")
127
131
  end
128
132
  end
129
133
 
@@ -143,9 +147,9 @@ module Appsignal
143
147
  # @since 1.0.0
144
148
  def stop(called_by = nil)
145
149
  if called_by
146
- logger.debug("Stopping appsignal (#{called_by})")
150
+ internal_logger.debug("Stopping appsignal (#{called_by})")
147
151
  else
148
- logger.debug("Stopping appsignal")
152
+ internal_logger.debug("Stopping appsignal")
149
153
  end
150
154
  Appsignal::Extension.stop
151
155
  end
@@ -154,7 +158,7 @@ module Appsignal
154
158
  return unless active?
155
159
 
156
160
  Appsignal.start_logger
157
- logger.debug("Forked process, resubscribing and restarting extension")
161
+ internal_logger.debug("Forked process, resubscribing and restarting extension")
158
162
  Appsignal::Extension.start
159
163
  end
160
164
 
@@ -162,7 +166,8 @@ module Appsignal
162
166
  Appsignal::Extension.get_server_state(key)
163
167
  end
164
168
 
165
- # In memory logger used before any logger is started with {.start_logger}.
169
+ # In memory internal logger used before any internal logger is started with
170
+ # {.start_logger}.
166
171
  #
167
172
  # The contents of this logger are flushed to the logger in {.start_logger}.
168
173
  #
@@ -176,11 +181,12 @@ module Appsignal
176
181
  end
177
182
  end
178
183
 
179
- def logger
180
- @logger ||= Appsignal::Utils::IntegrationLogger.new(in_memory_log).tap do |l|
181
- l.level = ::Logger::INFO
182
- l.formatter = log_formatter("appsignal")
183
- end
184
+ def internal_logger
185
+ @internal_logger ||=
186
+ Appsignal::Utils::IntegrationLogger.new(in_memory_log).tap do |l|
187
+ l.level = ::Logger::INFO
188
+ l.formatter = log_formatter("appsignal")
189
+ end
184
190
  end
185
191
 
186
192
  # @api private
@@ -192,7 +198,7 @@ module Appsignal
192
198
  end
193
199
  end
194
200
 
195
- # Start the AppSignal logger.
201
+ # Start the AppSignal internal logger.
196
202
  #
197
203
  # Sets the log level and sets the logger. Uses a file-based logger or the
198
204
  # STDOUT-based logger. See the `:log` configuration option.
@@ -201,18 +207,18 @@ module Appsignal
201
207
  # @since 0.7.0
202
208
  def start_logger
203
209
  if config && config[:log] == "file" && config.log_file_path
204
- start_file_logger(config.log_file_path)
210
+ start_internal_file_logger(config.log_file_path)
205
211
  else
206
- start_stdout_logger
212
+ start_internal_stdout_logger
207
213
  end
208
214
 
209
- logger.level =
215
+ internal_logger.level =
210
216
  if config
211
217
  config.log_level
212
218
  else
213
219
  Appsignal::Config::DEFAULT_LOG_LEVEL
214
220
  end
215
- logger << @in_memory_log.string if @in_memory_log
221
+ internal_logger << @in_memory_log.string if @in_memory_log
216
222
  end
217
223
 
218
224
  # Returns if the C-extension was loaded properly.
@@ -255,18 +261,18 @@ module Appsignal
255
261
 
256
262
  private
257
263
 
258
- def start_stdout_logger
259
- @logger = Appsignal::Utils::IntegrationLogger.new($stdout)
260
- logger.formatter = log_formatter("appsignal")
264
+ def start_internal_stdout_logger
265
+ @internal_logger = Appsignal::Utils::IntegrationLogger.new($stdout)
266
+ internal_logger.formatter = log_formatter("appsignal")
261
267
  end
262
268
 
263
- def start_file_logger(path)
264
- @logger = Appsignal::Utils::IntegrationLogger.new(path)
265
- logger.formatter = log_formatter
269
+ def start_internal_file_logger(path)
270
+ @internal_logger = Appsignal::Utils::IntegrationLogger.new(path)
271
+ internal_logger.formatter = log_formatter
266
272
  rescue SystemCallError => error
267
- start_stdout_logger
268
- logger.warn "Unable to start logger with log path '#{path}'."
269
- logger.warn error
273
+ start_internal_stdout_logger
274
+ internal_logger.warn "Unable to start internal logger with log path '#{path}'."
275
+ internal_logger.warn error
270
276
  end
271
277
 
272
278
  def collect_environment_metadata
@@ -265,7 +265,7 @@ describe Appsignal::Config do
265
265
 
266
266
  context "with an overriden config file" do
267
267
  let(:config) do
268
- project_fixture_config("production", {}, Appsignal.logger,
268
+ project_fixture_config("production", {}, Appsignal.internal_logger,
269
269
  File.join(project_fixture_path, "config", "appsignal.yml"))
270
270
  end
271
271
 
@@ -276,7 +276,7 @@ describe Appsignal::Config do
276
276
 
277
277
  context "with an invalid overriden config file" do
278
278
  let(:config) do
279
- project_fixture_config("production", {}, Appsignal.logger,
279
+ project_fixture_config("production", {}, Appsignal.internal_logger,
280
280
  File.join(project_fixture_path, "config", "missing.yml"))
281
281
  end
282
282
 
@@ -76,7 +76,7 @@ if DependencyHelper.active_job_present?
76
76
  ActiveJob::Base.queue_adapter = :inline
77
77
 
78
78
  start_agent
79
- Appsignal.logger = test_logger(log)
79
+ Appsignal.internal_logger = test_logger(log)
80
80
  class ActiveJobTestJob < ActiveJob::Base
81
81
  def perform(*_args)
82
82
  end
@@ -0,0 +1,222 @@
1
+ describe Appsignal::Hooks::RedisClientHook do
2
+ before do
3
+ Appsignal.config = project_fixture_config
4
+ end
5
+
6
+ if DependencyHelper.redis_client_present?
7
+ context "with redis_client" do
8
+ context "with instrumentation enabled" do
9
+ describe "#dependencies_present?" do
10
+ subject { described_class.new.dependencies_present? }
11
+
12
+ it { is_expected.to be_truthy }
13
+ end
14
+
15
+ context "with rest-client gem" do
16
+ describe "integration" do
17
+ before do
18
+ Appsignal.config.config_hash[:instrument_redis] = true
19
+ end
20
+
21
+ context "install" do
22
+ before do
23
+ Appsignal::Hooks.load_hooks
24
+ end
25
+
26
+ it "includes the integration for the ruby connection" do
27
+ # Test if the last included module (prepended module) was our
28
+ # integration. That's not certain with the assertions below
29
+ # because we have to overwrite the `process` method for the test.
30
+ expect(RedisClient::RubyConnection.included_modules.first)
31
+ .to eql(Appsignal::Integrations::RedisClientIntegration)
32
+ end
33
+ end
34
+
35
+ context "requirements" do
36
+ it "driver should have the write method" do
37
+ # Since we stub the driver class below, to make sure that we don't
38
+ # create a real connection, the test won't fail if the method definition
39
+ # is changed.
40
+ method = RedisClient::RubyConnection.instance_method(:write)
41
+ expect(method.arity).to eql(1)
42
+ end
43
+ end
44
+
45
+ context "instrumentation" do
46
+ before do
47
+ start_agent
48
+ # Stub RedisClient::RubyConnection class so that it doesn't perform an actual
49
+ # Redis query. This class will be included (prepended) with the
50
+ # AppSignal Redis integration.
51
+ stub_const("RedisClient::RubyConnection", Class.new do
52
+ def initialize(config)
53
+ @config = config
54
+ end
55
+
56
+ def write(_commands)
57
+ "stub_write"
58
+ end
59
+ end)
60
+ # Load the integration again for the stubbed RedisClient::RubyConnection class.
61
+ # Call it directly because {Appsignal::Hooks.load_hooks} keeps
62
+ # track if it was installed already or not.
63
+ Appsignal::Hooks::RedisClientHook.new.install
64
+ end
65
+ let!(:transaction) do
66
+ Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
67
+ end
68
+ let!(:client_config) { RedisClient::Config.new(:id => "stub_id") }
69
+ around { |example| keep_transactions { example.run } }
70
+
71
+ it "instrument a redis call" do
72
+ connection = RedisClient::RubyConnection.new client_config
73
+ expect(connection.write([:get, "key"])).to eql("stub_write")
74
+
75
+ transaction_hash = transaction.to_h
76
+ expect(transaction_hash["events"]).to include(
77
+ hash_including(
78
+ "name" => "query.redis",
79
+ "body" => "get ?",
80
+ "title" => "stub_id"
81
+ )
82
+ )
83
+ end
84
+
85
+ it "instrument a redis script call" do
86
+ connection = ::RedisClient::RubyConnection.new client_config
87
+ script = "return redis.call('set',KEYS[1],ARGV[1])"
88
+ keys = ["foo"]
89
+ argv = ["bar"]
90
+ expect(connection.write([:eval, script, keys.size, keys,
91
+ argv])).to eql("stub_write")
92
+
93
+ transaction_hash = transaction.to_h
94
+ expect(transaction_hash["events"]).to include(
95
+ hash_including(
96
+ "name" => "query.redis",
97
+ "body" => "#{script} ? ?",
98
+ "title" => "stub_id"
99
+ )
100
+ )
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ if DependencyHelper.hiredis_client_present?
107
+ context "with hiredis driver" do
108
+ describe "integration" do
109
+ before do
110
+ Appsignal.config.config_hash[:instrument_redis] = true
111
+ end
112
+
113
+ context "install" do
114
+ before do
115
+ Appsignal::Hooks.load_hooks
116
+ end
117
+
118
+ it "includes the integration in the HiredisConnection class" do
119
+ # Test if the last included module (prepended module) was our
120
+ # integration. That's not certain with the assertions below
121
+ # because we have to overwrite the `process` method for the test.
122
+ expect(RedisClient::HiredisConnection.included_modules.first)
123
+ .to eql(Appsignal::Integrations::RedisClientIntegration)
124
+ end
125
+ end
126
+
127
+ context "requirements" do
128
+ it "driver should have the write method" do
129
+ # Since we stub the driver class below, to make sure that we don't
130
+ # create a real connection, the test won't fail if the method definition
131
+ # is changed.
132
+ method = RedisClient::HiredisConnection.instance_method(:write)
133
+ expect(method.arity).to eql(1)
134
+ end
135
+ end
136
+
137
+ context "instrumentation" do
138
+ before do
139
+ start_agent
140
+ # Stub RedisClient::HiredisConnection class so that it doesn't perform an actual
141
+ # Redis query. This class will be included (prepended) with the
142
+ # AppSignal Redis integration.
143
+ stub_const("RedisClient::HiredisConnection", Class.new do
144
+ def initialize(config)
145
+ @config = config
146
+ end
147
+
148
+ def write(_commands)
149
+ "stub_write"
150
+ end
151
+ end)
152
+ # Load the integration again for the stubbed RedisClient::HiredisConnection class.
153
+ # Call it directly because {Appsignal::Hooks.load_hooks} keeps
154
+ # track if it was installed already or not.
155
+ Appsignal::Hooks::RedisClientHook.new.install
156
+ end
157
+ let!(:transaction) do
158
+ Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST,
159
+ "test")
160
+ end
161
+ let!(:client_config) { RedisClient::Config.new(:id => "stub_id") }
162
+ around { |example| keep_transactions { example.run } }
163
+
164
+ it "instrument a redis call" do
165
+ connection = RedisClient::HiredisConnection.new client_config
166
+ expect(connection.write([:get, "key"])).to eql("stub_write")
167
+
168
+ transaction_hash = transaction.to_h
169
+ expect(transaction_hash["events"]).to include(
170
+ hash_including(
171
+ "name" => "query.redis",
172
+ "body" => "get ?",
173
+ "title" => "stub_id"
174
+ )
175
+ )
176
+ end
177
+
178
+ it "instrument a redis script call" do
179
+ connection = ::RedisClient::HiredisConnection.new client_config
180
+ script = "return redis.call('set',KEYS[1],ARGV[1])"
181
+ keys = ["foo"]
182
+ argv = ["bar"]
183
+ expect(connection.write([:eval, script, keys.size, keys,
184
+ argv])).to eql("stub_write")
185
+
186
+ transaction_hash = transaction.to_h
187
+ expect(transaction_hash["events"]).to include(
188
+ hash_including(
189
+ "name" => "query.redis",
190
+ "body" => "#{script} ? ?",
191
+ "title" => "stub_id"
192
+ )
193
+ )
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+
201
+ context "with instrumentation disabled" do
202
+ before do
203
+ Appsignal.config.config_hash[:instrument_redis] = false
204
+ end
205
+
206
+ describe "#dependencies_present?" do
207
+ subject { described_class.new.dependencies_present? }
208
+
209
+ it { is_expected.to be_falsy }
210
+ end
211
+ end
212
+ end
213
+ else
214
+ context "without redis" do
215
+ describe "#dependencies_present?" do
216
+ subject { described_class.new.dependencies_present? }
217
+
218
+ it { is_expected.to be_falsy }
219
+ end
220
+ end
221
+ end
222
+ end
@@ -5,100 +5,122 @@ describe Appsignal::Hooks::RedisHook do
5
5
 
6
6
  if DependencyHelper.redis_present?
7
7
  context "with redis" do
8
- context "with instrumentation enabled" do
9
- describe "#dependencies_present?" do
10
- subject { described_class.new.dependencies_present? }
8
+ if DependencyHelper.redis_client_present?
9
+ context "with redis-client" do
10
+ context "with instrumentation enabled" do
11
+ describe "#dependencies_present?" do
12
+ subject { described_class.new.dependencies_present? }
11
13
 
12
- it { is_expected.to be_truthy }
14
+ it { is_expected.to be_falsey }
15
+ end
16
+ end
13
17
  end
18
+ else
19
+ context "with instrumentation enabled" do
20
+ describe "#dependencies_present?" do
21
+ subject { described_class.new.dependencies_present? }
14
22
 
15
- describe "integration" do
16
- before do
17
- Appsignal.config.config_hash[:instrument_redis] = true
23
+ it { is_expected.to be_truthy }
18
24
  end
19
25
 
20
- context "install" do
26
+ describe "integration" do
21
27
  before do
22
- Appsignal::Hooks.load_hooks
28
+ Appsignal.config.config_hash[:instrument_redis] = true
23
29
  end
24
30
 
25
- it "does something" do
26
- # Test if the last included module (prepended module) was our
27
- # integration. That's not certain with the assertions below
28
- # because we have to overwrite the `process` method for the test.
29
- expect(Redis::Client.included_modules.first)
30
- .to eql(Appsignal::Integrations::RedisIntegration)
31
- end
32
- end
31
+ context "install" do
32
+ before do
33
+ Appsignal::Hooks.load_hooks
34
+ end
33
35
 
34
- context "instrumentation" do
35
- before do
36
- start_agent
37
- # Stub Redis::Client class so that it doesn't perform an actual
38
- # Redis query. This class will be included (prepended) with the
39
- # AppSignal Redis integration.
40
- stub_const("Redis::Client", Class.new do
41
- def id
42
- "stub_id"
43
- end
44
-
45
- def write(_commands)
46
- "stub_write"
47
- end
48
- end)
49
- # Load the integration again for the stubbed Redis::Client class.
50
- # Call it directly because {Appsignal::Hooks.load_hooks} keeps
51
- # track if it was installed already or not.
52
- Appsignal::Hooks::RedisHook.new.install
53
- end
54
- let!(:transaction) do
55
- Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
36
+ it "prepends instrumentation module" do
37
+ # Test if the last included module (prepended module) was our
38
+ # integration. That's not certain with the assertions below
39
+ # because we have to overwrite the `process` method for the test.
40
+ expect(Redis::Client.included_modules.first)
41
+ .to eql(Appsignal::Integrations::RedisIntegration)
42
+ end
56
43
  end
57
- around { |example| keep_transactions { example.run } }
58
-
59
- it "instrument a redis call" do
60
- client = Redis::Client.new
61
- expect(client.write([:get, "key"])).to eql("stub_write")
62
-
63
- transaction_hash = transaction.to_h
64
- expect(transaction_hash["events"]).to include(
65
- hash_including(
66
- "name" => "query.redis",
67
- "body" => "get ?",
68
- "title" => "stub_id"
69
- )
70
- )
44
+
45
+ context "requirements" do
46
+ it "driver should have the write method" do
47
+ # Since we stub the client class below, to make sure that we don't
48
+ # create a real connection, the test won't fail if the method definition
49
+ # is changed.
50
+ method = Redis::Client.instance_method(:call)
51
+ expect(method.arity).to eql(1)
52
+ end
71
53
  end
72
54
 
73
- it "instrument a redis script call" do
74
- client = Redis::Client.new
75
- script = "return redis.call('set',KEYS[1],ARGV[1])"
76
- keys = ["foo"]
77
- argv = ["bar"]
78
- expect(client.write([:eval, script, keys.size, keys, argv])).to eql("stub_write")
79
-
80
- transaction_hash = transaction.to_h
81
- expect(transaction_hash["events"]).to include(
82
- hash_including(
83
- "name" => "query.redis",
84
- "body" => "#{script} ? ?",
85
- "title" => "stub_id"
86
- )
87
- )
55
+ context "instrumentation" do
56
+ before do
57
+ start_agent
58
+ # Stub Redis::Client class so that it doesn't perform an actual
59
+ # Redis query. This class will be included (prepended) with the
60
+ # AppSignal Redis integration.
61
+ stub_const("Redis::Client", Class.new do
62
+ def id
63
+ "stub_id"
64
+ end
65
+
66
+ def write(_commands)
67
+ "stub_write"
68
+ end
69
+ end)
70
+ # Load the integration again for the stubbed Redis::Client class.
71
+ # Call it directly because {Appsignal::Hooks.load_hooks} keeps
72
+ # track if it was installed already or not.
73
+ Appsignal::Hooks::RedisHook.new.install
74
+ end
75
+ let!(:transaction) do
76
+ Appsignal::Transaction.create("uuid", Appsignal::Transaction::HTTP_REQUEST, "test")
77
+ end
78
+ around { |example| keep_transactions { example.run } }
79
+
80
+ it "instrument a redis call" do
81
+ client = Redis::Client.new
82
+ expect(client.write([:get, "key"])).to eql("stub_write")
83
+
84
+ transaction_hash = transaction.to_h
85
+ expect(transaction_hash["events"]).to include(
86
+ hash_including(
87
+ "name" => "query.redis",
88
+ "body" => "get ?",
89
+ "title" => "stub_id"
90
+ )
91
+ )
92
+ end
93
+
94
+ it "instrument a redis script call" do
95
+ client = Redis::Client.new
96
+ script = "return redis.call('set',KEYS[1],ARGV[1])"
97
+ keys = ["foo"]
98
+ argv = ["bar"]
99
+ expect(client.write([:eval, script, keys.size, keys, argv])).to eql("stub_write")
100
+
101
+ transaction_hash = transaction.to_h
102
+ expect(transaction_hash["events"]).to include(
103
+ hash_including(
104
+ "name" => "query.redis",
105
+ "body" => "#{script} ? ?",
106
+ "title" => "stub_id"
107
+ )
108
+ )
109
+ end
88
110
  end
89
111
  end
90
112
  end
91
- end
92
113
 
93
- context "with instrumentation disabled" do
94
- before do
95
- Appsignal.config.config_hash[:instrument_redis] = false
96
- end
114
+ context "with instrumentation disabled" do
115
+ before do
116
+ Appsignal.config.config_hash[:instrument_redis] = false
117
+ end
97
118
 
98
- describe "#dependencies_present?" do
99
- subject { described_class.new.dependencies_present? }
119
+ describe "#dependencies_present?" do
120
+ subject { described_class.new.dependencies_present? }
100
121
 
101
- it { is_expected.to be_falsy }
122
+ it { is_expected.to be_falsy }
123
+ end
102
124
  end
103
125
  end
104
126
  end
@@ -67,12 +67,12 @@ describe Appsignal::Hooks do
67
67
  expect(Appsignal::Hooks.hooks[:mock_error_hook]).to be_instance_of(MockErrorHook)
68
68
  expect(Appsignal::Hooks.hooks[:mock_error_hook].installed?).to be_falsy
69
69
 
70
- expect(Appsignal.logger).to receive(:error)
70
+ expect(Appsignal.internal_logger).to receive(:error)
71
71
  .with("Error while installing mock_error_hook hook: error").once
72
- expect(Appsignal.logger).to receive(:debug).ordered do |message|
72
+ expect(Appsignal.internal_logger).to receive(:debug).ordered do |message|
73
73
  expect(message).to eq("Installing mock_error_hook hook")
74
74
  end
75
- expect(Appsignal.logger).to receive(:debug).ordered do |message|
75
+ expect(Appsignal.internal_logger).to receive(:debug).ordered do |message|
76
76
  # Start of the error backtrace as debug log
77
77
  expect(message).to start_with(File.expand_path("../../..", __dir__))
78
78
  end
@@ -89,7 +89,7 @@ describe Appsignal::Hooks do
89
89
  let(:log_stream) { std_stream }
90
90
  let(:log) { log_contents(log_stream) }
91
91
  before do
92
- Appsignal.logger = test_logger(log_stream)
92
+ Appsignal.internal_logger = test_logger(log_stream)
93
93
  end
94
94
 
95
95
  def call_constant(&block)
@@ -18,9 +18,9 @@ if DependencyHelper.rails_present?
18
18
  describe "#initialize_appsignal" do
19
19
  let(:app) { MyApp::Application.new }
20
20
 
21
- describe ".logger" do
21
+ describe ".internal_logger" do
22
22
  before { Appsignal::Integrations::Railtie.initialize_appsignal(app) }
23
- subject { Appsignal.logger }
23
+ subject { Appsignal.internal_logger }
24
24
 
25
25
  it { is_expected.to be_a Logger }
26
26
  end