appsignal 3.9.2-java → 3.10.0-java

Sign up to get free protection for your applications and to get access to all the features.
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]])