appsignal 3.9.2-java → 3.10.0-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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3138 -0
  3. data/.rubocop.yml +28 -20
  4. data/.rubocop_todo.yml +7 -33
  5. data/CHANGELOG.md +130 -0
  6. data/README.md +0 -1
  7. data/Rakefile +80 -65
  8. data/appsignal.gemspec +1 -1
  9. data/build_matrix.yml +112 -184
  10. data/ext/base.rb +1 -1
  11. data/gemfiles/hanami-2.1.gemfile +7 -0
  12. data/gemfiles/webmachine1.gemfile +5 -4
  13. data/lib/appsignal/cli/diagnose.rb +1 -1
  14. data/lib/appsignal/config.rb +5 -1
  15. data/lib/appsignal/demo.rb +0 -1
  16. data/lib/appsignal/environment.rb +11 -2
  17. data/lib/appsignal/extension/jruby.rb +1 -1
  18. data/lib/appsignal/helpers/instrumentation.rb +164 -2
  19. data/lib/appsignal/hooks/active_job.rb +1 -6
  20. data/lib/appsignal/integrations/grape.rb +19 -47
  21. data/lib/appsignal/integrations/hanami.rb +8 -7
  22. data/lib/appsignal/integrations/padrino.rb +51 -52
  23. data/lib/appsignal/integrations/railtie.rb +0 -3
  24. data/lib/appsignal/integrations/rake.rb +46 -12
  25. data/lib/appsignal/integrations/sidekiq.rb +1 -11
  26. data/lib/appsignal/integrations/sinatra.rb +0 -1
  27. data/lib/appsignal/integrations/webmachine.rb +15 -9
  28. data/lib/appsignal/probes/gvl.rb +24 -2
  29. data/lib/appsignal/probes/sidekiq.rb +1 -1
  30. data/lib/appsignal/probes.rb +1 -1
  31. data/lib/appsignal/rack/abstract_middleware.rb +104 -33
  32. data/lib/appsignal/rack/body_wrapper.rb +143 -0
  33. data/lib/appsignal/rack/event_handler.rb +12 -3
  34. data/lib/appsignal/rack/generic_instrumentation.rb +5 -4
  35. data/lib/appsignal/rack/grape_middleware.rb +40 -0
  36. data/lib/appsignal/rack/hanami_middleware.rb +2 -12
  37. data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
  38. data/lib/appsignal/rack/rails_instrumentation.rb +14 -57
  39. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
  40. data/lib/appsignal/rack/streaming_listener.rb +13 -59
  41. data/lib/appsignal/rack.rb +31 -0
  42. data/lib/appsignal/transaction.rb +50 -8
  43. data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
  44. data/lib/appsignal/utils.rb +1 -0
  45. data/lib/appsignal/version.rb +1 -1
  46. data/lib/appsignal.rb +36 -33
  47. data/spec/.rubocop.yml +1 -1
  48. data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
  49. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  50. data/spec/lib/appsignal/config_spec.rb +8 -5
  51. data/spec/lib/appsignal/demo_spec.rb +38 -41
  52. data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
  53. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
  54. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
  55. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
  56. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
  57. data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
  58. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
  59. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
  60. data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
  61. data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
  62. data/spec/lib/appsignal/hooks/rake_spec.rb +107 -34
  63. data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
  64. data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
  65. data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
  66. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
  67. data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
  68. data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
  69. data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
  70. data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
  71. data/spec/lib/appsignal/integrations/padrino_spec.rb +190 -163
  72. data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
  73. data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
  74. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
  75. data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -3
  76. data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -40
  77. data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
  78. data/spec/lib/appsignal/probes_spec.rb +7 -4
  79. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +302 -105
  80. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
  81. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
  82. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -27
  83. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
  84. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
  85. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
  86. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
  87. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
  88. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +44 -139
  89. data/spec/lib/appsignal/transaction_spec.rb +239 -94
  90. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
  91. data/spec/lib/appsignal_spec.rb +556 -344
  92. data/spec/support/helpers/dependency_helper.rb +6 -1
  93. data/spec/support/helpers/std_streams_helper.rb +1 -1
  94. data/spec/support/helpers/transaction_helpers.rb +8 -0
  95. data/spec/support/matchers/transaction.rb +185 -0
  96. data/spec/support/mocks/dummy_app.rb +20 -0
  97. data/spec/support/shared_examples/instrument.rb +17 -12
  98. data/spec/support/testing.rb +18 -9
  99. metadata +20 -11
  100. data/.semaphore/semaphore.yml +0 -2347
  101. data/script/lint_git +0 -22
  102. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
  103. data/spec/support/matchers/be_completed.rb +0 -5
  104. data/support/check_versions +0 -22
  105. /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
@@ -15,72 +15,109 @@ if DependencyHelper.webmachine_present?
15
15
 
16
16
  describe Appsignal::Integrations::WebmachineIntegration do
17
17
  let(:request) do
18
- Webmachine::Request.new("GET", "http://google.com:80/foo", {}, nil)
18
+ Webmachine::Request.new(
19
+ "GET",
20
+ "http://google.com:80/foo?param1=value1&param2=value2",
21
+ {},
22
+ nil
23
+ )
19
24
  end
20
- let(:resource) { double(:trace? => false, :handle_exception => true, :"code=" => nil) }
21
- let(:response) { Response.new }
22
- let(:transaction) { double(:set_action_if_nil => true) }
23
- let(:fsm) { Webmachine::Decision::FSM.new(resource, request, response) }
24
- before(:context) { start_agent }
25
-
26
- # Make sure the request responds to the method we need to get query params.
27
- describe "request" do
28
- it "should respond to `query`" do
29
- expect(request).to respond_to(:query)
25
+ let(:app) do
26
+ proc do
27
+ def to_html
28
+ "Some HTML"
29
+ end
30
+ end
31
+ end
32
+ let(:resource) do
33
+ app_block = app
34
+ Class.new(Webmachine::Resource) do
35
+ class_eval(&app_block) if app_block
36
+
37
+ def self.name
38
+ "MyResource"
39
+ end
30
40
  end
31
41
  end
42
+ let(:resource_instance) { resource.new(request, response) }
43
+ let(:response) { Webmachine::Response.new }
44
+ let(:fsm) { Webmachine::Decision::FSM.new(resource_instance, request, response) }
45
+ before { start_agent }
46
+ around { |example| keep_transactions { example.run } }
32
47
 
33
48
  describe "#run" do
34
- before do
35
- allow(SecureRandom).to receive(:uuid).and_return("uuid")
36
- allow(Appsignal::Transaction).to receive(:create).and_return(transaction)
49
+ it "creates a transaction" do
50
+ expect { fsm.run }.to(change { created_transactions.count }.by(1))
37
51
  end
38
52
 
39
- it "should create a transaction" do
40
- expect(Appsignal::Transaction).to receive(:create).with(
41
- "uuid",
42
- Appsignal::Transaction::HTTP_REQUEST,
43
- request,
44
- :params_method => :query
45
- ).and_return(transaction)
53
+ it "sets the action" do
54
+ fsm.run
55
+ expect(last_transaction).to have_action("MyResource#GET")
46
56
  end
47
57
 
48
- it "should set the action" do
49
- expect(transaction).to receive(:set_action_if_nil).with("RSpec::Mocks::Double#GET")
58
+ context "with action already set" do
59
+ let(:app) do
60
+ proc do
61
+ def to_html
62
+ Appsignal.set_action("Custom Action")
63
+ "Some HTML"
64
+ end
65
+ end
66
+ end
67
+
68
+ it "doesn't overwrite the action" do
69
+ fsm.run
70
+ expect(last_transaction).to have_action("Custom Action")
71
+ end
50
72
  end
51
73
 
52
- it "should call the original method" do
53
- expect(fsm).to receive(:run)
74
+ it "records an instrumentation event" do
75
+ fsm.run
76
+ expect(last_transaction).to include_event("name" => "process_action.webmachine")
54
77
  end
55
78
 
56
- it "should instrument the original method" do
57
- expect(Appsignal).to receive(:instrument).with("process_action.webmachine")
79
+ it "sets the params" do
80
+ fsm.run
81
+ expect(last_transaction).to include_params("param1" => "value1", "param2" => "value2")
58
82
  end
59
83
 
60
- it "should close the transaction" do
61
- expect(Appsignal::Transaction).to receive(:complete_current!)
84
+ it "closes the transaction" do
85
+ fsm.run
86
+ expect(last_transaction).to be_completed
87
+ expect(current_transaction?).to be_falsy
62
88
  end
63
89
 
64
- after { fsm.run }
90
+ context "with parent transaction" do
91
+ let(:transaction) { http_request_transaction }
92
+ before { set_current_transaction(transaction) }
93
+
94
+ it "sets the action" do
95
+ fsm.run
96
+ expect(last_transaction).to have_action("MyResource#GET")
97
+ end
65
98
 
66
- describe "concerning the response" do
67
- it "sets a response code" do
68
- expect(fsm.response.code).to be_nil
99
+ it "sets the params" do
69
100
  fsm.run
70
- expect(fsm.response.code).not_to be_nil
101
+ last_transaction._sample
102
+ expect(last_transaction).to include_params("param1" => "value1", "param2" => "value2")
103
+ end
104
+
105
+ it "does not close the transaction" do
106
+ expect(last_transaction).to_not be_completed
71
107
  end
72
108
  end
73
109
  end
74
110
 
75
111
  describe "#handle_exceptions" do
76
- let(:error) { ExampleException }
112
+ let(:error) { ExampleException.new("error message") }
113
+ let(:transaction) { http_request_transaction }
77
114
 
78
- it "should catch the error and send it to AppSignal" do
79
- expect(Appsignal).to receive(:set_error).with(error)
80
- end
115
+ it "tracks the error" do
116
+ with_current_transaction(transaction) do
117
+ fsm.send(:handle_exceptions) { raise error }
118
+ end
81
119
 
82
- after do
83
- fsm.send(:handle_exceptions) { raise error }
120
+ expect(last_transaction).to have_error("ExampleException", "error message")
84
121
  end
85
122
  end
86
123
  end
@@ -4,6 +4,13 @@ describe Appsignal::Probes::GvlProbe do
4
4
 
5
5
  let(:hostname) { "some-host" }
6
6
 
7
+ around do |example|
8
+ real_program_name = $PROGRAM_NAME
9
+ example.run
10
+ ensure
11
+ $PROGRAM_NAME = real_program_name
12
+ end
13
+
7
14
  def gauges_for(metric)
8
15
  gauges = appsignal_mock.gauges.select do |gauge|
9
16
  gauge[0] == metric
@@ -14,7 +21,7 @@ describe Appsignal::Probes::GvlProbe do
14
21
  end
15
22
  end
16
23
 
17
- after(:each) { FakeGVLTools.reset }
24
+ after { FakeGVLTools.reset }
18
25
 
19
26
  it "gauges the global timer delta" do
20
27
  FakeGVLTools::GlobalTimer.monotonic_time = 100_000_000
@@ -26,6 +33,11 @@ describe Appsignal::Probes::GvlProbe do
26
33
  probe.call
27
34
 
28
35
  expect(gauges_for("gvl_global_timer")).to eq [
36
+ [200, {
37
+ :hostname => hostname,
38
+ :process_name => "rspec",
39
+ :process_id => Process.pid
40
+ }],
29
41
  [200, { :hostname => hostname }]
30
42
  ]
31
43
  end
@@ -58,7 +70,7 @@ describe Appsignal::Probes::GvlProbe do
58
70
  end
59
71
 
60
72
  context "when the waiting threads count is enabled" do
61
- before(:each) do
73
+ before do
62
74
  FakeGVLTools::WaitingThreads.enabled = true
63
75
  end
64
76
 
@@ -67,13 +79,18 @@ describe Appsignal::Probes::GvlProbe do
67
79
  probe.call
68
80
 
69
81
  expect(gauges_for("gvl_waiting_threads")).to eq [
82
+ [3, {
83
+ :hostname => hostname,
84
+ :process_name => "rspec",
85
+ :process_id => Process.pid
86
+ }],
70
87
  [3, { :hostname => hostname }]
71
88
  ]
72
89
  end
73
90
  end
74
91
 
75
92
  context "when the waiting threads count is disabled" do
76
- before(:each) do
93
+ before do
77
94
  FakeGVLTools::WaitingThreads.enabled = false
78
95
  end
79
96
 
@@ -84,4 +101,64 @@ describe Appsignal::Probes::GvlProbe do
84
101
  expect(gauges_for("gvl_waiting_threads")).to be_empty
85
102
  end
86
103
  end
104
+
105
+ context "when the process name is a custom value" do
106
+ before do
107
+ FakeGVLTools::WaitingThreads.enabled = true
108
+ end
109
+
110
+ it "uses only the first word as the process name" do
111
+ $PROGRAM_NAME = "sidekiq 7.1.6 app [0 of 5 busy]"
112
+ probe.call
113
+
114
+ expect(gauges_for("gvl_waiting_threads")).to eq [
115
+ [0, {
116
+ :hostname => hostname,
117
+ :process_name => "sidekiq",
118
+ :process_id => Process.pid
119
+ }],
120
+ [0, { :hostname => hostname }]
121
+ ]
122
+ end
123
+ end
124
+
125
+ context "when the process name is a path" do
126
+ before do
127
+ FakeGVLTools::WaitingThreads.enabled = true
128
+ end
129
+
130
+ it "uses only the binary name as the process name" do
131
+ $PROGRAM_NAME = "/foo/folder with spaces/bin/rails"
132
+ probe.call
133
+
134
+ expect(gauges_for("gvl_waiting_threads")).to eq [
135
+ [0, {
136
+ :hostname => hostname,
137
+ :process_name => "rails",
138
+ :process_id => Process.pid
139
+ }],
140
+ [0, { :hostname => hostname }]
141
+ ]
142
+ end
143
+ end
144
+
145
+ context "when the process name is an empty string" do
146
+ before do
147
+ FakeGVLTools::WaitingThreads.enabled = true
148
+ end
149
+
150
+ it "uses [unknown process] as the process name" do
151
+ $PROGRAM_NAME = ""
152
+ probe.call
153
+
154
+ expect(gauges_for("gvl_waiting_threads")).to eq [
155
+ [0, {
156
+ :hostname => hostname,
157
+ :process_name => "[unknown process]",
158
+ :process_id => Process.pid
159
+ }],
160
+ [0, { :hostname => hostname }]
161
+ ]
162
+ end
163
+ end
87
164
  end
@@ -20,7 +20,7 @@ describe Appsignal::Probes do
20
20
  .to include("appsignal WARNING: The constant Appsignal::Minutely has been deprecated.")
21
21
  end
22
22
 
23
- it "logs a warning to STDERR" do
23
+ it "logs a warning" do
24
24
  logs =
25
25
  capture_logs do
26
26
  silence do
@@ -28,7 +28,10 @@ describe Appsignal::Probes do
28
28
  end
29
29
  end
30
30
 
31
- expect(logs).to include("The constant Appsignal::Minutely has been deprecated.")
31
+ expect(logs).to contains_log(
32
+ :warn,
33
+ "The constant Appsignal::Minutely has been deprecated."
34
+ )
32
35
  end
33
36
  end
34
37
 
@@ -78,7 +81,7 @@ describe Appsignal::Probes do
78
81
  describe ".started?" do
79
82
  it "returns true when the probes thread has been started" do
80
83
  expect(Appsignal::Probes.started?).to be_falsy
81
- Appsignal::Probes.register :my_probe, (lambda {})
84
+ Appsignal::Probes.register :my_probe, lambda {}
82
85
  Appsignal::Probes.start
83
86
  expect(Appsignal::Probes.started?).to be_truthy
84
87
  end
@@ -475,7 +478,7 @@ describe Appsignal::Probes do
475
478
  probe = lambda {}
476
479
  collection.internal_register :my_probe, probe
477
480
  list = []
478
- collection.each do |name, p|
481
+ collection.each do |name, p| # rubocop:disable Style/MapIntoArray
479
482
  list << [name, p]
480
483
  end
481
484
  expect(list).to eql([[:my_probe, probe]])