appsignal 4.0.6 → 4.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Rakefile +9 -9
  4. data/appsignal.gemspec +22 -1
  5. data/ext/agent.rb +27 -27
  6. data/lib/appsignal/check_in.rb +1 -1
  7. data/lib/appsignal/config.rb +1 -3
  8. data/lib/appsignal/integrations/resque.rb +1 -6
  9. data/lib/appsignal/utils/hash_sanitizer.rb +4 -0
  10. data/lib/appsignal/version.rb +1 -1
  11. data/lib/appsignal.rb +10 -8
  12. metadata +2 -192
  13. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  14. data/.github/ISSUE_TEMPLATE/chore.md +0 -14
  15. data/.github/workflows/ci.yml +0 -3285
  16. data/.github/workflows/create_release_from_tag.yml +0 -62
  17. data/.gitignore +0 -35
  18. data/.gitmodules +0 -3
  19. data/.rspec +0 -4
  20. data/.yardopts +0 -8
  21. data/benchmark.rake +0 -139
  22. data/gemfiles/capistrano2.gemfile +0 -6
  23. data/gemfiles/capistrano3.gemfile +0 -7
  24. data/gemfiles/dry-monitor.gemfile +0 -5
  25. data/gemfiles/grape.gemfile +0 -5
  26. data/gemfiles/hanami-2.0.gemfile +0 -7
  27. data/gemfiles/hanami-2.1.gemfile +0 -7
  28. data/gemfiles/http5.gemfile +0 -5
  29. data/gemfiles/no_dependencies.gemfile +0 -10
  30. data/gemfiles/padrino.gemfile +0 -7
  31. data/gemfiles/psych-3.gemfile +0 -5
  32. data/gemfiles/psych-4.gemfile +0 -5
  33. data/gemfiles/que-1.gemfile +0 -5
  34. data/gemfiles/que-2.gemfile +0 -5
  35. data/gemfiles/rails-6.0.gemfile +0 -10
  36. data/gemfiles/rails-6.1.gemfile +0 -11
  37. data/gemfiles/rails-7.0.gemfile +0 -11
  38. data/gemfiles/rails-7.1.gemfile +0 -11
  39. data/gemfiles/rails-7.2.gemfile +0 -11
  40. data/gemfiles/redis-4.gemfile +0 -5
  41. data/gemfiles/redis-5.gemfile +0 -6
  42. data/gemfiles/resque-2.gemfile +0 -6
  43. data/gemfiles/sequel.gemfile +0 -10
  44. data/gemfiles/sinatra.gemfile +0 -5
  45. data/gemfiles/webmachine1.gemfile +0 -7
  46. data/gemfiles/webmachine2.gemfile +0 -6
  47. data/mono.yml +0 -16
  48. data/spec/.rubocop.yml +0 -7
  49. data/spec/lib/appsignal/auth_check_spec.rb +0 -84
  50. data/spec/lib/appsignal/capistrano2_spec.rb +0 -227
  51. data/spec/lib/appsignal/capistrano3_spec.rb +0 -284
  52. data/spec/lib/appsignal/check_in/cron_spec.rb +0 -210
  53. data/spec/lib/appsignal/check_in/scheduler_spec.rb +0 -557
  54. data/spec/lib/appsignal/cli/demo_spec.rb +0 -46
  55. data/spec/lib/appsignal/cli/diagnose/paths_spec.rb +0 -16
  56. data/spec/lib/appsignal/cli/diagnose/utils_spec.rb +0 -86
  57. data/spec/lib/appsignal/cli/diagnose_spec.rb +0 -1553
  58. data/spec/lib/appsignal/cli/helpers_spec.rb +0 -179
  59. data/spec/lib/appsignal/cli/install_spec.rb +0 -848
  60. data/spec/lib/appsignal/cli_spec.rb +0 -56
  61. data/spec/lib/appsignal/config_spec.rb +0 -1380
  62. data/spec/lib/appsignal/demo_spec.rb +0 -83
  63. data/spec/lib/appsignal/environment_spec.rb +0 -190
  64. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +0 -60
  65. data/spec/lib/appsignal/event_formatter/active_record/instantiation_formatter_spec.rb +0 -21
  66. data/spec/lib/appsignal/event_formatter/active_record/sql_formatter_spec.rb +0 -21
  67. data/spec/lib/appsignal/event_formatter/elastic_search/search_formatter_spec.rb +0 -52
  68. data/spec/lib/appsignal/event_formatter/faraday/request_formatter_spec.rb +0 -21
  69. data/spec/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter_spec.rb +0 -84
  70. data/spec/lib/appsignal/event_formatter/rom/sql_formatter_spec.rb +0 -22
  71. data/spec/lib/appsignal/event_formatter/sequel/sql_formatter_spec.rb +0 -30
  72. data/spec/lib/appsignal/event_formatter/view_component/render_formatter_spec.rb +0 -41
  73. data/spec/lib/appsignal/event_formatter_spec.rb +0 -193
  74. data/spec/lib/appsignal/extension/jruby_spec.rb +0 -46
  75. data/spec/lib/appsignal/extension_install_failure_spec.rb +0 -20
  76. data/spec/lib/appsignal/extension_spec.rb +0 -178
  77. data/spec/lib/appsignal/garbage_collection_spec.rb +0 -98
  78. data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -345
  79. data/spec/lib/appsignal/hooks/action_mailer_spec.rb +0 -55
  80. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +0 -23
  81. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +0 -99
  82. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +0 -47
  83. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +0 -47
  84. data/spec/lib/appsignal/hooks/activejob_spec.rb +0 -650
  85. data/spec/lib/appsignal/hooks/at_exit_spec.rb +0 -105
  86. data/spec/lib/appsignal/hooks/celluloid_spec.rb +0 -40
  87. data/spec/lib/appsignal/hooks/data_mapper_spec.rb +0 -40
  88. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +0 -38
  89. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +0 -83
  90. data/spec/lib/appsignal/hooks/excon_spec.rb +0 -67
  91. data/spec/lib/appsignal/hooks/gvl_spec.rb +0 -145
  92. data/spec/lib/appsignal/hooks/http_spec.rb +0 -37
  93. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +0 -46
  94. data/spec/lib/appsignal/hooks/mri_spec.rb +0 -23
  95. data/spec/lib/appsignal/hooks/net_http_spec.rb +0 -18
  96. data/spec/lib/appsignal/hooks/passenger_spec.rb +0 -30
  97. data/spec/lib/appsignal/hooks/puma_spec.rb +0 -80
  98. data/spec/lib/appsignal/hooks/que_spec.rb +0 -19
  99. data/spec/lib/appsignal/hooks/rake_spec.rb +0 -144
  100. data/spec/lib/appsignal/hooks/redis_client_spec.rb +0 -218
  101. data/spec/lib/appsignal/hooks/redis_spec.rb +0 -124
  102. data/spec/lib/appsignal/hooks/resque_spec.rb +0 -27
  103. data/spec/lib/appsignal/hooks/sequel_spec.rb +0 -44
  104. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +0 -29
  105. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +0 -115
  106. data/spec/lib/appsignal/hooks/unicorn_spec.rb +0 -63
  107. data/spec/lib/appsignal/hooks/webmachine_spec.rb +0 -24
  108. data/spec/lib/appsignal/hooks_spec.rb +0 -124
  109. data/spec/lib/appsignal/integrations/data_mapper_spec.rb +0 -74
  110. data/spec/lib/appsignal/integrations/delayed_job_plugin_spec.rb +0 -454
  111. data/spec/lib/appsignal/integrations/http_spec.rb +0 -111
  112. data/spec/lib/appsignal/integrations/mongo_ruby_driver_spec.rb +0 -154
  113. data/spec/lib/appsignal/integrations/net_http_spec.rb +0 -33
  114. data/spec/lib/appsignal/integrations/object_spec.rb +0 -347
  115. data/spec/lib/appsignal/integrations/puma_spec.rb +0 -150
  116. data/spec/lib/appsignal/integrations/que_spec.rb +0 -187
  117. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -457
  118. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -155
  119. data/spec/lib/appsignal/integrations/shoryuken_spec.rb +0 -165
  120. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +0 -640
  121. data/spec/lib/appsignal/integrations/webmachine_spec.rb +0 -136
  122. data/spec/lib/appsignal/loaders/grape_spec.rb +0 -12
  123. data/spec/lib/appsignal/loaders/hanami_spec.rb +0 -92
  124. data/spec/lib/appsignal/loaders/padrino_spec.rb +0 -273
  125. data/spec/lib/appsignal/loaders/sinatra_spec.rb +0 -44
  126. data/spec/lib/appsignal/loaders_spec.rb +0 -144
  127. data/spec/lib/appsignal/logger_spec.rb +0 -205
  128. data/spec/lib/appsignal/marker_spec.rb +0 -51
  129. data/spec/lib/appsignal/probes/gvl_spec.rb +0 -164
  130. data/spec/lib/appsignal/probes/mri_spec.rb +0 -162
  131. data/spec/lib/appsignal/probes/sidekiq_spec.rb +0 -333
  132. data/spec/lib/appsignal/probes_spec.rb +0 -414
  133. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +0 -370
  134. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +0 -319
  135. data/spec/lib/appsignal/rack/event_handler_spec.rb +0 -441
  136. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +0 -201
  137. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +0 -36
  138. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +0 -38
  139. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +0 -126
  140. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +0 -217
  141. data/spec/lib/appsignal/rack_spec.rb +0 -243
  142. data/spec/lib/appsignal/sample_data_spec.rb +0 -238
  143. data/spec/lib/appsignal/span_spec.rb +0 -141
  144. data/spec/lib/appsignal/system_spec.rb +0 -126
  145. data/spec/lib/appsignal/transaction_spec.rb +0 -2115
  146. data/spec/lib/appsignal/transmitter_spec.rb +0 -198
  147. data/spec/lib/appsignal/utils/data_spec.rb +0 -166
  148. data/spec/lib/appsignal/utils/hash_sanitizer_spec.rb +0 -182
  149. data/spec/lib/appsignal/utils/integration_logger_spec.rb +0 -21
  150. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +0 -153
  151. data/spec/lib/appsignal/utils/json_spec.rb +0 -44
  152. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +0 -192
  153. data/spec/lib/appsignal_spec.rb +0 -1919
  154. data/spec/lib/puma/appsignal_spec.rb +0 -334
  155. data/spec/spec_helper.rb +0 -179
  156. data/spec/support/fixtures/generated_config.yml +0 -24
  157. data/spec/support/fixtures/projects/broken/config/appsignal.yml +0 -1
  158. data/spec/support/fixtures/projects/valid/config/appsignal.yml +0 -57
  159. data/spec/support/fixtures/projects/valid/log/.gitkeep +0 -0
  160. data/spec/support/fixtures/projects/valid_with_rails_app/config/application.rb +0 -16
  161. data/spec/support/fixtures/projects/valid_with_rails_app/config/appsignal.yml +0 -56
  162. data/spec/support/fixtures/projects/valid_with_rails_app/config/environment.rb +0 -10
  163. data/spec/support/fixtures/projects/valid_with_rails_app/log/.gitkeep +0 -0
  164. data/spec/support/fixtures/uploaded_file.txt +0 -0
  165. data/spec/support/hanami/hanami_app.rb +0 -29
  166. data/spec/support/helpers/action_mailer_helpers.rb +0 -25
  167. data/spec/support/helpers/activejob_helpers.rb +0 -27
  168. data/spec/support/helpers/api_request_helper.rb +0 -60
  169. data/spec/support/helpers/cli_helpers.rb +0 -40
  170. data/spec/support/helpers/config_helpers.rb +0 -66
  171. data/spec/support/helpers/dependency_helper.rb +0 -155
  172. data/spec/support/helpers/directory_helper.rb +0 -27
  173. data/spec/support/helpers/env_helpers.rb +0 -41
  174. data/spec/support/helpers/environment_metdata_helper.rb +0 -16
  175. data/spec/support/helpers/example_exception.rb +0 -13
  176. data/spec/support/helpers/example_standard_error.rb +0 -13
  177. data/spec/support/helpers/loader_helper.rb +0 -21
  178. data/spec/support/helpers/log_helpers.rb +0 -36
  179. data/spec/support/helpers/rails_helper.rb +0 -28
  180. data/spec/support/helpers/std_streams_helper.rb +0 -94
  181. data/spec/support/helpers/system_helpers.rb +0 -8
  182. data/spec/support/helpers/take_at_most_helper.rb +0 -21
  183. data/spec/support/helpers/time_helpers.rb +0 -11
  184. data/spec/support/helpers/transaction_helpers.rb +0 -122
  185. data/spec/support/helpers/wait_for_helper.rb +0 -39
  186. data/spec/support/matchers/contains_log.rb +0 -26
  187. data/spec/support/matchers/have_colorized_text.rb +0 -28
  188. data/spec/support/matchers/transaction.rb +0 -200
  189. data/spec/support/mocks/appsignal_mock.rb +0 -18
  190. data/spec/support/mocks/dummy_app.rb +0 -20
  191. data/spec/support/mocks/fake_gc_profiler.rb +0 -19
  192. data/spec/support/mocks/fake_gvl_tools.rb +0 -28
  193. data/spec/support/mocks/hash_like.rb +0 -10
  194. data/spec/support/mocks/mock_probe.rb +0 -13
  195. data/spec/support/mocks/puma_mock.rb +0 -43
  196. data/spec/support/shared_examples/instrument.rb +0 -48
  197. data/spec/support/stubs/appsignal/loaders/loader_stub.rb +0 -7
  198. data/spec/support/stubs/delayed_job.rb +0 -0
  199. data/spec/support/stubs/sidekiq/api.rb +0 -4
  200. data/spec/support/testing.rb +0 -203
  201. data/support/bundler_wrapper +0 -12
  202. data/support/install_deps +0 -33
@@ -1,205 +0,0 @@
1
- describe Appsignal::Logger do
2
- let(:log_stream) { StringIO.new }
3
- let(:logs) { log_contents(log_stream) }
4
- let(:logger) { Appsignal::Logger.new("group", :level => ::Logger::DEBUG) }
5
-
6
- before do
7
- Appsignal.internal_logger = test_logger(log_stream)
8
- end
9
-
10
- it "should not create a logger with a nil group" do
11
- expect do
12
- Appsignal::Logger.new(nil)
13
- end.to raise_error(TypeError)
14
- end
15
-
16
- describe "#add" do
17
- it "should log with a level and message" do
18
- expect(Appsignal::Extension).to receive(:log)
19
- .with("group", 3, 0, "Log message", instance_of(Appsignal::Extension::Data))
20
- logger.add(::Logger::INFO, "Log message")
21
- end
22
-
23
- it "does not log a message that's not a String" do
24
- expect(Appsignal::Extension).to_not receive(:log)
25
- logger.add(::Logger::INFO, 123)
26
- logger.add(::Logger::INFO, {})
27
- logger.add(::Logger::INFO, [])
28
- expect(logs)
29
- .to contains_log(:warn, "Logger message was ignored, because it was not a String: 123")
30
- expect(logs)
31
- .to contains_log(:warn, "Logger message was ignored, because it was not a String: []")
32
- expect(logs)
33
- .to contains_log(:warn, "Logger message was ignored, because it was not a String: {}")
34
- end
35
-
36
- it "should log with a block" do
37
- expect(Appsignal::Extension).to receive(:log)
38
- .with("group", 3, 0, "Log message", instance_of(Appsignal::Extension::Data))
39
- logger.add(::Logger::INFO) do
40
- "Log message"
41
- end
42
- end
43
-
44
- it "should log with a level, message and group" do
45
- expect(Appsignal::Extension).to receive(:log)
46
- .with("other_group", 3, 0, "Log message", instance_of(Appsignal::Extension::Data))
47
- logger.add(::Logger::INFO, "Log message", "other_group")
48
- end
49
-
50
- it "should log when using `group` for the log message" do
51
- expect(Appsignal::Extension).to receive(:log)
52
- .with("group", 3, 0, "Log message", instance_of(Appsignal::Extension::Data))
53
- logger.add(::Logger::INFO, nil, "Log message")
54
- end
55
-
56
- context "with info log level" do
57
- let(:logger) { Appsignal::Logger.new("group", :level => ::Logger::INFO) }
58
-
59
- it "should skip logging if the level is too low" do
60
- expect(Appsignal::Extension).not_to receive(:log)
61
- logger.add(::Logger::DEBUG, "Log message")
62
- end
63
- end
64
-
65
- context "with a format set" do
66
- let(:logger) { Appsignal::Logger.new("group", :format => Appsignal::Logger::LOGFMT) }
67
-
68
- it "should log and pass the format flag" do
69
- expect(Appsignal::Extension).to receive(:log)
70
- .with("group", 3, 1, "Log message", instance_of(Appsignal::Extension::Data))
71
- logger.add(::Logger::INFO, "Log message")
72
- end
73
- end
74
-
75
- context "with a formatter set" do
76
- before do
77
- logger.formatter = proc do |_level, _timestamp, _appname, message|
78
- "formatted: '#{message}'"
79
- end
80
- end
81
-
82
- it "should log with a level, message and group" do
83
- expect(Appsignal::Extension).to receive(:log).with(
84
- "other_group",
85
- 3,
86
- 0,
87
- "formatted: 'Log message'",
88
- instance_of(Appsignal::Extension::Data)
89
- )
90
- logger.add(::Logger::INFO, "Log message", "other_group")
91
- end
92
- end
93
- end
94
-
95
- describe "#silence" do
96
- it "calls the given block" do
97
- num = 1
98
-
99
- logger.silence do
100
- num += 1
101
- end
102
-
103
- expect(num).to eq(2)
104
- expect(Appsignal::Extension).not_to receive(:log)
105
- end
106
- end
107
-
108
- [
109
- ["debug", 2, ::Logger::INFO],
110
- ["info", 3, ::Logger::WARN],
111
- ["warn", 5, ::Logger::ERROR],
112
- ["error", 6, ::Logger::FATAL],
113
- ["fatal", 7, nil]
114
- ].each do |method|
115
- describe "##{method[0]}" do
116
- it "should log with a message" do
117
- expect(Appsignal::Utils::Data).to receive(:generate)
118
- .with({ :attribute => "value" })
119
- .and_call_original
120
- expect(Appsignal::Extension).to receive(:log)
121
- .with("group", method[1], 0, "Log message", instance_of(Appsignal::Extension::Data))
122
-
123
- logger.send(method[0], "Log message", :attribute => "value")
124
- end
125
-
126
- it "should log with a block" do
127
- expect(Appsignal::Utils::Data).to receive(:generate)
128
- .with({})
129
- .and_call_original
130
- expect(Appsignal::Extension).to receive(:log)
131
- .with("group", method[1], 0, "Log message", instance_of(Appsignal::Extension::Data))
132
-
133
- logger.send(method[0]) do
134
- "Log message"
135
- end
136
- end
137
-
138
- it "should return with a nil message" do
139
- expect(Appsignal::Extension).not_to receive(:log)
140
- logger.send(method[0])
141
- end
142
-
143
- if method[2]
144
- context "with a lower log level" do
145
- let(:logger) { Appsignal::Logger.new("group", :level => method[2]) }
146
-
147
- it "should skip logging if the level is too low" do
148
- expect(Appsignal::Extension).not_to receive(:log)
149
- logger.send(method[0], "Log message")
150
- end
151
- end
152
- end
153
-
154
- context "with a formatter set" do
155
- before do
156
- Timecop.freeze(Time.local(2023))
157
- logger.formatter = logger.formatter = proc do |_level, timestamp, _appname, message|
158
- # This line replicates the behaviour of the Ruby default Logger::Formatter
159
- # which expects a timestamp object as a second argument
160
- # https://github.com/ruby/ruby/blob/master/lib/logger/formatter.rb#L15-L17
161
- time = timestamp.strftime("%Y-%m-%dT%H:%M:%S.%6N")
162
- "formatted: #{time} '#{message}'"
163
- end
164
- end
165
-
166
- after do
167
- Timecop.return
168
- end
169
-
170
- it "should log with a level, message and group" do
171
- expect(Appsignal::Extension).to receive(:log)
172
- .with(
173
- "group",
174
- method[1],
175
- 0,
176
- "formatted: 2023-01-01T00:00:00.000000 'Log message'",
177
- instance_of(Appsignal::Extension::Data)
178
- )
179
- logger.send(method[0], "Log message")
180
- end
181
- end
182
- end
183
- end
184
-
185
- describe "#error with exception object" do
186
- it "logs the exception class and its message" do
187
- error =
188
- begin
189
- raise ExampleStandardError, "oh no!"
190
- rescue => e
191
- # This makes the exception include a backtrace, so we can assert it's NOT included
192
- e
193
- end
194
- expect(Appsignal::Extension).to receive(:log)
195
- .with(
196
- "group",
197
- 6,
198
- 0,
199
- "ExampleStandardError: oh no!",
200
- instance_of(Appsignal::Extension::Data)
201
- )
202
- logger.error(error)
203
- end
204
- end
205
- end
@@ -1,51 +0,0 @@
1
- describe Appsignal::Marker do
2
- let(:config) { build_config }
3
- let(:marker) do
4
- described_class.new(
5
- {
6
- :revision => "503ce0923ed177a3ce000005",
7
- :repository => "main",
8
- :user => "batman",
9
- :rails_env => "production"
10
- },
11
- config
12
- )
13
- end
14
- let(:out_stream) { std_stream }
15
- let(:output) { out_stream.read }
16
-
17
- describe "#transmit" do
18
- def stub_marker_request
19
- stub_api_request config, "markers", marker.marker_data
20
- end
21
-
22
- def run
23
- capture_stdout(out_stream) { marker.transmit }
24
- end
25
-
26
- context "when request is valid" do
27
- before { stub_marker_request.to_return(:status => 200) }
28
-
29
- it "outputs success" do
30
- run
31
- expect(output).to include \
32
- "Notifying AppSignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman",
33
- "AppSignal has been notified of this deploy!"
34
- end
35
- end
36
-
37
- context "when request is invalid" do
38
- before { stub_marker_request.to_return(:status => 500) }
39
-
40
- it "outputs failure" do
41
- run
42
- expect(output).to include \
43
- "Notifying AppSignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman",
44
- "Something went wrong while trying to notify AppSignal: 500 at " \
45
- "#{config[:endpoint]}/1/markers"
46
- expect(output).to_not include \
47
- "AppSignal has been notified of this deploy!"
48
- end
49
- end
50
- end
51
- end
@@ -1,164 +0,0 @@
1
- describe Appsignal::Probes::GvlProbe do
2
- let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
3
- let(:probe) { described_class.new(:appsignal => appsignal_mock, :gvl_tools => FakeGVLTools) }
4
-
5
- let(:hostname) { "some-host" }
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
-
14
- def gauges_for(metric)
15
- gauges = appsignal_mock.gauges.select do |gauge|
16
- gauge[0] == metric
17
- end
18
-
19
- gauges.map do |gauge|
20
- gauge.drop(1)
21
- end
22
- end
23
-
24
- after { FakeGVLTools.reset }
25
-
26
- it "gauges the global timer delta" do
27
- FakeGVLTools::GlobalTimer.monotonic_time = 100_000_000
28
- probe.call
29
-
30
- expect(gauges_for("gvl_global_timer")).to be_empty
31
-
32
- FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
33
- probe.call
34
-
35
- expect(gauges_for("gvl_global_timer")).to eq [
36
- [200, {
37
- :hostname => hostname,
38
- :process_name => "rspec",
39
- :process_id => Process.pid
40
- }],
41
- [200, { :hostname => hostname }]
42
- ]
43
- end
44
-
45
- context "when the delta is negative" do
46
- it "does not gauge the global timer delta" do
47
- FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
48
- probe.call
49
-
50
- expect(gauges_for("gvl_global_timer")).to be_empty
51
-
52
- FakeGVLTools::GlobalTimer.monotonic_time = 0
53
- probe.call
54
-
55
- expect(gauges_for("gvl_global_timer")).to be_empty
56
- end
57
- end
58
-
59
- context "when the delta is zero" do
60
- it "does not gauge the global timer delta" do
61
- FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
62
- probe.call
63
-
64
- expect(gauges_for("gvl_global_timer")).to be_empty
65
-
66
- probe.call
67
-
68
- expect(gauges_for("gvl_global_timer")).to be_empty
69
- end
70
- end
71
-
72
- context "when the waiting threads count is enabled" do
73
- before do
74
- FakeGVLTools::WaitingThreads.enabled = true
75
- end
76
-
77
- it "gauges the waiting threads count" do
78
- FakeGVLTools::WaitingThreads.count = 3
79
- probe.call
80
-
81
- expect(gauges_for("gvl_waiting_threads")).to eq [
82
- [3, {
83
- :hostname => hostname,
84
- :process_name => "rspec",
85
- :process_id => Process.pid
86
- }],
87
- [3, { :hostname => hostname }]
88
- ]
89
- end
90
- end
91
-
92
- context "when the waiting threads count is disabled" do
93
- before do
94
- FakeGVLTools::WaitingThreads.enabled = false
95
- end
96
-
97
- it "does not gauge the waiting threads count" do
98
- FakeGVLTools::WaitingThreads.count = 3
99
- probe.call
100
-
101
- expect(gauges_for("gvl_waiting_threads")).to be_empty
102
- end
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
164
- end
@@ -1,162 +0,0 @@
1
- describe Appsignal::Probes::MriProbe do
2
- let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
3
- let(:gc_profiler_mock) { instance_double("Appsignal::GarbageCollectionProfiler") }
4
- let(:probe) do
5
- described_class.new(:appsignal => appsignal_mock, :gc_profiler => gc_profiler_mock)
6
- end
7
-
8
- describe ".dependencies_present?" do
9
- if DependencyHelper.running_jruby?
10
- it "should not be present" do
11
- expect(described_class.dependencies_present?).to be_falsy
12
- end
13
- else
14
- it "should be present" do
15
- expect(described_class.dependencies_present?).to be_truthy
16
- end
17
- end
18
- end
19
-
20
- unless DependencyHelper.running_jruby?
21
- describe "#call" do
22
- let(:hostname) { nil }
23
- before do
24
- allow(gc_profiler_mock).to receive(:total_time)
25
- allow(GC::Profiler).to receive(:enabled?).and_return(true)
26
- end
27
-
28
- it "should track vm cache metrics" do
29
- probe.call
30
- if DependencyHelper.ruby_3_2_or_newer?
31
- expect_gauge_value("ruby_vm", :tags => { :metric => :constant_cache_invalidations })
32
- expect_gauge_value("ruby_vm", :tags => { :metric => :constant_cache_misses })
33
- else
34
- expect_gauge_value("ruby_vm", :tags => { :metric => :class_serial })
35
- expect_gauge_value("ruby_vm", :tags => { :metric => :global_constant_state })
36
- end
37
- end
38
-
39
- it "tracks thread counts" do
40
- probe.call
41
- expect_gauge_value("thread_count")
42
- end
43
-
44
- it "tracks GC time between measurements" do
45
- expect(gc_profiler_mock).to receive(:total_time).and_return(10, 15)
46
- probe.call
47
- probe.call
48
- expect_gauge_value("gc_time", 5)
49
- end
50
-
51
- context "when GC total time overflows" do
52
- it "skips one report" do
53
- expect(gc_profiler_mock).to receive(:total_time).and_return(10, 15, 0, 10)
54
- probe.call # Normal call, create a cache
55
- probe.call # Report delta value based on cached value
56
- probe.call # The value overflows and reports no value. Then stores 0 in the cache
57
- probe.call # Report new value based on cache of 0
58
- expect_gauges([["gc_time", 5], ["gc_time", 10]])
59
- end
60
- end
61
-
62
- context "when GC profiling is disabled" do
63
- it "does not report a gc_time metric" do
64
- allow(GC::Profiler).to receive(:enabled?).and_return(false)
65
- expect(gc_profiler_mock).to_not receive(:total_time)
66
- probe.call # Normal call, create a cache
67
- probe.call # Report delta value based on cached value
68
- metrics = appsignal_mock.gauges.map { |(key)| key }
69
- expect(metrics).to_not include("gc_time")
70
- end
71
-
72
- it "does not report a gc_time metric while temporarily disabled" do
73
- # While enabled
74
- allow(GC::Profiler).to receive(:enabled?).and_return(true)
75
- expect(gc_profiler_mock).to receive(:total_time).and_return(10, 15)
76
- probe.call # Normal call, create a cache
77
- probe.call # Report delta value based on cached value
78
- expect_gauges([["gc_time", 5]])
79
-
80
- # While disabled
81
- allow(GC::Profiler).to receive(:enabled?).and_return(false)
82
- probe.call # Call twice to make sure any caches resets wouldn't mess up the assertion
83
- probe.call
84
- # Does not include any newly reported metrics
85
- expect_gauges([["gc_time", 5]])
86
-
87
- # When enabled after being disabled for a while, it only reports the
88
- # newly reported time since it was renabled
89
- allow(GC::Profiler).to receive(:enabled?).and_return(true)
90
- expect(gc_profiler_mock).to receive(:total_time).and_return(25)
91
- probe.call
92
- expect_gauges([["gc_time", 5], ["gc_time", 10]])
93
- end
94
- end
95
-
96
- it "tracks GC run count" do
97
- expect(GC).to receive(:count).and_return(10, 15)
98
- expect(GC).to receive(:stat).and_return(
99
- { :minor_gc_count => 10, :major_gc_count => 10 },
100
- :minor_gc_count => 16, :major_gc_count => 17
101
- )
102
- probe.call
103
- probe.call
104
- expect_gauge_value("gc_count", 5, :tags => { :metric => :gc_count })
105
- expect_gauge_value("gc_count", 6, :tags => { :metric => :minor_gc_count })
106
- expect_gauge_value("gc_count", 7, :tags => { :metric => :major_gc_count })
107
- end
108
-
109
- it "tracks object allocation" do
110
- expect(GC).to receive(:stat).and_return(
111
- { :total_allocated_objects => 10 },
112
- :total_allocated_objects => 15
113
- )
114
- # Only tracks delta value so the needs to be called twice
115
- probe.call
116
- probe.call
117
- expect_gauge_value("allocated_objects", 5)
118
- end
119
-
120
- it "tracks heap slots" do
121
- probe.call
122
- expect_gauge_value("heap_slots", :tags => { :metric => :heap_live })
123
- expect_gauge_value("heap_slots", :tags => { :metric => :heap_free })
124
- end
125
-
126
- context "with custom hostname" do
127
- let(:hostname) { "my hostname" }
128
-
129
- it "reports custom hostname tag value" do
130
- probe.call
131
- expect_gauge_value("heap_slots",
132
- :tags => { :metric => :heap_live, :hostname => hostname })
133
- end
134
- end
135
- end
136
- end
137
-
138
- def expect_gauge_value(expected_key, expected_value = nil, tags: {})
139
- expected_tags = { :hostname => Socket.gethostname }.merge(tags)
140
- expect(appsignal_mock.gauges).to satisfy do |gauges|
141
- gauges.any? do |distribution_value|
142
- key, value, tags = distribution_value
143
- next unless key == expected_key
144
- next unless expected_value ? expected_value == value : !value.nil?
145
- next unless tags == expected_tags
146
-
147
- true
148
- end
149
- end
150
- end
151
-
152
- def expect_gauges(expected_metrics)
153
- default_tags = { :hostname => Socket.gethostname }
154
- keys = expected_metrics.map { |(key)| key }
155
- metrics = expected_metrics.map do |metric|
156
- key, value, tags = metric
157
- [key, value, default_tags.merge(tags || {})]
158
- end
159
- found_gauges = appsignal_mock.gauges.select { |(key)| keys.include? key }
160
- expect(found_gauges).to eq(metrics)
161
- end
162
- end