appsignal 3.13.0-java → 4.0.0.beta.1-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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +499 -487
  3. data/CHANGELOG.md +113 -0
  4. data/Rakefile +31 -7
  5. data/benchmark.rake +4 -6
  6. data/build_matrix.yml +45 -39
  7. data/ext/agent.rb +27 -27
  8. data/ext/appsignal_extension.c +25 -0
  9. data/gemfiles/rails-7.2.gemfile +11 -0
  10. data/lib/appsignal/check_in/cron.rb +2 -15
  11. data/lib/appsignal/cli/diagnose.rb +37 -28
  12. data/lib/appsignal/cli/install.rb +5 -1
  13. data/lib/appsignal/config.rb +57 -119
  14. data/lib/appsignal/demo.rb +2 -2
  15. data/lib/appsignal/extension/jruby.rb +14 -0
  16. data/lib/appsignal/helpers/instrumentation.rb +139 -417
  17. data/lib/appsignal/helpers/metrics.rb +0 -16
  18. data/lib/appsignal/hooks/action_cable.rb +8 -8
  19. data/lib/appsignal/hooks/active_job.rb +2 -2
  20. data/lib/appsignal/hooks/at_exit.rb +37 -0
  21. data/lib/appsignal/hooks.rb +1 -16
  22. data/lib/appsignal/integrations/action_cable.rb +2 -2
  23. data/lib/appsignal/integrations/capistrano/appsignal.cap +2 -4
  24. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +1 -4
  25. data/lib/appsignal/integrations/delayed_job_plugin.rb +3 -3
  26. data/lib/appsignal/integrations/que.rb +2 -2
  27. data/lib/appsignal/integrations/railtie.rb +26 -59
  28. data/lib/appsignal/integrations/rake.rb +2 -2
  29. data/lib/appsignal/integrations/resque.rb +2 -2
  30. data/lib/appsignal/integrations/shoryuken.rb +4 -4
  31. data/lib/appsignal/integrations/sidekiq.rb +3 -3
  32. data/lib/appsignal/integrations/webmachine.rb +2 -2
  33. data/lib/appsignal/loaders.rb +1 -1
  34. data/lib/appsignal/probes.rb +0 -9
  35. data/lib/appsignal/rack/abstract_middleware.rb +4 -26
  36. data/lib/appsignal/rack/event_handler.rb +4 -4
  37. data/lib/appsignal/rack/rails_instrumentation.rb +1 -1
  38. data/lib/appsignal/rack.rb +0 -25
  39. data/lib/appsignal/sample_data.rb +95 -0
  40. data/lib/appsignal/transaction.rb +235 -361
  41. data/lib/appsignal/utils/rails_helper.rb +4 -0
  42. data/lib/appsignal/version.rb +1 -1
  43. data/lib/appsignal.rb +19 -71
  44. data/spec/lib/appsignal/auth_check_spec.rb +1 -1
  45. data/spec/lib/appsignal/capistrano2_spec.rb +1 -1
  46. data/spec/lib/appsignal/capistrano3_spec.rb +53 -13
  47. data/spec/lib/appsignal/check_in_spec.rb +1 -207
  48. data/spec/lib/appsignal/cli/demo_spec.rb +7 -27
  49. data/spec/lib/appsignal/cli/diagnose_spec.rb +145 -110
  50. data/spec/lib/appsignal/config_spec.rb +304 -379
  51. data/spec/lib/appsignal/extension_install_failure_spec.rb +5 -1
  52. data/spec/lib/appsignal/extension_spec.rb +5 -1
  53. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +1 -1
  54. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +1 -2
  55. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +1 -0
  56. data/spec/lib/appsignal/hooks/activejob_spec.rb +7 -12
  57. data/spec/lib/appsignal/hooks/at_exit_spec.rb +72 -0
  58. data/spec/lib/appsignal/hooks/gvl_spec.rb +10 -5
  59. data/spec/lib/appsignal/hooks/http_spec.rb +3 -3
  60. data/spec/lib/appsignal/hooks/net_http_spec.rb +3 -3
  61. data/spec/lib/appsignal/hooks/rake_spec.rb +6 -9
  62. data/spec/lib/appsignal/hooks/redis_client_spec.rb +5 -10
  63. data/spec/lib/appsignal/hooks/redis_spec.rb +4 -7
  64. data/spec/lib/appsignal/hooks/resque_spec.rb +3 -5
  65. data/spec/lib/appsignal/hooks_spec.rb +0 -41
  66. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +29 -20
  67. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +4 -9
  68. data/spec/lib/appsignal/integrations/railtie_spec.rb +179 -157
  69. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +3 -5
  70. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +48 -62
  71. data/spec/lib/appsignal/loaders/hanami_spec.rb +6 -9
  72. data/spec/lib/appsignal/loaders/padrino_spec.rb +6 -10
  73. data/spec/lib/appsignal/loaders/sinatra_spec.rb +6 -9
  74. data/spec/lib/appsignal/loaders_spec.rb +8 -1
  75. data/spec/lib/appsignal/marker_spec.rb +1 -1
  76. data/spec/lib/appsignal/probes_spec.rb +4 -83
  77. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +4 -63
  78. data/spec/lib/appsignal/rack/event_handler_spec.rb +18 -15
  79. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +3 -11
  80. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +4 -5
  81. data/spec/lib/appsignal/sample_data_spec.rb +174 -0
  82. data/spec/lib/appsignal/transaction_spec.rb +791 -1031
  83. data/spec/lib/appsignal/transmitter_spec.rb +6 -8
  84. data/spec/lib/appsignal_spec.rb +294 -643
  85. data/spec/spec_helper.rb +1 -3
  86. data/spec/support/fixtures/projects/valid/config/appsignal.yml +4 -7
  87. data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +16 -0
  88. data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +56 -0
  89. data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +5 -0
  90. data/spec/support/helpers/api_request_helper.rb +3 -2
  91. data/spec/support/helpers/config_helpers.rb +41 -11
  92. data/spec/support/helpers/dependency_helper.rb +8 -0
  93. data/spec/support/helpers/log_helpers.rb +1 -0
  94. data/spec/support/helpers/rails_helper.rb +6 -6
  95. data/spec/support/helpers/transaction_helpers.rb +2 -24
  96. data/spec/support/matchers/transaction.rb +3 -3
  97. data/spec/support/mocks/appsignal_mock.rb +3 -3
  98. data/spec/support/mocks/mock_probe.rb +2 -0
  99. data/spec/support/testing.rb +2 -2
  100. metadata +12 -22
  101. data/gemfiles/que_beta.gemfile +0 -5
  102. data/lib/appsignal/helpers/heartbeat.rb +0 -20
  103. data/lib/appsignal/integrations/grape.rb +0 -35
  104. data/lib/appsignal/integrations/hanami.rb +0 -13
  105. data/lib/appsignal/integrations/padrino.rb +0 -13
  106. data/lib/appsignal/integrations/sinatra.rb +0 -13
  107. data/lib/appsignal/rack/generic_instrumentation.rb +0 -22
  108. data/lib/appsignal/rack/streaming_listener.rb +0 -28
  109. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -36
  110. data/spec/lib/appsignal/integrations/hanami_spec.rb +0 -17
  111. data/spec/lib/appsignal/integrations/padrino_spec.rb +0 -15
  112. data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -15
  113. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +0 -81
  114. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +0 -69
  115. data/spec/support/fixtures/projects/valid/config/environments/development.rb +0 -0
  116. data/spec/support/fixtures/projects/valid/config/environments/production.rb +0 -0
  117. data/spec/support/fixtures/projects/valid/config/environments/test.rb +0 -0
  118. data/spec/support/rails/my_app.rb +0 -6
  119. /data/spec/support/fixtures/projects/{valid/config/application.rb → valid_with_rails_app/log/.gitkeep} +0 -0
@@ -13,10 +13,11 @@ describe Appsignal::Rack::EventHandler do
13
13
  let(:request) { Rack::Request.new(env) }
14
14
  let(:response) { nil }
15
15
  let(:log_stream) { StringIO.new }
16
- let(:log) { log_contents(log_stream) }
16
+ let(:logs) { log_contents(log_stream) }
17
17
  let(:event_handler_instance) { described_class.new }
18
+ let(:appsignal_env) { :default }
18
19
  before do
19
- start_agent
20
+ start_agent(:env => appsignal_env)
20
21
  Appsignal.internal_logger = test_logger(log_stream)
21
22
  end
22
23
  around { |example| keep_transactions { example.run } }
@@ -41,9 +42,9 @@ describe Appsignal::Rack::EventHandler do
41
42
  end
42
43
 
43
44
  context "when not active" do
44
- it "does not create a new transaction" do
45
- allow(Appsignal).to receive(:active?).and_return(false)
45
+ let(:appsignal_env) { :inactive_env }
46
46
 
47
+ it "does not create a new transaction" do
47
48
  expect { on_start }.to_not(change { created_transactions.length })
48
49
  end
49
50
  end
@@ -95,7 +96,7 @@ describe Appsignal::Rack::EventHandler do
95
96
  end
96
97
 
97
98
  it "logs an error" do
98
- expect(log).to contains_log(
99
+ expect(logs).to contains_log(
99
100
  :error,
100
101
  "Error occurred in Appsignal::Rack::EventHandler's after_reply: " \
101
102
  "ExampleStandardError: oh no"
@@ -112,7 +113,7 @@ describe Appsignal::Rack::EventHandler do
112
113
  callback = request.env[Appsignal::Rack::RACK_AFTER_REPLY].first
113
114
  callback.call
114
115
 
115
- expect(log).to contains_log(
116
+ expect(logs).to contains_log(
116
117
  :error,
117
118
  "Error occurred in Appsignal::Rack::EventHandler's after_reply: ExampleStandardError: oh no"
118
119
  )
@@ -124,7 +125,7 @@ describe Appsignal::Rack::EventHandler do
124
125
 
125
126
  on_start
126
127
 
127
- expect(log).to contains_log(
128
+ expect(logs).to contains_log(
128
129
  :error,
129
130
  "Error occurred in Appsignal::Rack::EventHandler#on_start: ExampleStandardError: oh no"
130
131
  )
@@ -140,9 +141,9 @@ describe Appsignal::Rack::EventHandler do
140
141
  end
141
142
 
142
143
  context "when not active" do
143
- it "does not report the transaction" do
144
- allow(Appsignal).to receive(:active?).and_return(false)
144
+ let(:appsignal_env) { :inactive_env }
145
145
 
146
+ it "does not report the transaction" do
146
147
  on_start
147
148
  on_error(ExampleStandardError.new("the error"))
148
149
 
@@ -167,7 +168,7 @@ describe Appsignal::Rack::EventHandler do
167
168
 
168
169
  on_error(ExampleStandardError.new("the error"))
169
170
 
170
- expect(log).to contains_log(
171
+ expect(logs).to contains_log(
171
172
  :error,
172
173
  "Error occurred in Appsignal::Rack::EventHandler#on_error: ExampleStandardError: oh no"
173
174
  )
@@ -195,9 +196,9 @@ describe Appsignal::Rack::EventHandler do
195
196
  end
196
197
 
197
198
  context "when not active" do
198
- it "doesn't do anything" do
199
- allow(Appsignal).to receive(:active?).and_return(false)
199
+ let(:appsignal_env) { :inactive_env }
200
200
 
201
+ it "doesn't do anything" do
201
202
  request.env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = http_request_transaction
202
203
  on_finish
203
204
 
@@ -353,8 +354,10 @@ describe Appsignal::Rack::EventHandler do
353
354
  end
354
355
 
355
356
  it "logs an error" do
356
- expect(log).to contains_log(:error,
357
- "Error occurred in Appsignal::Rack::EventHandler#on_finish: ExampleStandardError: oh no")
357
+ expect(logs).to contains_log(
358
+ :error,
359
+ "Error occurred in Appsignal::Rack::EventHandler#on_finish: ExampleStandardError: oh no"
360
+ )
358
361
  end
359
362
  end
360
363
 
@@ -429,7 +432,7 @@ describe Appsignal::Rack::EventHandler do
429
432
  on_start
430
433
  on_finish
431
434
 
432
- expect(log).to contains_log(
435
+ expect(logs).to contains_log(
433
436
  :error,
434
437
  "Error occurred in Appsignal::Rack::EventHandler#on_finish: ExampleStandardError: oh no"
435
438
  )
@@ -2,14 +2,7 @@ if DependencyHelper.rails_present?
2
2
  describe Appsignal::Rack::RailsInstrumentation do
3
3
  class MockController; end
4
4
 
5
- let(:log) { StringIO.new }
6
- let(:transaction) do
7
- Appsignal::Transaction.new(
8
- "transaction_id",
9
- Appsignal::Transaction::HTTP_REQUEST,
10
- Rack::Request.new(env)
11
- )
12
- end
5
+ let(:transaction) { new_transaction }
13
6
  let(:app) { DummyApp.new }
14
7
  let(:params) do
15
8
  {
@@ -36,7 +29,6 @@ if DependencyHelper.rails_present?
36
29
  around { |example| keep_transactions { example.run } }
37
30
  before do
38
31
  start_agent
39
- Appsignal.internal_logger = test_logger(log)
40
32
  env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = transaction
41
33
  end
42
34
 
@@ -111,10 +103,10 @@ if DependencyHelper.rails_present?
111
103
  it "does not store the invalid HTTP request method" do
112
104
  env[:request_method] = "FOO"
113
105
  env["REQUEST_METHOD"] = "FOO"
114
- make_request
106
+ logs = capture_logs { make_request }
115
107
 
116
108
  expect(last_transaction).to_not include_metadata("method" => anything)
117
- expect(log_contents(log)).to contains_log(
109
+ expect(logs).to contains_log(
118
110
  :error,
119
111
  "Exception while fetching the HTTP request method: "
120
112
  )
@@ -51,13 +51,12 @@ if DependencyHelper.sinatra_present?
51
51
  let(:env) do
52
52
  Rack::MockRequest.env_for("/path", "sinatra.route" => "GET /path", "REQUEST_METHOD" => "GET")
53
53
  end
54
+ let(:appsignal_env) { :default }
54
55
  let(:options) { {} }
55
56
  let(:middleware) { Appsignal::Rack::SinatraBaseInstrumentation.new(app, options) }
56
57
 
57
- before { start_agent }
58
- around do |example|
59
- keep_transactions { example.run }
60
- end
58
+ before { start_agent(:env => appsignal_env) }
59
+ around { |example| keep_transactions { example.run } }
61
60
 
62
61
  describe "#initialize" do
63
62
  context "with no settings method in the Sinatra app" do
@@ -97,7 +96,7 @@ if DependencyHelper.sinatra_present?
97
96
  before { allow(middleware).to receive(:raw_payload).and_return({}) }
98
97
 
99
98
  context "when appsignal is not active" do
100
- before { allow(Appsignal).to receive(:active?).and_return(false) }
99
+ let(:appsignal_env) { :inactive_env }
101
100
 
102
101
  it "does not instrument requests" do
103
102
  expect { make_request }.to_not(change { created_transactions.count })
@@ -0,0 +1,174 @@
1
+ describe Appsignal::SampleData do
2
+ let(:data) { described_class.new(:data_key) }
3
+
4
+ describe "#add" do
5
+ it "sets the given value" do
6
+ data.add(:key1 => "value 1")
7
+
8
+ expect(data.value).to eq(:key1 => "value 1")
9
+ end
10
+
11
+ it "adds the given value with the block being leading" do
12
+ data.add(:key1 => "value 1") { { :key2 => "value 2" } }
13
+
14
+ expect(data.value).to eq(:key2 => "value 2")
15
+ end
16
+
17
+ it "merges multiple values" do
18
+ data.add(:key1 => "value 1")
19
+ data.add(:key2 => "value 2")
20
+
21
+ expect(data.value).to eq(:key1 => "value 1", :key2 => "value 2")
22
+ end
23
+
24
+ it "merges only root level Hash keys" do
25
+ data.add(:key => { :abc => "value" })
26
+ data.add(:key => { :def => "value" })
27
+
28
+ expect(data.value).to eq(:key => { :def => "value" })
29
+ end
30
+
31
+ it "merges values from arguments and blocks" do
32
+ data.add(:key1 => "value 1")
33
+ data.add { { :key2 => "value 2" } }
34
+ data.add(:key3 => "value 3")
35
+
36
+ expect(data.value).to eq(:key1 => "value 1", :key2 => "value 2", :key3 => "value 3")
37
+ end
38
+
39
+ it "merges array values" do
40
+ data.add([:first_arg])
41
+ data.add { [:from_block] }
42
+ data.add([:second_arg])
43
+
44
+ expect(data.value).to eq([:first_arg, :from_block, :second_arg])
45
+ end
46
+
47
+ it "overwrites the value if the new value is of a different type" do
48
+ data.add(:key1 => "value 1")
49
+ expect(data.value).to eq(:key1 => "value 1")
50
+
51
+ data.add(["abc"])
52
+ expect(data.value).to eq(["abc"])
53
+
54
+ logs = capture_logs { data.value }
55
+ expect(logs).to contains_log(
56
+ :warn,
57
+ "The sample data 'data_key' changed type from 'Hash' to 'Array'."
58
+ )
59
+ end
60
+
61
+ it "ignores invalid values" do
62
+ logs = capture_logs { data.add("string") }
63
+ expect(data.value).to be_nil
64
+ expect(logs).to contains_log(
65
+ :error,
66
+ "Sample data 'data_key': Unsupported data type 'String' received: \"string\""
67
+ )
68
+
69
+ set = Set.new
70
+ set.add("abc")
71
+ logs = capture_logs { data.add(set) }
72
+ expect(data.value).to be_nil
73
+ expect(logs).to contains_log(
74
+ :error,
75
+ "Sample data 'data_key': Unsupported data type 'Set' received: #<Set: {\"abc\"}>"
76
+ )
77
+
78
+ instance = Class.new
79
+ logs = capture_logs { data.add(instance) }
80
+ expect(data.value).to be_nil
81
+ expect(logs).to contains_log(
82
+ :error,
83
+ "Sample data 'data_key': Unsupported data type 'Class' received: #<Class:"
84
+ )
85
+ end
86
+
87
+ context "with a type specified" do
88
+ it "only accepts values of Hash type" do
89
+ data = described_class.new(:data_key, Hash)
90
+
91
+ data.add(:key1 => "value 1")
92
+ data.add(["abc"])
93
+ data.add { { :key2 => "value 2" } }
94
+ data.add { ["def"] }
95
+ data.add(:key3 => "value 3")
96
+
97
+ expect(data.value).to eq(:key1 => "value 1", :key2 => "value 2", :key3 => "value 3")
98
+ end
99
+
100
+ it "only accepts values of Array type" do
101
+ data = described_class.new(:data_key, Array)
102
+
103
+ data.add(:key1 => "value 1")
104
+ data.add(["abc"])
105
+ data.add { { :key2 => "value 2" } }
106
+ data.add { ["def"] }
107
+ data.add(:key3 => "value 3")
108
+
109
+ expect(data.value).to eq(["abc", "def"])
110
+ end
111
+ end
112
+ end
113
+
114
+ describe "#value" do
115
+ it "caches the block value after calling it once" do
116
+ Appsignal::Testing.store[:block_call] = 0
117
+ data.add do
118
+ Appsignal::Testing.store[:block_call] += 1
119
+ { :key => "value" }
120
+ end
121
+
122
+ expect(data.value).to eq(:key => "value")
123
+ data.value
124
+
125
+ expect(Appsignal::Testing.store[:block_call]).to eq(1)
126
+ end
127
+ end
128
+
129
+ describe "#value?" do
130
+ it "returns true when value is set" do
131
+ data.add(["abc"])
132
+ expect(data.value?).to be_truthy
133
+ end
134
+
135
+ it "returns true when value is set with a block" do
136
+ data.add { ["abc"] }
137
+ expect(data.value?).to be_truthy
138
+ end
139
+
140
+ it "returns false when the value is not set" do
141
+ expect(data.value?).to be_falsey
142
+ end
143
+ end
144
+
145
+ describe "#duplicate" do
146
+ it "duplicates the internal Hash state without modifying the original" do
147
+ data = described_class.new(:my_key, Hash)
148
+ data.add(:abc => :value)
149
+
150
+ duplicate = data.dup
151
+ duplicate.add(:def => :value)
152
+
153
+ expect(data.value).to eq(:abc => :value)
154
+ expect(duplicate.value).to eq(:abc => :value, :def => :value)
155
+
156
+ expect(duplicate.instance_variable_get(:@key)).to eq(:my_key)
157
+ expect(duplicate.instance_variable_get(:@accepted_type)).to eq(Hash)
158
+ end
159
+
160
+ it "duplicates the internal Array state without modifying the original" do
161
+ data = described_class.new(:my_key, Array)
162
+ data.add([:abc])
163
+
164
+ duplicate = data.dup
165
+ duplicate.add([:def])
166
+
167
+ expect(data.value).to eq([:abc])
168
+ expect(duplicate.value).to eq([:abc, :def])
169
+
170
+ expect(duplicate.instance_variable_get(:@key)).to eq(:my_key)
171
+ expect(duplicate.instance_variable_get(:@accepted_type)).to eq(Array)
172
+ end
173
+ end
174
+ end