appsignal 3.10.0 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +88 -0
- data/Gemfile +1 -0
- data/benchmark.rake +99 -42
- data/lib/appsignal/cli/demo.rb +0 -1
- data/lib/appsignal/config.rb +54 -98
- data/lib/appsignal/demo.rb +15 -20
- data/lib/appsignal/event_formatter/rom/sql_formatter.rb +1 -0
- data/lib/appsignal/event_formatter.rb +3 -2
- data/lib/appsignal/helpers/instrumentation.rb +331 -19
- data/lib/appsignal/hooks/action_cable.rb +21 -16
- data/lib/appsignal/hooks/active_job.rb +14 -8
- data/lib/appsignal/hooks/delayed_job.rb +1 -1
- data/lib/appsignal/hooks/shoryuken.rb +3 -63
- data/lib/appsignal/integrations/action_cable.rb +5 -7
- data/lib/appsignal/integrations/active_support_notifications.rb +1 -0
- data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +36 -35
- data/lib/appsignal/integrations/data_mapper.rb +1 -0
- data/lib/appsignal/integrations/delayed_job_plugin.rb +27 -33
- data/lib/appsignal/integrations/dry_monitor.rb +1 -0
- data/lib/appsignal/integrations/excon.rb +1 -0
- data/lib/appsignal/integrations/http.rb +1 -0
- data/lib/appsignal/integrations/net_http.rb +1 -0
- data/lib/appsignal/integrations/object.rb +6 -0
- data/lib/appsignal/integrations/que.rb +13 -20
- data/lib/appsignal/integrations/railtie.rb +1 -1
- data/lib/appsignal/integrations/rake.rb +1 -5
- data/lib/appsignal/integrations/redis.rb +1 -0
- data/lib/appsignal/integrations/redis_client.rb +1 -0
- data/lib/appsignal/integrations/resque.rb +2 -5
- data/lib/appsignal/integrations/shoryuken.rb +75 -0
- data/lib/appsignal/integrations/sidekiq.rb +7 -15
- data/lib/appsignal/integrations/unicorn.rb +1 -0
- data/lib/appsignal/integrations/webmachine.rb +2 -5
- data/lib/appsignal/logger.rb +7 -3
- data/lib/appsignal/probes/helpers.rb +1 -0
- data/lib/appsignal/probes/mri.rb +1 -0
- data/lib/appsignal/probes/sidekiq.rb +1 -0
- data/lib/appsignal/probes.rb +3 -0
- data/lib/appsignal/rack/abstract_middleware.rb +18 -12
- data/lib/appsignal/rack/event_handler.rb +39 -8
- data/lib/appsignal/rack/generic_instrumentation.rb +1 -0
- data/lib/appsignal/rack/grape_middleware.rb +2 -1
- data/lib/appsignal/rack/streaming_listener.rb +1 -0
- data/lib/appsignal/rack.rb +29 -0
- data/lib/appsignal/span.rb +1 -0
- data/lib/appsignal/transaction.rb +308 -101
- data/lib/appsignal/utils/data.rb +0 -1
- data/lib/appsignal/utils/hash_sanitizer.rb +0 -1
- data/lib/appsignal/utils/integration_logger.rb +0 -13
- data/lib/appsignal/utils/integration_memory_logger.rb +0 -13
- data/lib/appsignal/utils/json.rb +0 -1
- data/lib/appsignal/utils/query_params_sanitizer.rb +0 -1
- data/lib/appsignal/utils/stdout_and_logger_message.rb +0 -1
- data/lib/appsignal/utils.rb +6 -0
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +6 -5
- data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
- data/spec/lib/appsignal/config_spec.rb +138 -43
- data/spec/lib/appsignal/hooks/action_cable_spec.rb +43 -74
- data/spec/lib/appsignal/hooks/activejob_spec.rb +9 -0
- data/spec/lib/appsignal/hooks/delayed_job_spec.rb +2 -443
- data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -171
- data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +459 -0
- data/spec/lib/appsignal/integrations/que_spec.rb +3 -4
- data/spec/lib/appsignal/integrations/shoryuken_spec.rb +167 -0
- data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -4
- data/spec/lib/appsignal/integrations/webmachine_spec.rb +13 -1
- data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +48 -3
- data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -10
- data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +4 -2
- data/spec/lib/appsignal/rack_spec.rb +63 -0
- data/spec/lib/appsignal/transaction_spec.rb +1634 -1071
- data/spec/lib/appsignal/utils/integration_logger_spec.rb +12 -16
- data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -10
- data/spec/lib/appsignal_spec.rb +323 -10
- data/spec/support/helpers/transaction_helpers.rb +44 -20
- data/spec/support/matchers/transaction.rb +15 -1
- data/spec/support/testing.rb +1 -1
- metadata +6 -2
@@ -4,7 +4,6 @@ require "logger"
|
|
4
4
|
|
5
5
|
module Appsignal
|
6
6
|
module Utils
|
7
|
-
# @api private
|
8
7
|
class IntegrationMemoryLogger
|
9
8
|
LEVELS = {
|
10
9
|
Logger::DEBUG => :DEBUG,
|
@@ -35,18 +34,6 @@ module Appsignal
|
|
35
34
|
add(:WARN, message)
|
36
35
|
end
|
37
36
|
|
38
|
-
def seen_keys
|
39
|
-
@seen_keys ||= Set.new
|
40
|
-
end
|
41
|
-
|
42
|
-
def warn_once_then_debug(key, message)
|
43
|
-
if seen_keys.add?(key).nil?
|
44
|
-
debug message
|
45
|
-
else
|
46
|
-
warn message
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
37
|
def error(message)
|
51
38
|
add(:ERROR, message)
|
52
39
|
end
|
data/lib/appsignal/utils/json.rb
CHANGED
data/lib/appsignal/utils.rb
CHANGED
data/lib/appsignal/version.rb
CHANGED
data/lib/appsignal.rb
CHANGED
@@ -47,7 +47,7 @@ module Appsignal
|
|
47
47
|
# @see Extension
|
48
48
|
# @see extension_loaded?
|
49
49
|
attr_accessor :extension_loaded
|
50
|
-
# @!attribute [rw]
|
50
|
+
# @!attribute [rw] internal_logger
|
51
51
|
# Accessor for the internal AppSignal logger.
|
52
52
|
#
|
53
53
|
# Not to be confused with our logging feature.
|
@@ -59,10 +59,8 @@ module Appsignal
|
|
59
59
|
# {.start}) the contents of the "in memory logger" is written to the new
|
60
60
|
# logger.
|
61
61
|
#
|
62
|
-
# @note some classes may have options to set custom loggers. Their
|
63
|
-
# defaults are pointed to this attribute.
|
64
62
|
# @api private
|
65
|
-
# @return [
|
63
|
+
# @return [Utils::IntegrationLogger or Utils::IntegrationMemoryLogger]
|
66
64
|
# @see start
|
67
65
|
attr_writer :internal_logger
|
68
66
|
|
@@ -165,10 +163,12 @@ module Appsignal
|
|
165
163
|
Appsignal::Extension.start
|
166
164
|
end
|
167
165
|
|
166
|
+
# @api private
|
168
167
|
def get_server_state(key)
|
169
168
|
Appsignal::Extension.get_server_state(key)
|
170
169
|
end
|
171
170
|
|
171
|
+
# @api private
|
172
172
|
def in_memory_logger
|
173
173
|
@in_memory_logger ||=
|
174
174
|
Appsignal::Utils::IntegrationMemoryLogger.new.tap do |l|
|
@@ -176,6 +176,7 @@ module Appsignal
|
|
176
176
|
end
|
177
177
|
end
|
178
178
|
|
179
|
+
# @api private
|
179
180
|
def internal_logger
|
180
181
|
@internal_logger ||= in_memory_logger
|
181
182
|
end
|
@@ -195,7 +196,7 @@ module Appsignal
|
|
195
196
|
def start_logger
|
196
197
|
callers = caller
|
197
198
|
Appsignal::Utils::StdoutAndLoggerMessage.warning \
|
198
|
-
"
|
199
|
+
"Calling 'Appsignal.start_logger' is deprecated. " \
|
199
200
|
"The logger will be started when calling 'Appsignal.start'. " \
|
200
201
|
"Remove the 'Appsignal.start_logger' call in the following file to " \
|
201
202
|
"remove this message.\n#{callers.first}"
|
@@ -1,19 +1,4 @@
|
|
1
1
|
describe Appsignal::Config do
|
2
|
-
describe "config keys" do
|
3
|
-
it "all config keys have an environment variable version registered" do
|
4
|
-
config = Appsignal::Config
|
5
|
-
mapped_env_keys = config::ENV_TO_KEY_MAPPING.keys.sort
|
6
|
-
configured_env_keys = (
|
7
|
-
config::ENV_STRING_KEYS +
|
8
|
-
config::ENV_BOOLEAN_KEYS +
|
9
|
-
config::ENV_ARRAY_KEYS +
|
10
|
-
config::ENV_FLOAT_KEYS
|
11
|
-
).sort
|
12
|
-
|
13
|
-
expect(mapped_env_keys).to eql(configured_env_keys)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
2
|
describe "#initialize" do
|
18
3
|
describe "environment" do
|
19
4
|
context "when environment is nil" do
|
@@ -416,49 +401,159 @@ describe Appsignal::Config do
|
|
416
401
|
let(:working_directory_path) { File.join(tmp_dir, "test_working_directory_path") }
|
417
402
|
let(:env_config) do
|
418
403
|
{
|
419
|
-
:running_in_container => true,
|
420
|
-
:push_api_key => "aaa-bbb-ccc",
|
421
404
|
:active => true,
|
405
|
+
:activejob_report_errors => "all",
|
422
406
|
:bind_address => "0.0.0.0",
|
407
|
+
:ca_file_path => "/some/path",
|
423
408
|
:cpu_count => 1.5,
|
424
|
-
:name => "App name",
|
425
409
|
:debug => true,
|
426
410
|
:dns_servers => ["8.8.8.8", "8.8.4.4"],
|
427
|
-
:
|
428
|
-
:
|
411
|
+
:enable_allocation_tracking => false,
|
412
|
+
:enable_gvl_global_timer => false,
|
413
|
+
:enable_gvl_waiting_threads => false,
|
414
|
+
:enable_host_metrics => false,
|
415
|
+
:enable_minutely_probes => false,
|
416
|
+
:enable_nginx_metrics => false,
|
417
|
+
:enable_rails_error_reporter => false,
|
418
|
+
:enable_rake_performance_instrumentation => false,
|
419
|
+
:enable_statsd => false,
|
420
|
+
:endpoint => "https://test.appsignal.com",
|
421
|
+
:files_world_accessible => false,
|
422
|
+
:filter_metadata => ["key1", "key2"],
|
423
|
+
:filter_parameters => ["param1", "param2"],
|
424
|
+
:filter_session_data => ["session1", "session2"],
|
425
|
+
:host_role => "my host role",
|
426
|
+
:hostname => "my hostname",
|
427
|
+
:http_proxy => "some proxy",
|
428
|
+
:ignore_actions => ["action1", "action2"],
|
429
|
+
:ignore_errors => ["ExampleStandardError", "AnotherError"],
|
429
430
|
:ignore_logs => ["^start$", "^Completed 2.* in .*ms (.*)"],
|
430
|
-
:ignore_namespaces =>
|
431
|
+
:ignore_namespaces => ["admin", "private_namespace"],
|
432
|
+
:instrument_http_rb => false,
|
431
433
|
:instrument_net_http => false,
|
432
434
|
:instrument_redis => false,
|
433
435
|
:instrument_sequel => false,
|
434
|
-
:
|
435
|
-
:
|
436
|
+
:log => "file",
|
437
|
+
:log_level => "debug",
|
438
|
+
:log_path => "/tmp/something",
|
439
|
+
:logging_endpoint => "https://appsignal-endpoint.net/test",
|
440
|
+
:name => "App name",
|
441
|
+
:push_api_key => "aaa-bbb-ccc",
|
442
|
+
:request_headers => ["accept", "accept-charset"],
|
436
443
|
:revision => "v2.5.1",
|
444
|
+
:running_in_container => true,
|
437
445
|
:send_environment_metadata => false,
|
446
|
+
:send_params => false,
|
447
|
+
:send_session_data => false,
|
448
|
+
:sidekiq_report_errors => "all",
|
449
|
+
:skip_session_data => false,
|
450
|
+
:statsd_port => "7890",
|
451
|
+
:transaction_debug_mode => false,
|
452
|
+
:working_dir_path => "/some/path",
|
438
453
|
:working_directory_path => working_directory_path
|
439
454
|
}
|
440
455
|
end
|
456
|
+
let(:env_vars) do
|
457
|
+
{
|
458
|
+
# Strings
|
459
|
+
"APPSIGNAL_ACTIVEJOB_REPORT_ERRORS" => "all",
|
460
|
+
"APPSIGNAL_APP_NAME" => "App name",
|
461
|
+
"APPSIGNAL_BIND_ADDRESS" => "0.0.0.0",
|
462
|
+
"APPSIGNAL_CA_FILE_PATH" => "/some/path",
|
463
|
+
"APPSIGNAL_HOSTNAME" => "my hostname",
|
464
|
+
"APPSIGNAL_HOST_ROLE" => "my host role",
|
465
|
+
"APPSIGNAL_HTTP_PROXY" => "some proxy",
|
466
|
+
"APPSIGNAL_LOG" => "file",
|
467
|
+
"APPSIGNAL_LOGGING_ENDPOINT" => "https://appsignal-endpoint.net/test",
|
468
|
+
"APPSIGNAL_LOG_LEVEL" => "debug",
|
469
|
+
"APPSIGNAL_LOG_PATH" => "/tmp/something",
|
470
|
+
"APPSIGNAL_PUSH_API_ENDPOINT" => "https://test.appsignal.com",
|
471
|
+
"APPSIGNAL_PUSH_API_KEY" => "aaa-bbb-ccc",
|
472
|
+
"APPSIGNAL_SIDEKIQ_REPORT_ERRORS" => "all",
|
473
|
+
"APPSIGNAL_STATSD_PORT" => "7890",
|
474
|
+
"APPSIGNAL_WORKING_DIRECTORY_PATH" => working_directory_path,
|
475
|
+
"APPSIGNAL_WORKING_DIR_PATH" => "/some/path",
|
476
|
+
"APP_REVISION" => "v2.5.1",
|
477
|
+
|
478
|
+
# Booleans
|
479
|
+
"APPSIGNAL_ACTIVE" => "true",
|
480
|
+
"APPSIGNAL_DEBUG" => "true",
|
481
|
+
"APPSIGNAL_ENABLE_ALLOCATION_TRACKING" => "false",
|
482
|
+
"APPSIGNAL_ENABLE_GVL_GLOBAL_TIMER" => "false",
|
483
|
+
"APPSIGNAL_ENABLE_GVL_WAITING_THREADS" => "false",
|
484
|
+
"APPSIGNAL_ENABLE_HOST_METRICS" => "false",
|
485
|
+
"APPSIGNAL_ENABLE_MINUTELY_PROBES" => "false",
|
486
|
+
"APPSIGNAL_ENABLE_NGINX_METRICS" => "false",
|
487
|
+
"APPSIGNAL_ENABLE_RAILS_ERROR_REPORTER" => "false",
|
488
|
+
"APPSIGNAL_ENABLE_RAKE_PERFORMANCE_INSTRUMENTATION" => "false",
|
489
|
+
"APPSIGNAL_ENABLE_STATSD" => "false",
|
490
|
+
"APPSIGNAL_FILES_WORLD_ACCESSIBLE" => "false",
|
491
|
+
"APPSIGNAL_INSTRUMENT_HTTP_RB" => "false",
|
492
|
+
"APPSIGNAL_INSTRUMENT_NET_HTTP" => "false",
|
493
|
+
"APPSIGNAL_INSTRUMENT_REDIS" => "false",
|
494
|
+
"APPSIGNAL_INSTRUMENT_SEQUEL" => "false",
|
495
|
+
"APPSIGNAL_RUNNING_IN_CONTAINER" => "true",
|
496
|
+
"APPSIGNAL_SEND_ENVIRONMENT_METADATA" => "false",
|
497
|
+
"APPSIGNAL_SEND_PARAMS" => "false",
|
498
|
+
"APPSIGNAL_SEND_SESSION_DATA" => "false",
|
499
|
+
"APPSIGNAL_SKIP_SESSION_DATA" => "false",
|
500
|
+
"APPSIGNAL_TRANSACTION_DEBUG_MODE" => "false",
|
501
|
+
|
502
|
+
# Arrays
|
503
|
+
"APPSIGNAL_DNS_SERVERS" => "8.8.8.8,8.8.4.4",
|
504
|
+
"APPSIGNAL_FILTER_METADATA" => "key1,key2",
|
505
|
+
"APPSIGNAL_FILTER_PARAMETERS" => "param1,param2",
|
506
|
+
"APPSIGNAL_FILTER_SESSION_DATA" => "session1,session2",
|
507
|
+
"APPSIGNAL_IGNORE_ACTIONS" => "action1,action2",
|
508
|
+
"APPSIGNAL_IGNORE_ERRORS" => "ExampleStandardError,AnotherError",
|
509
|
+
"APPSIGNAL_IGNORE_LOGS" => "^start$,^Completed 2.* in .*ms (.*)",
|
510
|
+
"APPSIGNAL_IGNORE_NAMESPACES" => "admin,private_namespace",
|
511
|
+
"APPSIGNAL_REQUEST_HEADERS" => "accept,accept-charset",
|
512
|
+
|
513
|
+
# Floats
|
514
|
+
"APPSIGNAL_CPU_COUNT" => "1.5"
|
515
|
+
}
|
516
|
+
end
|
441
517
|
before do
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
518
|
+
env_vars.each do |key, value|
|
519
|
+
ENV[key] = value
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
it "reads all string env keys" do
|
524
|
+
config
|
525
|
+
|
526
|
+
Appsignal::Config::ENV_STRING_KEYS.each do |env_key, option|
|
527
|
+
ENV.fetch(env_key) { raise "Config env var '#{env_key}' is not set for this test" }
|
528
|
+
expect(config[option]).to eq(ENV.fetch(env_key, nil))
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
it "reads all boolean env keys" do
|
533
|
+
config
|
534
|
+
|
535
|
+
Appsignal::Config::ENV_BOOLEAN_KEYS.each do |env_key, option|
|
536
|
+
ENV.fetch(env_key) { raise "Config env var '#{env_key}' is not set for this test" }
|
537
|
+
expect(config[option]).to eq(ENV.fetch(env_key, nil) == "true")
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
it "reads all array env keys" do
|
542
|
+
config
|
543
|
+
|
544
|
+
Appsignal::Config::ENV_ARRAY_KEYS.each do |env_key, option|
|
545
|
+
ENV.fetch(env_key) { raise "Config env var '#{env_key}' is not set for this test" }
|
546
|
+
expect(config[option]).to eq(ENV.fetch(env_key, nil).split(","))
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
it "reads all float env keys" do
|
551
|
+
config
|
552
|
+
|
553
|
+
Appsignal::Config::ENV_FLOAT_KEYS.each do |env_key, option|
|
554
|
+
ENV.fetch(env_key) { raise "Config env var '#{env_key}' is not set for this test" }
|
555
|
+
expect(config[option]).to eq(ENV.fetch(env_key, nil).to_f)
|
556
|
+
end
|
462
557
|
end
|
463
558
|
|
464
559
|
it "overrides config with environment values" do
|
@@ -14,13 +14,6 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
describe ActionCable::Channel::Base do
|
17
|
-
let(:transaction) do
|
18
|
-
Appsignal::Transaction.new(
|
19
|
-
transaction_id,
|
20
|
-
Appsignal::Transaction::ACTION_CABLE,
|
21
|
-
ActionDispatch::Request.new(env)
|
22
|
-
)
|
23
|
-
end
|
24
17
|
let(:channel) do
|
25
18
|
Class.new(ActionCable::Channel::Base) do
|
26
19
|
def speak(_data)
|
@@ -37,21 +30,20 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
37
30
|
s.config.logger = ActiveSupport::Logger.new(log)
|
38
31
|
end
|
39
32
|
end
|
33
|
+
let(:env) do
|
34
|
+
http_request_env_with_data(
|
35
|
+
"action_dispatch.request_id" => request_id,
|
36
|
+
:params => params,
|
37
|
+
:with_queue_start => true
|
38
|
+
)
|
39
|
+
end
|
40
40
|
let(:connection) { ActionCable::Connection::Base.new(server, env) }
|
41
41
|
let(:identifier) { { :channel => "MyChannel" }.to_json }
|
42
42
|
let(:params) { {} }
|
43
43
|
let(:request_id) { SecureRandom.uuid }
|
44
|
-
let(:transaction_id) { request_id }
|
45
|
-
let(:env) do
|
46
|
-
http_request_env_with_data("action_dispatch.request_id" => request_id, :params => params)
|
47
|
-
end
|
48
44
|
let(:instance) { channel.new(connection, identifier, params) }
|
49
45
|
before do
|
50
46
|
start_agent
|
51
|
-
expect(Appsignal.active?).to be_truthy
|
52
|
-
transaction
|
53
|
-
|
54
|
-
set_current_transaction(transaction)
|
55
47
|
|
56
48
|
# Stub transmit call for subscribe/unsubscribe tests
|
57
49
|
allow(connection).to receive(:websocket)
|
@@ -64,7 +56,7 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
64
56
|
instance.perform_action("message" => "foo", "action" => "speak")
|
65
57
|
|
66
58
|
transaction = last_transaction
|
67
|
-
expect(transaction).to have_id
|
59
|
+
expect(transaction).to have_id
|
68
60
|
expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
|
69
61
|
expect(transaction).to have_action("MyChannel#speak")
|
70
62
|
expect(transaction).to_not have_error
|
@@ -83,40 +75,20 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
83
75
|
"action" => "speak",
|
84
76
|
"message" => "foo"
|
85
77
|
)
|
78
|
+
expect(transaction).to include_tags("request_id" => request_id)
|
79
|
+
expect(transaction).to_not have_queue_start
|
80
|
+
expect(transaction).to be_completed
|
86
81
|
end
|
87
82
|
|
88
83
|
context "without request_id (standalone server)" do
|
89
84
|
let(:request_id) { nil }
|
90
|
-
let(:transaction_id) { SecureRandom.uuid }
|
91
|
-
let(:action_transaction) do
|
92
|
-
Appsignal::Transaction.new(
|
93
|
-
transaction_id,
|
94
|
-
Appsignal::Transaction::ACTION_CABLE,
|
95
|
-
ActionDispatch::Request.new(env)
|
96
|
-
)
|
97
|
-
end
|
98
|
-
before do
|
99
|
-
# Stub future (private AppSignal) transaction id generated by the hook.
|
100
|
-
expect(SecureRandom).to receive(:uuid).and_return(transaction_id)
|
101
|
-
end
|
102
85
|
|
103
|
-
it "
|
86
|
+
it "sets a generated request ID" do
|
104
87
|
# Subscribe action, sets the request_id
|
105
88
|
instance.subscribe_to_channel
|
106
|
-
expect(transaction).to have_id(transaction_id)
|
107
|
-
|
108
|
-
# Expect another transaction for the action.
|
109
|
-
# This transaction will use the same request_id as the
|
110
|
-
# transaction id used to subscribe to the channel.
|
111
|
-
expect(Appsignal::Transaction).to receive(:create).with(
|
112
|
-
transaction_id,
|
113
|
-
Appsignal::Transaction::ACTION_CABLE,
|
114
|
-
kind_of(ActionDispatch::Request)
|
115
|
-
).and_return(action_transaction)
|
116
|
-
allow(Appsignal::Transaction).to receive(:current).and_return(action_transaction)
|
117
89
|
|
118
90
|
instance.perform_action("message" => "foo", "action" => "speak")
|
119
|
-
expect(
|
91
|
+
expect(last_transaction).to include_tags("request_id" => kind_of(String))
|
120
92
|
end
|
121
93
|
end
|
122
94
|
|
@@ -139,7 +111,7 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
139
111
|
end.to raise_error(ExampleException)
|
140
112
|
|
141
113
|
transaction = last_transaction
|
142
|
-
expect(transaction).to have_id
|
114
|
+
expect(transaction).to have_id
|
143
115
|
expect(transaction).to have_action("MyChannel#speak")
|
144
116
|
expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
|
145
117
|
expect(transaction).to have_error("ExampleException", "oh no!")
|
@@ -151,6 +123,8 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
151
123
|
"action" => "speak",
|
152
124
|
"message" => "foo"
|
153
125
|
)
|
126
|
+
expect(transaction).to_not have_queue_start
|
127
|
+
expect(transaction).to be_completed
|
154
128
|
end
|
155
129
|
end
|
156
130
|
end
|
@@ -162,7 +136,7 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
162
136
|
instance.subscribe_to_channel
|
163
137
|
|
164
138
|
transaction = last_transaction
|
165
|
-
expect(transaction).to have_id
|
139
|
+
expect(transaction).to have_id
|
166
140
|
expect(transaction).to have_action("MyChannel#subscribed")
|
167
141
|
expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
|
168
142
|
expect(transaction).to_not have_error
|
@@ -178,18 +152,17 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
178
152
|
"name" => "subscribed.action_cable",
|
179
153
|
"title" => ""
|
180
154
|
)
|
155
|
+
expect(transaction).to include_tags("request_id" => request_id)
|
156
|
+
expect(transaction).to_not have_queue_start
|
157
|
+
expect(transaction).to be_completed
|
181
158
|
end
|
182
159
|
|
183
160
|
context "without request_id (standalone server)" do
|
184
161
|
let(:request_id) { nil }
|
185
|
-
|
186
|
-
before do
|
187
|
-
allow(SecureRandom).to receive(:uuid).and_return(transaction_id)
|
188
|
-
instance.subscribe_to_channel
|
189
|
-
end
|
162
|
+
before { instance.subscribe_to_channel }
|
190
163
|
|
191
|
-
it "
|
192
|
-
expect(last_transaction).to
|
164
|
+
it "sets a generated request ID" do
|
165
|
+
expect(last_transaction).to include_tags("request_id" => kind_of(String))
|
193
166
|
end
|
194
167
|
end
|
195
168
|
|
@@ -212,7 +185,7 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
212
185
|
end.to raise_error(ExampleException)
|
213
186
|
|
214
187
|
transaction = last_transaction
|
215
|
-
expect(transaction).to have_id
|
188
|
+
expect(transaction).to have_id
|
216
189
|
expect(transaction).to have_action("MyChannel#subscribed")
|
217
190
|
expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
|
218
191
|
expect(transaction).to have_error("ExampleException", "oh no!")
|
@@ -221,23 +194,20 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
221
194
|
"path" => "/blog"
|
222
195
|
)
|
223
196
|
expect(transaction).to include_params("internal" => "true")
|
197
|
+
expect(transaction).to_not have_queue_start
|
198
|
+
expect(transaction).to be_completed
|
224
199
|
end
|
225
200
|
end
|
226
201
|
|
227
202
|
if DependencyHelper.rails6_present?
|
228
203
|
context "with ConnectionStub" do
|
229
204
|
let(:connection) { ActionCable::Channel::ConnectionStub.new }
|
230
|
-
let(:transaction_id) { "Stubbed transaction id" }
|
231
|
-
before do
|
232
|
-
# Stub future (private AppSignal) transaction id generated by the hook.
|
233
|
-
expect(SecureRandom).to receive(:uuid).and_return(transaction_id)
|
234
|
-
end
|
235
205
|
|
236
206
|
it "does not fail on missing `#env` method on `ConnectionStub`" do
|
237
207
|
instance.subscribe_to_channel
|
238
208
|
|
239
209
|
transaction = last_transaction
|
240
|
-
expect(transaction).to have_id
|
210
|
+
expect(transaction).to have_id
|
241
211
|
expect(transaction).to have_action("MyChannel#subscribed")
|
242
212
|
expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
|
243
213
|
expect(transaction).to_not have_error
|
@@ -245,7 +215,7 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
245
215
|
"method" => "websocket",
|
246
216
|
"path" => "" # No path as the ConnectionStub doesn't have the real request env
|
247
217
|
)
|
248
|
-
expect(transaction).
|
218
|
+
expect(transaction).to_not include_params
|
249
219
|
expect(transaction).to include_event(
|
250
220
|
"body" => "",
|
251
221
|
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
@@ -253,6 +223,8 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
253
223
|
"name" => "subscribed.action_cable",
|
254
224
|
"title" => ""
|
255
225
|
)
|
226
|
+
expect(transaction).to_not have_queue_start
|
227
|
+
expect(transaction).to be_completed
|
256
228
|
end
|
257
229
|
end
|
258
230
|
end
|
@@ -265,7 +237,7 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
265
237
|
instance.unsubscribe_from_channel
|
266
238
|
|
267
239
|
transaction = last_transaction
|
268
|
-
expect(transaction).to have_id
|
240
|
+
expect(transaction).to have_id
|
269
241
|
expect(transaction).to have_action("MyChannel#unsubscribed")
|
270
242
|
expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
|
271
243
|
expect(transaction).to_not have_error
|
@@ -281,18 +253,16 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
281
253
|
"name" => "unsubscribed.action_cable",
|
282
254
|
"title" => ""
|
283
255
|
)
|
256
|
+
expect(transaction).to_not have_queue_start
|
257
|
+
expect(transaction).to be_completed
|
284
258
|
end
|
285
259
|
|
286
260
|
context "without request_id (standalone server)" do
|
287
261
|
let(:request_id) { nil }
|
288
|
-
|
289
|
-
before do
|
290
|
-
allow(SecureRandom).to receive(:uuid).and_return(transaction_id)
|
291
|
-
instance.unsubscribe_from_channel
|
292
|
-
end
|
262
|
+
before { instance.unsubscribe_from_channel }
|
293
263
|
|
294
|
-
it "
|
295
|
-
expect(
|
264
|
+
it "sets a generated request ID" do
|
265
|
+
expect(last_transaction).to include_tags("request_id" => kind_of(String))
|
296
266
|
end
|
297
267
|
end
|
298
268
|
|
@@ -315,7 +285,7 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
315
285
|
end.to raise_error(ExampleException)
|
316
286
|
|
317
287
|
transaction = last_transaction
|
318
|
-
expect(transaction).to have_id
|
288
|
+
expect(transaction).to have_id
|
319
289
|
expect(transaction).to have_action("MyChannel#unsubscribed")
|
320
290
|
expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
|
321
291
|
expect(transaction).to have_error("ExampleException", "oh no!")
|
@@ -324,23 +294,20 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
324
294
|
"path" => "/blog"
|
325
295
|
)
|
326
296
|
expect(transaction).to include_params("internal" => "true")
|
297
|
+
expect(transaction).to_not have_queue_start
|
298
|
+
expect(transaction).to be_completed
|
327
299
|
end
|
328
300
|
end
|
329
301
|
|
330
302
|
if DependencyHelper.rails6_present?
|
331
303
|
context "with ConnectionStub" do
|
332
304
|
let(:connection) { ActionCable::Channel::ConnectionStub.new }
|
333
|
-
let(:transaction_id) { "Stubbed transaction id" }
|
334
|
-
before do
|
335
|
-
# Stub future (private AppSignal) transaction id generated by the hook.
|
336
|
-
expect(SecureRandom).to receive(:uuid).and_return(transaction_id)
|
337
|
-
end
|
338
305
|
|
339
306
|
it "does not fail on missing `#env` method on `ConnectionStub`" do
|
340
307
|
instance.unsubscribe_from_channel
|
341
308
|
|
342
309
|
transaction = last_transaction
|
343
|
-
expect(transaction).to have_id
|
310
|
+
expect(transaction).to have_id
|
344
311
|
expect(transaction).to have_action("MyChannel#unsubscribed")
|
345
312
|
expect(transaction).to have_namespace(Appsignal::Transaction::ACTION_CABLE)
|
346
313
|
expect(transaction).to_not have_error
|
@@ -348,7 +315,7 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
348
315
|
"method" => "websocket",
|
349
316
|
"path" => "" # No path as the ConnectionStub doesn't have the real request env
|
350
317
|
)
|
351
|
-
expect(transaction).
|
318
|
+
expect(transaction).to_not include_params
|
352
319
|
expect(transaction).to include_event(
|
353
320
|
"body" => "",
|
354
321
|
"body_format" => Appsignal::EventFormatter::DEFAULT,
|
@@ -356,6 +323,8 @@ describe Appsignal::Hooks::ActionCableHook do
|
|
356
323
|
"name" => "unsubscribed.action_cable",
|
357
324
|
"title" => ""
|
358
325
|
)
|
326
|
+
expect(transaction).to_not have_queue_start
|
327
|
+
expect(transaction).to be_completed
|
359
328
|
end
|
360
329
|
end
|
361
330
|
end
|